| 1 |
/**************************************************************************** |
| 2 |
** |
| 3 |
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). |
| 4 |
** All rights reserved. |
| 5 |
** Contact: Nokia Corporation (qt-info@nokia.com) |
| 6 |
** |
| 7 |
** This file is part of the test suite of the Qt Toolkit. |
| 8 |
** |
| 9 |
** $QT_BEGIN_LICENSE:LGPL$ |
| 10 |
** GNU Lesser General Public License Usage |
| 11 |
** This file may be used under the terms of the GNU Lesser General Public |
| 12 |
** License version 2.1 as published by the Free Software Foundation and |
| 13 |
** appearing in the file LICENSE.LGPL included in the packaging of this |
| 14 |
** file. Please review the following information to ensure the GNU Lesser |
| 15 |
** General Public License version 2.1 requirements will be met: |
| 16 |
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
| 17 |
** |
| 18 |
** In addition, as a special exception, Nokia gives you certain additional |
| 19 |
** rights. These rights are described in the Nokia Qt LGPL Exception |
| 20 |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
| 21 |
** |
| 22 |
** GNU General Public License Usage |
| 23 |
** Alternatively, this file may be used under the terms of the GNU General |
| 24 |
** Public License version 3.0 as published by the Free Software Foundation |
| 25 |
** and appearing in the file LICENSE.GPL included in the packaging of this |
| 26 |
** file. Please review the following information to ensure the GNU General |
| 27 |
** Public License version 3.0 requirements will be met: |
| 28 |
** http://www.gnu.org/copyleft/gpl.html. |
| 29 |
** |
| 30 |
** Other Usage |
| 31 |
** Alternatively, this file may be used in accordance with the terms and |
| 32 |
** conditions contained in a signed written agreement between you and Nokia. |
| 33 |
** |
| 34 |
** |
| 35 |
** |
| 36 |
** |
| 37 |
** |
| 38 |
** $QT_END_LICENSE$ |
| 39 |
** |
| 40 |
****************************************************************************/ |
| 41 |
|
| 42 |
|
| 43 |
#include <QtTest/QtTest> |
| 44 |
|
| 45 |
#include <q3urloperator.h> |
| 46 |
#include <qtimer.h> |
| 47 |
#include <qapplication.h> |
| 48 |
#include <qfile.h> |
| 49 |
#include <qfileinfo.h> |
| 50 |
#include <qurlinfo.h> |
| 51 |
#include <q3network.h> |
| 52 |
#include <q3networkprotocol.h> |
| 53 |
#include <qtimer.h> |
| 54 |
#include <q3ptrlist.h> |
| 55 |
#include <q3valuelist.h> |
| 56 |
#include <qlist.h> |
| 57 |
|
| 58 |
#include "../network-settings.h" |
| 59 |
|
| 60 |
//TESTED_CLASS= |
| 61 |
//TESTED_FILES= |
| 62 |
|
| 63 |
QT_FORWARD_DECLARE_CLASS(Q3NetworkOperation) |
| 64 |
|
| 65 |
class tst_Q3UrlOperator : public QObject |
| 66 |
{ |
| 67 |
Q_OBJECT |
| 68 |
|
| 69 |
public: |
| 70 |
tst_Q3UrlOperator(); |
| 71 |
virtual ~tst_Q3UrlOperator(); |
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
public slots: |
| 76 |
void initTestCase(); |
| 77 |
void cleanupTestCase(); |
| 78 |
void init(); |
| 79 |
void cleanup(); |
| 80 |
private slots: |
| 81 |
void copy_data(); |
| 82 |
void copy(); |
| 83 |
void put_data(); |
| 84 |
void put(); |
| 85 |
void rename_data(); |
| 86 |
void rename(); |
| 87 |
void stop_data(); |
| 88 |
void stop(); |
| 89 |
void listChildren_data(); |
| 90 |
void listChildren(); |
| 91 |
|
| 92 |
protected slots: |
| 93 |
void slotFinished_init( Q3NetworkOperation* ); |
| 94 |
void slotFinished_cleanup( Q3NetworkOperation* ); |
| 95 |
|
| 96 |
void slotFinished_copy( Q3NetworkOperation* ); |
| 97 |
|
| 98 |
void slotFinished_put( Q3NetworkOperation* ); |
| 99 |
void slotData_put( const QByteArray&, Q3NetworkOperation* ); |
| 100 |
|
| 101 |
void slotFinished_rename( Q3NetworkOperation* ); |
| 102 |
void slotItemChanged_rename( Q3NetworkOperation* ); |
| 103 |
|
| 104 |
void slotFinished_stop( Q3NetworkOperation* ); |
| 105 |
void slotDataTransferProgress_stop( int, int, Q3NetworkOperation* ); |
| 106 |
|
| 107 |
void slotFinished_listChildren( Q3NetworkOperation* ); |
| 108 |
void slotNewChildren_listChildren( const Q3ValueList<QUrlInfo> &, Q3NetworkOperation * ); |
| 109 |
|
| 110 |
void stopOperation(); |
| 111 |
|
| 112 |
private: |
| 113 |
Q3UrlOperator *urlOp; |
| 114 |
QString ftpQtestUpload; |
| 115 |
bool doStop; |
| 116 |
bool finished; |
| 117 |
|
| 118 |
Q3PtrList<Q3NetworkOperation> pendingOperations; |
| 119 |
Q3NetworkProtocol::State finishedState; |
| 120 |
int finishedErrorCode; |
| 121 |
QString finishedProtocolDetail; |
| 122 |
Q3ValueList<QUrlInfo> listChildrenInfo; |
| 123 |
QByteArray baData; |
| 124 |
uint timeout_count; |
| 125 |
}; |
| 126 |
|
| 127 |
//#define DUMP_SIGNALS |
| 128 |
|
| 129 |
tst_Q3UrlOperator::tst_Q3UrlOperator() |
| 130 |
{ |
| 131 |
q3InitNetworkProtocols(); |
| 132 |
timeout_count = 0; |
| 133 |
|
| 134 |
} |
| 135 |
|
| 136 |
tst_Q3UrlOperator::~tst_Q3UrlOperator() |
| 137 |
{ |
| 138 |
} |
| 139 |
|
| 140 |
void tst_Q3UrlOperator::initTestCase() |
| 141 |
{ |
| 142 |
// create files for checking permissions |
| 143 |
QFile textFile("listData/readOnly"); |
| 144 |
textFile.open(QIODevice::WriteOnly); |
| 145 |
textFile.close(); |
| 146 |
textFile.setPermissions(QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther); |
| 147 |
QFile exe("listData/executable.exe"); |
| 148 |
exe.open(QIODevice::WriteOnly); |
| 149 |
exe.close(); |
| 150 |
exe.setPermissions(QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther | |
| 151 |
QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther); |
| 152 |
|
| 153 |
// prepare: make sure that there is a unique directory for FTP upload |
| 154 |
// testing (to avoid parallel executed tests interfere with each other) |
| 155 |
ftpQtestUpload = QString("ftp://%1/").arg(QtNetworkSettings::serverLocalName()); |
| 156 |
QString dir = QString( "qtest/upload/%1" ).arg( (ulong)this ); |
| 157 |
|
| 158 |
Q3UrlOperator opMkdir( ftpQtestUpload ); |
| 159 |
|
| 160 |
connect( &opMkdir, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_init(Q3NetworkOperation*)) ); |
| 161 |
if ( opMkdir.mkdir( dir ) != 0 ) { |
| 162 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 163 |
if ( QTestEventLoop::instance().timeout() ) |
| 164 |
qWarning( "Prepare: Network operation timed out for create directory" ); |
| 165 |
} |
| 166 |
ftpQtestUpload += dir; |
| 167 |
} |
| 168 |
|
| 169 |
void tst_Q3UrlOperator::slotFinished_init( Q3NetworkOperation *op ) |
| 170 |
{ |
| 171 |
if ( op->state() == Q3NetworkProtocol::StFailed ) |
| 172 |
qWarning( QString( "Prepare: Can't create directory: network operation failed ('%1'). " ).arg(op->protocolDetail()) ); |
| 173 |
QTestEventLoop::instance().exitLoop(); |
| 174 |
} |
| 175 |
|
| 176 |
void tst_Q3UrlOperator::cleanupTestCase() |
| 177 |
{ |
| 178 |
// remove the files created before |
| 179 |
QFile textFile("listData/readOnly"); |
| 180 |
textFile.setPermissions(textFile.permissions() | QFile::WriteOwner); |
| 181 |
if (! textFile.remove()) |
| 182 |
qWarning() << "could not remove file:" << textFile.error(); |
| 183 |
QFile exe("listData/executable.exe"); |
| 184 |
exe.setPermissions(textFile.permissions() | QFile::WriteOwner); |
| 185 |
if (! exe.remove()) |
| 186 |
qWarning() << "could not remove file:" << exe.error(); |
| 187 |
|
| 188 |
// cleanup: delete the unique directory for FTP upload testing |
| 189 |
QStringList tmp = QStringList::split( '/', ftpQtestUpload, TRUE ); |
| 190 |
QString dir = tmp.last(); |
| 191 |
tmp.pop_back(); |
| 192 |
QString url = tmp.join( "/" ); |
| 193 |
|
| 194 |
Q3UrlOperator opRemove( url ); |
| 195 |
connect( &opRemove, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_cleanup(Q3NetworkOperation*)) ); |
| 196 |
if ( opRemove.remove( dir ) != 0 ) { |
| 197 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 198 |
if ( QTestEventLoop::instance().timeout() ) |
| 199 |
qWarning( "Cleanup: Network operation timed out for removing directory" ); |
| 200 |
} |
| 201 |
} |
| 202 |
|
| 203 |
void tst_Q3UrlOperator::slotFinished_cleanup( Q3NetworkOperation *op ) |
| 204 |
{ |
| 205 |
if ( op->state() == Q3NetworkProtocol::StFailed ) |
| 206 |
qWarning( QString( "Cleanup: Can't remove directory: network operation failed ('%1'). " ).arg(op->protocolDetail()) ); |
| 207 |
QTestEventLoop::instance().exitLoop(); |
| 208 |
} |
| 209 |
|
| 210 |
void tst_Q3UrlOperator::init() |
| 211 |
{ |
| 212 |
doStop = FALSE; |
| 213 |
finished = FALSE; |
| 214 |
pendingOperations.clear(); |
| 215 |
} |
| 216 |
|
| 217 |
void tst_Q3UrlOperator::cleanup() |
| 218 |
{ |
| 219 |
} |
| 220 |
|
| 221 |
void tst_Q3UrlOperator::copy_data() |
| 222 |
{ |
| 223 |
const QString ftpQtest( QString("ftp://%1/qtest").arg(QtNetworkSettings::serverLocalName()) ); |
| 224 |
const QString httpQtest( QString("http://%1/qtest").arg(QtNetworkSettings::serverLocalName()) ); |
| 225 |
|
| 226 |
// argument for the constructor |
| 227 |
QTest::addColumn<QString>("url"); |
| 228 |
// arguments for the copy() |
| 229 |
QTest::addColumn<QString>("from"); |
| 230 |
QTest::addColumn<QString>("to"); |
| 231 |
QTest::addColumn<bool>("move"); |
| 232 |
QTest::addColumn<bool>("toPath"); |
| 233 |
|
| 234 |
// FTP data |
| 235 |
// QTest::newRow( "ftp00" ) << QString() << QString("%1/rfc3252.txt").arg(ftpQtest) << QString(".") << (bool)FALSE << (bool)TRUE; |
| 236 |
QTest::newRow( "ftp01" ) << QString() << QString("%1/rfc3252").arg(ftpQtest) << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 237 |
|
| 238 |
QTest::newRow( "ftp02" ) << QString("%1/").arg(ftpQtest) << QString("rfc3252.txt") << QString(".") << (bool)FALSE << (bool)TRUE; |
| 239 |
QTest::newRow( "ftp03" ) << QString("%1/").arg(ftpQtest) << QString("rfc3252") << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 240 |
|
| 241 |
QTest::newRow( "ftp04" ) << QString("%1").arg(ftpQtest) << QString("rfc3252.txt") << QString(".") << (bool)FALSE << (bool)TRUE; |
| 242 |
QTest::newRow( "ftp05" ) << QString("%1").arg(ftpQtest) << QString("rfc3252") << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 243 |
|
| 244 |
// the ftp.faqs.org host is down that often, that it does not make sense to |
| 245 |
// use it for automated tests |
| 246 |
// QTest::newRow( "ftp06" ) << QString() << QString("ftp://ftp.faqs.org/rfc/rfc3252.txt") << QString(".") << (bool)FALSE << (bool)TRUE; |
| 247 |
|
| 248 |
// HTTP data |
| 249 |
QTest::newRow( "http00" ) << QString() << QString("%1/rfc3252.txt").arg(httpQtest) << QString(".") << (bool)FALSE << (bool)TRUE; |
| 250 |
QTest::newRow( "http01" ) << QString() << QString("%1/rfc3252").arg(httpQtest) << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 251 |
QTest::newRow( "http02" ) << QString() << QString("%1/").arg(httpQtest) << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 252 |
|
| 253 |
QTest::newRow( "http03" ) << QString("%1/").arg(httpQtest) << QString("rfc3252.txt") << QString(".") << (bool)FALSE << (bool)TRUE; |
| 254 |
QTest::newRow( "http04" ) << QString("%1/").arg(httpQtest) << QString("rfc3252") << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 255 |
QTest::newRow( "http05" ) << QString("%1/").arg(httpQtest) << QString("") << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 256 |
QTest::newRow( "http06" ) << QString("%1/").arg(httpQtest) << QString() << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 257 |
|
| 258 |
QTest::newRow( "http07" ) << QString("%1").arg(httpQtest) << QString("rfc3252.txt") << QString(".") << (bool)FALSE << (bool)TRUE; |
| 259 |
QTest::newRow( "http08" ) << QString("%1").arg(httpQtest) << QString("rfc3252") << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 260 |
QTest::newRow( "http09" ) << QString("%1").arg(httpQtest) << QString("") << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 261 |
QTest::newRow( "http10" ) << QString("%1").arg(httpQtest) << QString() << QString("rfc3252.txt") << (bool)FALSE << (bool)FALSE; |
| 262 |
|
| 263 |
// Unstable host: |
| 264 |
// QTest::newRow( "http11" ) << QString() << QString("http://www.ietf.org/rfc/rfc3252.txt") << QString(".") << (bool)FALSE << (bool)TRUE; |
| 265 |
} |
| 266 |
|
| 267 |
void tst_Q3UrlOperator::copy() |
| 268 |
{ |
| 269 |
if (timeout_count >= 3) { |
| 270 |
QFAIL( "Too many timeout's. Aborting test prematurely." ); |
| 271 |
} |
| 272 |
|
| 273 |
QFETCH( QString, url ); |
| 274 |
QFETCH( QString, from ); |
| 275 |
QFETCH( QString, to ); |
| 276 |
QFETCH( bool, move ); |
| 277 |
QFETCH( bool, toPath ); |
| 278 |
|
| 279 |
if ( url.isNull() ) { |
| 280 |
urlOp = new Q3UrlOperator(); |
| 281 |
} else { |
| 282 |
urlOp = new Q3UrlOperator( url ); |
| 283 |
} |
| 284 |
pendingOperations = urlOp->copy( from, to, move, toPath ); |
| 285 |
|
| 286 |
connect( urlOp, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_copy(Q3NetworkOperation*)) ); |
| 287 |
|
| 288 |
QTestEventLoop::instance().enterLoop( 60 ); |
| 289 |
delete urlOp; |
| 290 |
if ( QTestEventLoop::instance().timeout() ) |
| 291 |
QFAIL( "Network operation timed out" ); |
| 292 |
|
| 293 |
// test the results of the operation |
| 294 |
if ( finished ) { |
| 295 |
QVERIFY( finishedState==Q3NetworkProtocol::StDone || finishedState==Q3NetworkProtocol::StFailed ); |
| 296 |
if ( finishedState == Q3NetworkProtocol::StDone ) { |
| 297 |
QFile file( "rfc3252.txt" ); |
| 298 |
if ( !file.open( QIODevice::ReadOnly ) ) |
| 299 |
QFAIL( "Could not open downloaded file" ); |
| 300 |
|
| 301 |
// ### this should move in the tesdata |
| 302 |
QFile fileRes( "copy.res/rfc3252.txt" ); |
| 303 |
if ( !fileRes.open( QIODevice::ReadOnly ) ) |
| 304 |
QFAIL( "Could not open result file" ); |
| 305 |
|
| 306 |
QCOMPARE(file.readAll(), fileRes.readAll()); |
| 307 |
|
| 308 |
// delete the downloaded file |
| 309 |
if ( !file.remove() ) |
| 310 |
QFAIL( QString("Cleanup failed: could not remove the downloaded file '%1'").arg(file.name()) ); |
| 311 |
timeout_count = 0; |
| 312 |
} else { |
| 313 |
QFAIL( QString( "Network operation failed ('%1'). " |
| 314 |
"This could be due to a temporary network failure. " |
| 315 |
"If this test continues to fail, take a closer look").arg(finishedProtocolDetail) ); |
| 316 |
timeout_count++; |
| 317 |
} |
| 318 |
} |
| 319 |
} |
| 320 |
|
| 321 |
void tst_Q3UrlOperator::slotFinished_copy( Q3NetworkOperation *op ) |
| 322 |
{ |
| 323 |
#if defined( DUMP_SIGNALS ) |
| 324 |
qDebug( "finished( %p )", op ); |
| 325 |
#endif |
| 326 |
QVERIFY( op != 0 ); |
| 327 |
pendingOperations.remove( op ); |
| 328 |
// We are finished if either of this happens: |
| 329 |
// - both, the get and the put of the copy are finished |
| 330 |
// - we are in an error case (for the case that the get fails, no |
| 331 |
// finished() signal for the put is emitted since it is never executed) |
| 332 |
if ( pendingOperations.isEmpty() || op->state()==Q3NetworkProtocol::StFailed ) { |
| 333 |
finished = TRUE; |
| 334 |
finishedState = op->state(); |
| 335 |
finishedErrorCode = op->errorCode(); |
| 336 |
finishedProtocolDetail = op->protocolDetail(); |
| 337 |
|
| 338 |
QTestEventLoop::instance().exitLoop(); |
| 339 |
} |
| 340 |
} |
| 341 |
|
| 342 |
void tst_Q3UrlOperator::put_data() |
| 343 |
{ |
| 344 |
const QString httpQtest( QString("http://%1/qtest/cgi-bin").arg(QtNetworkSettings::serverLocalName()) ); |
| 345 |
const QString httpQtestGet( QString("http://%1/qtest/cgi-bin/retrieve_testfile.cgi").arg(QtNetworkSettings::serverLocalName()) ); |
| 346 |
|
| 347 |
QByteArray putData_1( 5 ); |
| 348 |
putData_1[0] = 'a'; |
| 349 |
putData_1[1] = 'b'; |
| 350 |
putData_1[2] = '\n'; |
| 351 |
putData_1[3] = 'c'; |
| 352 |
putData_1[4] = 'd'; |
| 353 |
|
| 354 |
QTest::addColumn<QString>("url"); |
| 355 |
QTest::addColumn<QString>("to"); |
| 356 |
QTest::addColumn<QByteArray>("putData"); |
| 357 |
QTest::addColumn<QString>("getUrl"); |
| 358 |
QTest::addColumn<QString>("rmUrl"); |
| 359 |
QTest::addColumn<QString>("rmFile"); |
| 360 |
|
| 361 |
// FTP data |
| 362 |
QTest::newRow( "ftp00" ) |
| 363 |
<< ftpQtestUpload << "put_ftp00" << putData_1 |
| 364 |
<< QString("%1/put_ftp00").arg(ftpQtestUpload) |
| 365 |
<< ftpQtestUpload << "put_ftp00"; |
| 366 |
QTest::newRow( "ftp01" ) |
| 367 |
<< QString() << QString("%1/put_ftp01").arg(ftpQtestUpload) << putData_1 |
| 368 |
<< QString("%1/put_ftp01").arg(ftpQtestUpload) |
| 369 |
<< ftpQtestUpload << "put_ftp01"; |
| 370 |
|
| 371 |
QTest::newRow( "ftp02" ) |
| 372 |
<< ftpQtestUpload << "put_ftp02" << QByteArray(0) |
| 373 |
<< QString("%1/put_ftp02").arg(ftpQtestUpload) |
| 374 |
<< ftpQtestUpload << "put_ftp02"; |
| 375 |
QTest::newRow( "ftp03" ) |
| 376 |
<< QString() << QString("%1/put_ftp03").arg(ftpQtestUpload) << QByteArray(0) |
| 377 |
<< QString("%1/put_ftp03").arg(ftpQtestUpload) |
| 378 |
<< ftpQtestUpload << "put_ftp03"; |
| 379 |
// HTTP data |
| 380 |
QTest::newRow( "http00" ) |
| 381 |
<< httpQtest << "store_testfile.cgi" << putData_1 |
| 382 |
<< httpQtestGet |
| 383 |
<< httpQtest << QString(); |
| 384 |
QTest::newRow( "http01" ) |
| 385 |
<< QString() << QString("%1/store_testfile.cgi").arg(httpQtest) << putData_1 |
| 386 |
<< httpQtestGet |
| 387 |
<< httpQtest << QString(); |
| 388 |
QTest::newRow( "http02" ) |
| 389 |
<< httpQtest << "store_testfile.cgi" << QByteArray(0) |
| 390 |
<< httpQtestGet |
| 391 |
<< httpQtest << QString(); |
| 392 |
QTest::newRow( "http03" ) << QString() << QString("%1/store_testfile.cgi").arg(httpQtest) << QByteArray(0) |
| 393 |
<< httpQtestGet |
| 394 |
<< httpQtest << QString(); |
| 395 |
} |
| 396 |
|
| 397 |
void tst_Q3UrlOperator::put() |
| 398 |
{ |
| 399 |
{ |
| 400 |
// do the put |
| 401 |
QFETCH( QString, url ); |
| 402 |
QFETCH( QString, to ); |
| 403 |
QFETCH( QByteArray, putData ); |
| 404 |
|
| 405 |
if ( url.isNull() ) { |
| 406 |
urlOp = new Q3UrlOperator(); |
| 407 |
} else { |
| 408 |
urlOp = new Q3UrlOperator( url ); |
| 409 |
} |
| 410 |
|
| 411 |
pendingOperations.append( urlOp->put( putData, to) ); |
| 412 |
|
| 413 |
connect( urlOp, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_put(Q3NetworkOperation*)) ); |
| 414 |
|
| 415 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 416 |
delete urlOp; |
| 417 |
if ( QTestEventLoop::instance().timeout() ) |
| 418 |
QFAIL( "Network operation timed out" ); |
| 419 |
} |
| 420 |
{ |
| 421 |
// In order to test that the put was really successful, we have to get the |
| 422 |
// file from the server. |
| 423 |
QFETCH( QString, getUrl ); |
| 424 |
baData.resize( 0 ); |
| 425 |
Q3UrlOperator opGet( getUrl ); |
| 426 |
opGet.get(); |
| 427 |
connect( &opGet, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_put(Q3NetworkOperation*)) ); |
| 428 |
connect( &opGet, SIGNAL(data(const QByteArray&,Q3NetworkOperation*)), SLOT(slotData_put(const QByteArray&,Q3NetworkOperation*)) ); |
| 429 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 430 |
if ( QTestEventLoop::instance().timeout() ) |
| 431 |
QFAIL( "Network operation timed out" ); |
| 432 |
|
| 433 |
QTEST( baData, "putData" ); |
| 434 |
} |
| 435 |
{ |
| 436 |
// cleanup: delete file (if possible) |
| 437 |
QFETCH( QString, rmUrl ); |
| 438 |
QFETCH( QString, rmFile ); |
| 439 |
Q3UrlOperator opRemove( rmUrl ); |
| 440 |
connect( &opRemove, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_put(Q3NetworkOperation*)) ); |
| 441 |
if ( opRemove.remove( rmFile ) != 0 ) { |
| 442 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 443 |
if ( QTestEventLoop::instance().timeout() ) |
| 444 |
QFAIL( "Network operation timed out" ); |
| 445 |
QVERIFY( finishedState==Q3NetworkProtocol::StDone || finishedState==Q3NetworkProtocol::StFailed ); |
| 446 |
if ( finishedState != Q3NetworkProtocol::StDone ) { |
| 447 |
QFAIL( QString( "Can't remove file: network operation failed ('%1'). " ).arg(finishedProtocolDetail) ); |
| 448 |
} |
| 449 |
} |
| 450 |
} |
| 451 |
} |
| 452 |
|
| 453 |
void tst_Q3UrlOperator::slotFinished_put( Q3NetworkOperation *op ) |
| 454 |
{ |
| 455 |
#if defined( DUMP_SIGNALS ) |
| 456 |
qDebug( "finished( %p )", op ); |
| 457 |
#endif |
| 458 |
QVERIFY( op != 0 ); |
| 459 |
pendingOperations.remove( op ); |
| 460 |
QVERIFY( pendingOperations.isEmpty() ); |
| 461 |
|
| 462 |
finished = TRUE; |
| 463 |
finishedState = op->state(); |
| 464 |
finishedErrorCode = op->errorCode(); |
| 465 |
finishedProtocolDetail = op->protocolDetail(); |
| 466 |
|
| 467 |
if (op->state() != Q3NetworkProtocol::StFailed) |
| 468 |
QTestEventLoop::instance().exitLoop(); |
| 469 |
} |
| 470 |
|
| 471 |
void tst_Q3UrlOperator::slotData_put( const QByteArray& ba, Q3NetworkOperation *op ) |
| 472 |
{ |
| 473 |
#if defined( DUMP_SIGNALS ) |
| 474 |
qDebug( "data( %d, %p )", ba.size(), op ); |
| 475 |
#endif |
| 476 |
QVERIFY( op != 0 ); |
| 477 |
int oldSize = baData.size(); |
| 478 |
baData.resize( ba.size() + oldSize ); |
| 479 |
memcpy( baData.data()+oldSize, ba.data(), ba.size() ); |
| 480 |
} |
| 481 |
|
| 482 |
void tst_Q3UrlOperator::rename_data() |
| 483 |
{ |
| 484 |
QTest::addColumn<QString>("url"); |
| 485 |
QTest::addColumn<QString>("oldname"); |
| 486 |
QTest::addColumn<QString>("newname"); |
| 487 |
|
| 488 |
QTest::newRow( "local00" ) << QString(".") << QString("foo") << QString("bar"); |
| 489 |
} |
| 490 |
|
| 491 |
void tst_Q3UrlOperator::rename() |
| 492 |
{ |
| 493 |
{ |
| 494 |
// create direcotry first |
| 495 |
QFETCH( QString, url ); |
| 496 |
QFETCH( QString, oldname ); |
| 497 |
|
| 498 |
if ( url.isNull() ) { |
| 499 |
urlOp = new Q3UrlOperator(); |
| 500 |
} else { |
| 501 |
urlOp = new Q3UrlOperator( url ); |
| 502 |
} |
| 503 |
|
| 504 |
pendingOperations.append( urlOp->mkdir( oldname ) ); |
| 505 |
|
| 506 |
connect( urlOp, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_rename(Q3NetworkOperation*)) ); |
| 507 |
|
| 508 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 509 |
delete urlOp; |
| 510 |
if ( QTestEventLoop::instance().timeout() ) |
| 511 |
QFAIL( "Network operation timed out" ); |
| 512 |
|
| 513 |
QVERIFY( finishedState == Q3NetworkProtocol::StDone ); |
| 514 |
} |
| 515 |
{ |
| 516 |
// rename directory |
| 517 |
QFETCH( QString, url ); |
| 518 |
QFETCH( QString, oldname ); |
| 519 |
QFETCH( QString, newname ); |
| 520 |
|
| 521 |
if ( url.isNull() ) { |
| 522 |
urlOp = new Q3UrlOperator(); |
| 523 |
} else { |
| 524 |
urlOp = new Q3UrlOperator( url ); |
| 525 |
} |
| 526 |
|
| 527 |
pendingOperations.append( urlOp->rename( oldname, newname ) ); |
| 528 |
|
| 529 |
connect( urlOp, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_rename(Q3NetworkOperation*)) ); |
| 530 |
connect( urlOp, SIGNAL(itemChanged(Q3NetworkOperation*)), SLOT(slotItemChanged_rename(Q3NetworkOperation*)) ); |
| 531 |
|
| 532 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 533 |
delete urlOp; |
| 534 |
if ( QTestEventLoop::instance().timeout() ) |
| 535 |
QFAIL( "Network operation timed out" ); |
| 536 |
|
| 537 |
QVERIFY( finishedState == Q3NetworkProtocol::StDone ); |
| 538 |
} |
| 539 |
{ |
| 540 |
// delete direcotry |
| 541 |
QFETCH( QString, url ); |
| 542 |
QFETCH( QString, newname ); |
| 543 |
|
| 544 |
if ( url.isNull() ) { |
| 545 |
urlOp = new Q3UrlOperator(); |
| 546 |
} else { |
| 547 |
urlOp = new Q3UrlOperator( url ); |
| 548 |
} |
| 549 |
|
| 550 |
pendingOperations.append( urlOp->remove( newname ) ); |
| 551 |
|
| 552 |
connect( urlOp, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_rename(Q3NetworkOperation*)) ); |
| 553 |
|
| 554 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 555 |
delete urlOp; |
| 556 |
if ( QTestEventLoop::instance().timeout() ) |
| 557 |
QFAIL( "Network operation timed out" ); |
| 558 |
|
| 559 |
QVERIFY( finishedState == Q3NetworkProtocol::StDone ); |
| 560 |
} |
| 561 |
} |
| 562 |
|
| 563 |
void tst_Q3UrlOperator::slotFinished_rename( Q3NetworkOperation *op ) |
| 564 |
{ |
| 565 |
#if defined( DUMP_SIGNALS ) |
| 566 |
qDebug( "finished( %p )", op ); |
| 567 |
#endif |
| 568 |
QVERIFY( op != 0 ); |
| 569 |
pendingOperations.remove( op ); |
| 570 |
QVERIFY( pendingOperations.isEmpty() ); |
| 571 |
|
| 572 |
finished = TRUE; |
| 573 |
finishedState = op->state(); |
| 574 |
finishedErrorCode = op->errorCode(); |
| 575 |
finishedProtocolDetail = op->protocolDetail(); |
| 576 |
|
| 577 |
QTestEventLoop::instance().exitLoop(); |
| 578 |
} |
| 579 |
|
| 580 |
void tst_Q3UrlOperator::slotItemChanged_rename( Q3NetworkOperation *op ) |
| 581 |
{ |
| 582 |
#if defined( DUMP_SIGNALS ) |
| 583 |
qDebug( "itemChanged( %p )", op ); |
| 584 |
#endif |
| 585 |
QVERIFY( op != 0 ); |
| 586 |
// ### what to do here? |
| 587 |
} |
| 588 |
|
| 589 |
void tst_Q3UrlOperator::stop_data() |
| 590 |
{ |
| 591 |
QTest::addColumn<QString>("from"); |
| 592 |
QTest::addColumn<QString>("to"); |
| 593 |
QTest::addColumn<QString>("rmUrl"); |
| 594 |
QTest::addColumn<QString>("rmFile"); |
| 595 |
|
| 596 |
// FTP data |
| 597 |
QTest::newRow( "ftp01" ) |
| 598 |
<< "stop/bigfile" << ftpQtestUpload |
| 599 |
<< ftpQtestUpload << "bigfile"; |
| 600 |
} |
| 601 |
|
| 602 |
void tst_Q3UrlOperator::stop() |
| 603 |
{ |
| 604 |
doStop = TRUE; |
| 605 |
urlOp = new Q3UrlOperator(); |
| 606 |
connect( urlOp, SIGNAL(finished(Q3NetworkOperation*)), |
| 607 |
SLOT(slotFinished_stop(Q3NetworkOperation*)) ); |
| 608 |
connect( urlOp, SIGNAL(dataTransferProgress(int,int,Q3NetworkOperation*)), |
| 609 |
SLOT(slotDataTransferProgress_stop(int,int,Q3NetworkOperation*)) ); |
| 610 |
{ |
| 611 |
// do the upload |
| 612 |
QFETCH( QString, from ); |
| 613 |
QFETCH( QString, to ); |
| 614 |
pendingOperations = urlOp->copy( from, to ); |
| 615 |
|
| 616 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 617 |
if ( QTestEventLoop::instance().timeout() ) |
| 618 |
QFAIL( "Network operation timed out" ); |
| 619 |
} |
| 620 |
doStop = FALSE; |
| 621 |
{ |
| 622 |
// do the upload again (this time without stop) -- this used to fail |
| 623 |
// until change 71380 |
| 624 |
QFETCH( QString, from ); |
| 625 |
QFETCH( QString, to ); |
| 626 |
pendingOperations = urlOp->copy( from, to ); |
| 627 |
|
| 628 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 629 |
if ( QTestEventLoop::instance().timeout() ) |
| 630 |
QFAIL( "Network operation timed out" ); |
| 631 |
} |
| 632 |
delete urlOp; |
| 633 |
|
| 634 |
{ |
| 635 |
// cleanup: delete file (if possible) |
| 636 |
QFETCH( QString, rmUrl ); |
| 637 |
QFETCH( QString, rmFile ); |
| 638 |
Q3UrlOperator opRemove( rmUrl ); |
| 639 |
connect( &opRemove, SIGNAL(finished(Q3NetworkOperation*)), SLOT(slotFinished_stop(Q3NetworkOperation*)) ); |
| 640 |
if ( opRemove.remove( rmFile ) != 0 ) { |
| 641 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 642 |
if ( QTestEventLoop::instance().timeout() ) |
| 643 |
QFAIL( "Network operation timed out" ); |
| 644 |
QVERIFY( finishedState==Q3NetworkProtocol::StDone || finishedState==Q3NetworkProtocol::StFailed ); |
| 645 |
if ( finishedState != Q3NetworkProtocol::StDone ) |
| 646 |
QFAIL( QString( "Can't remove file: network operation failed ('%1'). " ).arg(finishedProtocolDetail) ); |
| 647 |
} |
| 648 |
} |
| 649 |
} |
| 650 |
|
| 651 |
void tst_Q3UrlOperator::slotFinished_stop( Q3NetworkOperation *op ) |
| 652 |
{ |
| 653 |
#if defined( DUMP_SIGNALS ) |
| 654 |
qDebug( "finished( %p )", op ); |
| 655 |
#endif |
| 656 |
QVERIFY( op != 0 ); |
| 657 |
|
| 658 |
pendingOperations.remove( op ); |
| 659 |
// We are finished if either of this happens: |
| 660 |
// - both, the get and the put of the copy are finished |
| 661 |
// - we are in an error case (for the case that the get fails, no |
| 662 |
// finished() signal for the put is emitted since it is never executed) |
| 663 |
if ( pendingOperations.isEmpty() || op->state()==Q3NetworkProtocol::StFailed ) { |
| 664 |
finished = TRUE; |
| 665 |
finishedState = op->state(); |
| 666 |
finishedErrorCode = op->errorCode(); |
| 667 |
finishedProtocolDetail = op->protocolDetail(); |
| 668 |
|
| 669 |
QTestEventLoop::instance().exitLoop(); |
| 670 |
} |
| 671 |
} |
| 672 |
|
| 673 |
void tst_Q3UrlOperator::slotDataTransferProgress_stop( int done, int total, Q3NetworkOperation *op ) |
| 674 |
{ |
| 675 |
#if defined( DUMP_SIGNALS ) |
| 676 |
qDebug( "dataTransferProgress( %d, %d, %p )", done, total, op ); |
| 677 |
#endif |
| 678 |
QVERIFY( op != 0 ); |
| 679 |
QVERIFY( done <= total ); |
| 680 |
|
| 681 |
if ( QTest::currentTestFunction() == QLatin1String("stop") ) { |
| 682 |
// ### it would be nice if we could specify in our testdata when to do |
| 683 |
// the stop |
| 684 |
if ( doStop && pendingOperations.count()==1 ) { |
| 685 |
if ( done > 0 && done >= total/100000 ) { |
| 686 |
// it is not safe to call stop() in a slot connected to the |
| 687 |
// dataTransferProgress() signal (and it is not trivial to make |
| 688 |
// it work) |
| 689 |
QTimer::singleShot( 0, this, SLOT(stopOperation()) ); |
| 690 |
doStop = FALSE; |
| 691 |
} |
| 692 |
} |
| 693 |
} |
| 694 |
} |
| 695 |
|
| 696 |
void tst_Q3UrlOperator::stopOperation() |
| 697 |
{ |
| 698 |
if ( urlOp ) |
| 699 |
urlOp->stop(); |
| 700 |
} |
| 701 |
|
| 702 |
void tst_Q3UrlOperator::listChildren_data() |
| 703 |
{ |
| 704 |
QTest::addColumn<QString>("url"); |
| 705 |
QTest::addColumn<QString>("nameFilter"); |
| 706 |
QTest::addColumn<bool>("readable"); |
| 707 |
QTest::addColumn<bool>("writable"); |
| 708 |
QTest::addColumn<bool>("executable"); |
| 709 |
QTest::addColumn<int>("permissions"); |
| 710 |
|
| 711 |
QTest::newRow( "localfs00" ) |
| 712 |
<< QString("listData") << QString("readOnly") |
| 713 |
<< (bool)TRUE << (bool)FALSE << (bool)FALSE << 0444; |
| 714 |
QTest::newRow( "localfs01" ) |
| 715 |
<< QString("listData") << QString("executable.exe") |
| 716 |
<< (bool)TRUE << (bool)FALSE << (bool)TRUE << 0555; |
| 717 |
int permissions = 0755; |
| 718 |
#ifdef Q_OS_WIN |
| 719 |
permissions = 0777; |
| 720 |
#endif |
| 721 |
QTest::newRow( "localfs02" ) |
| 722 |
<< QString("listData") << QString("readWriteExec.exe") |
| 723 |
<< (bool)TRUE << (bool)TRUE << (bool)TRUE << permissions; |
| 724 |
} |
| 725 |
|
| 726 |
void tst_Q3UrlOperator::listChildren() |
| 727 |
{ |
| 728 |
QFETCH( QString, url ); |
| 729 |
QFETCH( QString, nameFilter ); |
| 730 |
urlOp = new Q3UrlOperator( "listData" ); |
| 731 |
urlOp->setNameFilter( nameFilter ); |
| 732 |
|
| 733 |
pendingOperations.append( urlOp->listChildren() ); |
| 734 |
|
| 735 |
connect( urlOp, SIGNAL(finished(Q3NetworkOperation*)), |
| 736 |
SLOT(slotFinished_listChildren(Q3NetworkOperation*)) ); |
| 737 |
connect( urlOp, SIGNAL(newChildren(const Q3ValueList<QUrlInfo>&, Q3NetworkOperation*)), |
| 738 |
SLOT(slotNewChildren_listChildren(const Q3ValueList<QUrlInfo>&, Q3NetworkOperation*)) ); |
| 739 |
|
| 740 |
QTestEventLoop::instance().enterLoop( 30 ); |
| 741 |
delete urlOp; |
| 742 |
if ( QTestEventLoop::instance().timeout() ) |
| 743 |
QFAIL( "Network operation timed out" ); |
| 744 |
|
| 745 |
QVERIFY( finishedState == Q3NetworkProtocol::StDone ); |
| 746 |
for ( int i=0; i<(int)listChildrenInfo.count(); i++ ) { |
| 747 |
if ( listChildrenInfo[i].name() == "." || listChildrenInfo[i].name() == ".." ) |
| 748 |
continue; |
| 749 |
|
| 750 |
QFETCH( bool, readable ); |
| 751 |
QFETCH( bool, writable ); |
| 752 |
QFETCH( bool, executable ); |
| 753 |
QFETCH( int, permissions ); |
| 754 |
QCOMPARE( listChildrenInfo[i].isReadable(), readable ); |
| 755 |
QCOMPARE( listChildrenInfo[i].isWritable(), writable ); |
| 756 |
|
| 757 |
QCOMPARE( listChildrenInfo[i].isExecutable(), executable); |
| 758 |
QCOMPARE( listChildrenInfo[i].permissions(), permissions ); |
| 759 |
} |
| 760 |
} |
| 761 |
|
| 762 |
void tst_Q3UrlOperator::slotFinished_listChildren( Q3NetworkOperation *op ) |
| 763 |
{ |
| 764 |
#if defined( DUMP_SIGNALS ) |
| 765 |
qDebug( "finished( %p )", op ); |
| 766 |
#endif |
| 767 |
QVERIFY( op != 0 ); |
| 768 |
pendingOperations.remove( op ); |
| 769 |
QVERIFY( pendingOperations.isEmpty() ); |
| 770 |
|
| 771 |
finished = TRUE; |
| 772 |
finishedState = op->state(); |
| 773 |
finishedErrorCode = op->errorCode(); |
| 774 |
finishedProtocolDetail = op->protocolDetail(); |
| 775 |
|
| 776 |
QTestEventLoop::instance().exitLoop(); |
| 777 |
} |
| 778 |
|
| 779 |
void tst_Q3UrlOperator::slotNewChildren_listChildren( const Q3ValueList<QUrlInfo> &i, Q3NetworkOperation * ) |
| 780 |
{ |
| 781 |
listChildrenInfo = i; |
| 782 |
} |
| 783 |
|
| 784 |
QTEST_MAIN(tst_Q3UrlOperator) |
| 785 |
#include "tst_q3urloperator.moc" |