tests/auto/qftp/tst_qftp.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #include <qcoreapplication.h>
       
    46 #include <qfile.h>
       
    47 #include <qbuffer.h>
       
    48 #include "qftp.h"
       
    49 #include <qmap.h>
       
    50 #include <time.h>
       
    51 #include <stdlib.h>
       
    52 #include <QNetworkProxy>
       
    53 
       
    54 #ifndef TEST_QNETWORK_PROXY
       
    55 #define TEST_QNETWORK_PROXY
       
    56 #endif
       
    57 #include "../network-settings.h"
       
    58 
       
    59 //TESTED_CLASS=
       
    60 //TESTED_FILES=
       
    61 
       
    62 #ifdef Q_OS_SYMBIAN
       
    63 // In Symbian OS test data is located in applications private dir
       
    64 // Application private dir is default serach path for files, so SRCDIR can be set to empty
       
    65 #define SRCDIR ""
       
    66 #endif
       
    67 
       
    68 
       
    69 
       
    70 class tst_QFtp : public QObject
       
    71 {
       
    72     Q_OBJECT
       
    73 
       
    74 public:
       
    75     tst_QFtp();
       
    76     virtual ~tst_QFtp();
       
    77 
       
    78 
       
    79 public slots:
       
    80     void initTestCase_data();
       
    81     void initTestCase();
       
    82     void cleanupTestCase();
       
    83     void init();
       
    84     void cleanup();
       
    85 private slots:
       
    86     void connectToHost_data();
       
    87     void connectToHost();
       
    88     void connectToUnresponsiveHost();
       
    89     void login_data();
       
    90     void login();
       
    91     void close_data();
       
    92     void close();
       
    93 
       
    94     void list_data();
       
    95     void list();
       
    96     void cd_data();
       
    97     void cd();
       
    98     void get_data();
       
    99     void get();
       
   100     void put_data();
       
   101     void put();
       
   102     void remove();
       
   103     void mkdir_data();
       
   104     void mkdir();
       
   105     void mkdir2();
       
   106     void rmdir();
       
   107     void rename_data();
       
   108     void rename();
       
   109 
       
   110     void commandSequence_data();
       
   111     void commandSequence();
       
   112 
       
   113     void abort_data();
       
   114     void abort();
       
   115 
       
   116     void bytesAvailable_data();
       
   117     void bytesAvailable();
       
   118 
       
   119     void activeMode();
       
   120 
       
   121     void proxy_data();
       
   122     void proxy();
       
   123 
       
   124     void binaryAscii();
       
   125 
       
   126     void doneSignal();
       
   127     void queueMoreCommandsInDoneSlot();
       
   128 
       
   129 protected slots:
       
   130     void stateChanged( int );
       
   131     void listInfo( const QUrlInfo & );
       
   132     void readyRead();
       
   133     void dataTransferProgress(qint64, qint64);
       
   134 
       
   135     void commandStarted( int );
       
   136     void commandFinished( int, bool );
       
   137     void done( bool );
       
   138     void activeModeDone( bool );
       
   139     void mkdir2Slot(int id, bool error);
       
   140     void cdUpSlot(bool);
       
   141 
       
   142 private:
       
   143     QFtp *newFtp();
       
   144     void addCommand( QFtp::Command, int );
       
   145     bool fileExists( const QString &host, quint16 port, const QString &user, const QString &password, const QString &file, const QString &cdDir = QString::null );
       
   146     bool dirExists( const QString &host, quint16 port, const QString &user, const QString &password, const QString &cdDir, const QString &dirToCreate );
       
   147 
       
   148     void renameInit( const QString &host, const QString &user, const QString &password, const QString &createFile );
       
   149     void renameCleanup( const QString &host, const QString &user, const QString &password, const QString &fileToDelete );
       
   150 
       
   151     QFtp *ftp;
       
   152 
       
   153     QList<int> ids; // helper to make sure that all expected signals are emitted
       
   154     int current_id;
       
   155 
       
   156     int connectToHost_state;
       
   157     int close_state;
       
   158     int login_state;
       
   159     int cur_state;
       
   160     struct CommandResult
       
   161     {
       
   162         int id;
       
   163         int success;
       
   164     };
       
   165     QMap< QFtp::Command, CommandResult > resultMap;
       
   166     typedef QMap<QFtp::Command,CommandResult>::Iterator ResMapIt;
       
   167 
       
   168     int done_success;
       
   169     int commandSequence_success;
       
   170 
       
   171     qlonglong bytesAvailable_finishedGet;
       
   172     qlonglong bytesAvailable_finished;
       
   173     qlonglong bytesAvailable_done;
       
   174 
       
   175     QList<QUrlInfo> listInfo_i;
       
   176     QByteArray newData_ba;
       
   177     qlonglong bytesTotal;
       
   178     qlonglong bytesDone;
       
   179 
       
   180     bool inFileDirExistsFunction;
       
   181 
       
   182     QString uniqueExtension;
       
   183 };
       
   184 
       
   185 //#define DUMP_SIGNALS
       
   186 
       
   187 const int bytesTotal_init = -10;
       
   188 const int bytesDone_init = -10;
       
   189 
       
   190 tst_QFtp::tst_QFtp()
       
   191 {
       
   192     Q_SET_DEFAULT_IAP
       
   193 }
       
   194 
       
   195 tst_QFtp::~tst_QFtp()
       
   196 {
       
   197 }
       
   198 
       
   199 void tst_QFtp::initTestCase_data()
       
   200 {
       
   201     QTest::addColumn<bool>("setProxy");
       
   202     QTest::addColumn<int>("proxyType");
       
   203 
       
   204     QTest::newRow("WithoutProxy") << false << 0;
       
   205 #ifdef TEST_QNETWORK_PROXY
       
   206     QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy);
       
   207     //### doesn't work well yet.
       
   208     //QTest::newRow("WithHttpProxy") << true << int(QNetworkProxy::HttpProxy);
       
   209 #endif
       
   210 }
       
   211 
       
   212 void tst_QFtp::initTestCase()
       
   213 {
       
   214 }
       
   215 
       
   216 void tst_QFtp::cleanupTestCase()
       
   217 {
       
   218 }
       
   219 
       
   220 void tst_QFtp::init()
       
   221 {
       
   222     QFETCH_GLOBAL(bool, setProxy);
       
   223     if (setProxy) {
       
   224         QFETCH_GLOBAL(int, proxyType);
       
   225         if (proxyType == QNetworkProxy::Socks5Proxy) {
       
   226             QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080));
       
   227         } else if (proxyType == QNetworkProxy::HttpProxy) {
       
   228             QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128));
       
   229         }
       
   230     }
       
   231 
       
   232     ftp = 0;
       
   233 
       
   234     ids.clear();
       
   235     current_id = 0;
       
   236 
       
   237     resultMap.clear();
       
   238     connectToHost_state = -1;
       
   239     close_state = -1;
       
   240     login_state = -1;
       
   241     cur_state = QFtp::Unconnected;
       
   242 
       
   243     listInfo_i.clear();
       
   244     newData_ba = QByteArray();
       
   245     bytesTotal = bytesTotal_init;
       
   246     bytesDone = bytesDone_init;
       
   247 
       
   248     done_success = -1;
       
   249     commandSequence_success = -1;
       
   250 
       
   251     bytesAvailable_finishedGet = 1234567890;
       
   252     bytesAvailable_finished = 1234567890;
       
   253     bytesAvailable_done = 1234567890;
       
   254 
       
   255     inFileDirExistsFunction = FALSE;
       
   256 
       
   257 #if !defined(Q_OS_WINCE)
       
   258     srand(time(0));
       
   259     uniqueExtension = QString("%1%2%3").arg((qulonglong)this).arg(rand()).arg((qulonglong)time(0));
       
   260 #else
       
   261     srand(0);
       
   262     uniqueExtension = QString("%1%2%3").arg((qulonglong)this).arg(rand()).arg((qulonglong)(0));
       
   263 #endif
       
   264 }
       
   265 
       
   266 void tst_QFtp::cleanup()
       
   267 {
       
   268     QFETCH_GLOBAL(bool, setProxy);
       
   269     if (setProxy) {
       
   270         QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
       
   271     }
       
   272 }
       
   273 
       
   274 void tst_QFtp::connectToHost_data()
       
   275 {
       
   276     QTest::addColumn<QString>("host");
       
   277     QTest::addColumn<uint>("port");
       
   278     QTest::addColumn<int>("state");
       
   279 
       
   280     QTest::newRow( "ok01" ) << QtNetworkSettings::serverName() << (uint)21 << (int)QFtp::Connected;
       
   281     QTest::newRow( "error01" ) << QtNetworkSettings::serverName() << (uint)2222 << (int)QFtp::Unconnected;
       
   282     QTest::newRow( "error02" ) << QString("foo.bar") << (uint)21 << (int)QFtp::Unconnected;
       
   283 }
       
   284 
       
   285 void tst_QFtp::connectToHost()
       
   286 {
       
   287     QFETCH( QString, host );
       
   288     QFETCH( uint, port );
       
   289 
       
   290     ftp = newFtp();
       
   291     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   292 
       
   293     QTestEventLoop::instance().enterLoop( 61 );
       
   294     delete ftp;
       
   295     if ( QTestEventLoop::instance().timeout() )
       
   296         QFAIL( "Network operation timed out" );
       
   297 
       
   298     QTEST( connectToHost_state, "state" );
       
   299 
       
   300     ResMapIt it = resultMap.find( QFtp::ConnectToHost );
       
   301     QVERIFY( it != resultMap.end() );
       
   302     QFETCH( int, state );
       
   303     if ( state == QFtp::Connected ) {
       
   304         QVERIFY( it.value().success == 1 );
       
   305     } else {
       
   306         QVERIFY( it.value().success == 0 );
       
   307     }
       
   308 }
       
   309 
       
   310 void tst_QFtp::connectToUnresponsiveHost()
       
   311 {
       
   312     QFETCH_GLOBAL(bool, setProxy);
       
   313     if (setProxy)
       
   314         QSKIP( "This test takes too long if we test with proxies too", SkipSingle );
       
   315 
       
   316     QString host = "1.2.3.4";
       
   317     uint port = 21;
       
   318 
       
   319     ftp = newFtp();
       
   320     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   321 
       
   322     qDebug( "About to connect to host that won't reply (this test takes 60 seconds)" );
       
   323     QTestEventLoop::instance().enterLoop( 61 );
       
   324 #ifdef Q_OS_WIN
       
   325     /* On Windows, we do not get a timeout, because Winsock is behaving in a strange way:
       
   326     We issue two "WSAConnect()" calls, after the first, as a result we get WSAEWOULDBLOCK,
       
   327     after the second, we get WSAEISCONN, which means that the socket is connected, which cannot be.
       
   328     However, after some seconds we get a socket error saying that the remote host closed the connection,
       
   329     which can neither be. For this test, that would actually enable us to finish before timout, but handling that case
       
   330     (in void QFtpPI::error(QAbstractSocket::SocketError e)) breaks
       
   331     a lot of other stuff in QFtp, so we just expect this test to fail on Windows.
       
   332     */
       
   333     QEXPECT_FAIL("", "timeout not working due to strange Windows socket behaviour (see source file of this test for explanation)", Abort);
       
   334 #endif
       
   335     QVERIFY2(! QTestEventLoop::instance().timeout(), "Network timeout longer than expected (should have been 60 seconds)");
       
   336 
       
   337     QVERIFY( ftp->state() == QFtp::Unconnected);
       
   338     ResMapIt it = resultMap.find( QFtp::ConnectToHost );
       
   339     QVERIFY( it != resultMap.end() );
       
   340     QVERIFY( it.value().success == 0 );
       
   341 
       
   342     delete ftp;
       
   343 }
       
   344 
       
   345 void tst_QFtp::login_data()
       
   346 {
       
   347     QTest::addColumn<QString>("host");
       
   348     QTest::addColumn<uint>("port");
       
   349     QTest::addColumn<QString>("user");
       
   350     QTest::addColumn<QString>("password");
       
   351     QTest::addColumn<int>("success");
       
   352 
       
   353     QTest::newRow( "ok01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << 1;
       
   354     QTest::newRow( "ok02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftp") << QString() << 1;
       
   355     QTest::newRow( "ok03" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftp") << QString("foo") << 1;
       
   356     QTest::newRow( "ok04" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest") << QString("password") << 1;
       
   357 
       
   358     QTest::newRow( "error01" ) << QtNetworkSettings::serverName() << (uint)21 << QString("foo") << QString() << 0;
       
   359     QTest::newRow( "error02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("foo") << QString("bar") << 0;
       
   360 }
       
   361 
       
   362 void tst_QFtp::login()
       
   363 {
       
   364     QFETCH( QString, host );
       
   365     QFETCH( uint, port );
       
   366     QFETCH( QString, user );
       
   367     QFETCH( QString, password );
       
   368 
       
   369     ftp = newFtp();
       
   370     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   371     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   372 
       
   373     QTestEventLoop::instance().enterLoop( 30 );
       
   374     delete ftp;
       
   375     if ( QTestEventLoop::instance().timeout() )
       
   376         QFAIL( "Network operation timed out" );
       
   377 
       
   378     ResMapIt it = resultMap.find( QFtp::Login );
       
   379     QVERIFY( it != resultMap.end() );
       
   380     QTEST( it.value().success, "success" );
       
   381 
       
   382     if ( it.value().success ) {
       
   383         QVERIFY( login_state == QFtp::LoggedIn );
       
   384     } else {
       
   385         QVERIFY( login_state != QFtp::LoggedIn );
       
   386     }
       
   387 }
       
   388 
       
   389 void tst_QFtp::close_data()
       
   390 {
       
   391     QTest::addColumn<QString>("host");
       
   392     QTest::addColumn<uint>("port");
       
   393     QTest::addColumn<QString>("user");
       
   394     QTest::addColumn<QString>("password");
       
   395     QTest::addColumn<bool>("login");
       
   396 
       
   397     QTest::newRow( "login01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << (bool)TRUE;
       
   398     QTest::newRow( "login02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftp") << QString() << (bool)TRUE;
       
   399     QTest::newRow( "login03" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftp") << QString("foo") << (bool)TRUE;
       
   400     QTest::newRow( "login04" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest") << QString("password") << (bool)TRUE;
       
   401 
       
   402     QTest::newRow( "no-login01" ) << QtNetworkSettings::serverName() << (uint)21 << QString("") << QString("") << (bool)FALSE;
       
   403 }
       
   404 
       
   405 void tst_QFtp::close()
       
   406 {
       
   407     QFETCH( QString, host );
       
   408     QFETCH( uint, port );
       
   409     QFETCH( QString, user );
       
   410     QFETCH( QString, password );
       
   411     QFETCH( bool, login );
       
   412 
       
   413     ftp = newFtp();
       
   414     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   415     if ( login )
       
   416         addCommand( QFtp::Login, ftp->login( user, password ) );
       
   417     addCommand( QFtp::Close, ftp->close() );
       
   418 
       
   419     QTestEventLoop::instance().enterLoop( 30 );
       
   420     delete ftp;
       
   421     if ( QTestEventLoop::instance().timeout() )
       
   422         QFAIL( "Network operation timed out" );
       
   423 
       
   424     QCOMPARE( close_state, (int)QFtp::Unconnected );
       
   425 
       
   426     ResMapIt it = resultMap.find( QFtp::Close );
       
   427     QVERIFY( it != resultMap.end() );
       
   428     QVERIFY( it.value().success == 1 );
       
   429 }
       
   430 
       
   431 void tst_QFtp::list_data()
       
   432 {
       
   433     QTest::addColumn<QString>("host");
       
   434     QTest::addColumn<uint>("port");
       
   435     QTest::addColumn<QString>("user");
       
   436     QTest::addColumn<QString>("password");
       
   437     QTest::addColumn<QString>("dir");
       
   438     QTest::addColumn<int>("success");
       
   439     QTest::addColumn<QStringList>("entryNames"); // ### we should rather use a QList<QUrlInfo> here
       
   440 
       
   441     QStringList flukeRoot;
       
   442     flukeRoot << "pub";
       
   443     flukeRoot << "qtest";
       
   444     QStringList flukeQtest;
       
   445     flukeQtest << "bigfile";
       
   446     flukeQtest << "nonASCII";
       
   447     flukeQtest << "rfc3252";
       
   448     flukeQtest << "rfc3252.txt";
       
   449     flukeQtest << "upload";
       
   450 
       
   451     QTest::newRow( "workDir01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString() << 1 << flukeRoot;
       
   452     QTest::newRow( "workDir02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")     << QString() << 1 << flukeRoot;
       
   453 
       
   454     QTest::newRow( "relPath01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("qtest") << 1 << flukeQtest;
       
   455     QTest::newRow( "relPath02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")     << QString("qtest") << 1 << flukeQtest;
       
   456 
       
   457     QTest::newRow( "absPath01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("/qtest") << 1 << flukeQtest;
       
   458     QTest::newRow( "absPath02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")     << QString("/var/ftp/qtest") << 1 << flukeQtest;
       
   459 
       
   460     QTest::newRow( "nonExist01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("foo")  << 1 << QStringList();
       
   461     QTest::newRow( "nonExist02" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("/foo") << 1 << QStringList();
       
   462     // ### The microsoft server does not seem to work properly at the moment --
       
   463     // I am also not able to open a data connection with other, non-Qt FTP
       
   464     // clients to it.
       
   465     // QTest::newRow( "nonExist03" ) << "ftp.microsoft.com" << (uint)21 << QString() << QString() << QString("/foo") << 0 << QStringList();
       
   466 
       
   467     QStringList susePub;
       
   468     susePub << "README.mirror-policy" << "axp" << "i386" << "ia64" << "install" << "noarch" << "pubring.gpg-build.suse.de" << "update" << "x86_64";
       
   469     QTest::newRow( "epsvNotSupported" ) << QString("ftp.funet.fi") << (uint)21 << QString::fromLatin1("ftp") << QString::fromLatin1("root@") << QString("/pub/Linux/suse/suse") << 1 << susePub;
       
   470 }
       
   471 
       
   472 void tst_QFtp::list()
       
   473 {
       
   474     QFETCH( QString, host );
       
   475     QFETCH( uint, port );
       
   476     QFETCH( QString, user );
       
   477     QFETCH( QString, password );
       
   478     QFETCH( QString, dir );
       
   479 
       
   480     ftp = newFtp();
       
   481     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   482     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   483     addCommand( QFtp::List, ftp->list( dir ) );
       
   484     addCommand( QFtp::Close, ftp->close() );
       
   485 
       
   486     QTestEventLoop::instance().enterLoop( 30 );
       
   487     delete ftp;
       
   488     if ( QTestEventLoop::instance().timeout() )
       
   489         QFAIL( "Network operation timed out" );
       
   490 
       
   491     ResMapIt it = resultMap.find( QFtp::List );
       
   492     QVERIFY( it != resultMap.end() );
       
   493     QTEST( it.value().success, "success" );
       
   494     QFETCH( QStringList, entryNames );
       
   495     QCOMPARE( listInfo_i.count(), entryNames.count() );
       
   496     for ( uint i=0; i < (uint) entryNames.count(); i++ ) {
       
   497         QCOMPARE( listInfo_i[i].name(), entryNames[i] );
       
   498     }
       
   499 }
       
   500 
       
   501 void tst_QFtp::cd_data()
       
   502 {
       
   503     QTest::addColumn<QString>("host");
       
   504     QTest::addColumn<uint>("port");
       
   505     QTest::addColumn<QString>("user");
       
   506     QTest::addColumn<QString>("password");
       
   507     QTest::addColumn<QString>("dir");
       
   508     QTest::addColumn<int>("success");
       
   509     QTest::addColumn<QStringList>("entryNames"); // ### we should rather use a QList<QUrlInfo> here
       
   510 
       
   511     QStringList flukeRoot;
       
   512     flukeRoot << "qtest";
       
   513     QStringList flukeQtest;
       
   514     flukeQtest << "bigfile";
       
   515     flukeQtest << "nonASCII";
       
   516     flukeQtest << "rfc3252";
       
   517     flukeQtest << "rfc3252.txt";
       
   518     flukeQtest << "upload";
       
   519 
       
   520     QTest::newRow( "relPath01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("qtest") << 1 << flukeQtest;
       
   521     QTest::newRow( "relPath02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")     << QString("qtest") << 1 << flukeQtest;
       
   522 
       
   523     QTest::newRow( "absPath01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("/qtest") << 1 << flukeQtest;
       
   524     QTest::newRow( "absPath02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")     << QString("/var/ftp/qtest") << 1 << flukeQtest;
       
   525 
       
   526     QTest::newRow( "nonExist01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("foo")  << 0 << QStringList();
       
   527     QTest::newRow( "nonExist03" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("/foo") << 0 << QStringList();
       
   528 }
       
   529 
       
   530 void tst_QFtp::cd()
       
   531 {
       
   532     QFETCH( QString, host );
       
   533     QFETCH( uint, port );
       
   534     QFETCH( QString, user );
       
   535     QFETCH( QString, password );
       
   536     QFETCH( QString, dir );
       
   537 
       
   538     ftp = newFtp();
       
   539     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   540     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   541     addCommand( QFtp::Cd, ftp->cd( dir ) );
       
   542     addCommand( QFtp::List, ftp->list() );
       
   543     addCommand( QFtp::Close, ftp->close() );
       
   544 
       
   545     QTestEventLoop::instance().enterLoop( 30 );
       
   546 
       
   547     delete ftp;
       
   548     if ( QTestEventLoop::instance().timeout() ) {
       
   549         QFAIL( "Network operation timed out" );
       
   550     }
       
   551 
       
   552     ResMapIt it = resultMap.find( QFtp::Cd );
       
   553     QVERIFY( it != resultMap.end() );
       
   554     QTEST( it.value().success, "success" );
       
   555     QFETCH( QStringList, entryNames );
       
   556     QCOMPARE( listInfo_i.count(), entryNames.count() );
       
   557     for ( uint i=0; i < (uint) entryNames.count(); i++ ) {
       
   558         QCOMPARE( listInfo_i[i].name(), entryNames[i] );
       
   559     }
       
   560 }
       
   561 
       
   562 void tst_QFtp::get_data()
       
   563 {
       
   564     QTest::addColumn<QString>("host");
       
   565     QTest::addColumn<uint>("port");
       
   566     QTest::addColumn<QString>("user");
       
   567     QTest::addColumn<QString>("password");
       
   568     QTest::addColumn<QString>("file");
       
   569     QTest::addColumn<int>("success");
       
   570     QTest::addColumn<QByteArray>("res");
       
   571     QTest::addColumn<bool>("useIODevice");
       
   572 
       
   573     // ### move this into external testdata
       
   574     QFile file( SRCDIR "rfc3252.txt" );
       
   575     QVERIFY( file.open( QIODevice::ReadOnly ) );
       
   576     QByteArray rfc3252 = file.readAll();
       
   577 
       
   578     // test the two get() overloads in one routine
       
   579     for ( int i=0; i<2; i++ ) {
       
   580         QTest::newRow( QString("relPath01_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   581                 << "qtest/rfc3252" << 1 << rfc3252 << (bool)(i==1);
       
   582         QTest::newRow( QString("relPath02_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")
       
   583                 << "qtest/rfc3252" << 1 << rfc3252 << (bool)(i==1);
       
   584 
       
   585         QTest::newRow( QString("absPath01_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   586                 << "/qtest/rfc3252" << 1 << rfc3252 << (bool)(i==1);
       
   587         QTest::newRow( QString("absPath02_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")
       
   588                 << "/var/ftp/qtest/rfc3252" << 1 << rfc3252 << (bool)(i==1);
       
   589 
       
   590         QTest::newRow( QString("nonExist01_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   591                 << QString("foo")  << 0 << QByteArray() << (bool)(i==1);
       
   592         QTest::newRow( QString("nonExist02_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   593                 << QString("/foo") << 0 << QByteArray() << (bool)(i==1);
       
   594     }
       
   595 }
       
   596 
       
   597 void tst_QFtp::get()
       
   598 {
       
   599     // for the overload that takes a QIODevice
       
   600     QByteArray buf_ba;
       
   601     QBuffer buf( &buf_ba );
       
   602 
       
   603     QFETCH( QString, host );
       
   604     QFETCH( uint, port );
       
   605     QFETCH( QString, user );
       
   606     QFETCH( QString, password );
       
   607     QFETCH( QString, file );
       
   608     QFETCH( bool, useIODevice );
       
   609 
       
   610     ftp = newFtp();
       
   611     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   612     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   613     if ( useIODevice ) {
       
   614         buf.open( QIODevice::WriteOnly );
       
   615         addCommand( QFtp::Get, ftp->get( file, &buf ) );
       
   616     } else {
       
   617         addCommand( QFtp::Get, ftp->get( file ) );
       
   618     }
       
   619     addCommand( QFtp::Close, ftp->close() );
       
   620 
       
   621     QTestEventLoop::instance().enterLoop( 30 );
       
   622     delete ftp;
       
   623     if ( QTestEventLoop::instance().timeout() )
       
   624         QFAIL( "Network operation timed out" );
       
   625 
       
   626     ResMapIt it = resultMap.find( QFtp::Get );
       
   627     QVERIFY( it != resultMap.end() );
       
   628     QTEST( it.value().success, "success" );
       
   629     if ( useIODevice ) {
       
   630         QTEST( buf_ba, "res" );
       
   631     } else {
       
   632         QTEST( newData_ba, "res" );
       
   633     }
       
   634     QVERIFY( bytesTotal != bytesTotal_init );
       
   635     if ( bytesTotal != -1 ) {
       
   636         QVERIFY( bytesDone == bytesTotal );
       
   637     }
       
   638     if ( useIODevice ) {
       
   639         if ( bytesDone != bytesDone_init ) {
       
   640             QVERIFY( (int)buf_ba.size() == bytesDone );
       
   641         }
       
   642     } else {
       
   643         if ( bytesDone != bytesDone_init ) {
       
   644             QVERIFY( (int)newData_ba.size() == bytesDone );
       
   645         }
       
   646     }
       
   647 }
       
   648 
       
   649 void tst_QFtp::put_data()
       
   650 {
       
   651     QTest::addColumn<QString>("host");
       
   652     QTest::addColumn<uint>("port");
       
   653     QTest::addColumn<QString>("user");
       
   654     QTest::addColumn<QString>("password");
       
   655     QTest::addColumn<QString>("file");
       
   656     QTest::addColumn<QByteArray>("fileData");
       
   657     QTest::addColumn<bool>("useIODevice");
       
   658     QTest::addColumn<int>("success");
       
   659 
       
   660     // ### move this into external testdata
       
   661     QFile file( SRCDIR "rfc3252.txt" );
       
   662     QVERIFY( file.open( QIODevice::ReadOnly ) );
       
   663     QByteArray rfc3252 = file.readAll();
       
   664 
       
   665     QByteArray bigData( 10*1024*1024, 0 );
       
   666     bigData.fill( 'A' );
       
   667 
       
   668     // test the two put() overloads in one routine
       
   669     for ( int i=0; i<2; i++ ) {
       
   670         QTest::newRow( QString("relPath01_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   671                 << QString("qtest/upload/rel01_%1") << rfc3252
       
   672                 << (bool)(i==1) << 1;
       
   673         /*
       
   674     QTest::newRow( QString("relPath02_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")
       
   675         << QString("qtest/upload/rel02_%1") << rfc3252
       
   676         << (bool)(i==1) << 1;
       
   677     QTest::newRow( QString("relPath03_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")
       
   678         << QString("qtest/upload/rel03_%1") << QByteArray()
       
   679         << (bool)(i==1) << 1;
       
   680     QTest::newRow( QString("relPath04_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")
       
   681         << QString("qtest/upload/rel04_%1") << bigData
       
   682         << (bool)(i==1) << 1;
       
   683 
       
   684     QTest::newRow( QString("absPath01_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   685         << QString("/qtest/upload/abs01_%1") << rfc3252
       
   686         << (bool)(i==1) << 1;
       
   687     QTest::newRow( QString("absPath02_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")
       
   688         << QString("/srv/ftp/qtest/upload/abs02_%1") << rfc3252
       
   689         << (bool)(i==1) << 1;
       
   690 
       
   691     QTest::newRow( QString("nonExist01_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   692         << QString("foo")  << QByteArray()
       
   693         << (bool)(i==1) << 0;
       
   694     QTest::newRow( QString("nonExist02_%1").arg(i).toLatin1().constData() ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   695         << QString("/foo") << QByteArray()
       
   696         << (bool)(i==1) << 0;
       
   697 */
       
   698     }
       
   699 }
       
   700 
       
   701 void tst_QFtp::put()
       
   702 {
       
   703     QFETCH( QString, host );
       
   704     QFETCH( uint, port );
       
   705     QFETCH( QString, user );
       
   706     QFETCH( QString, password );
       
   707     QFETCH( QString, file );
       
   708     QFETCH( QByteArray, fileData );
       
   709     QFETCH( bool, useIODevice );
       
   710 
       
   711 #ifdef Q_OS_WIN
       
   712     QFETCH_GLOBAL(bool, setProxy);
       
   713     if (setProxy) {
       
   714         QFETCH_GLOBAL(int, proxyType);
       
   715         if (proxyType == QNetworkProxy::Socks5Proxy) {
       
   716             QSKIP("With socks5 the put() test takes too long time on Windows.", SkipAll);
       
   717         }
       
   718     }
       
   719 #endif
       
   720 
       
   721     const int timestep = 50;
       
   722 
       
   723     if(file.contains('%'))
       
   724         file = file.arg(uniqueExtension);
       
   725 
       
   726     // for the overload that takes a QIODevice
       
   727     QBuffer buf_fileData( &fileData );
       
   728     buf_fileData.open( QIODevice::ReadOnly );
       
   729 
       
   730     ResMapIt it;
       
   731     //////////////////////////////////////////////////////////////////
       
   732     // upload the file
       
   733     init();
       
   734     ftp = newFtp();
       
   735     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   736     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   737     if ( useIODevice )
       
   738         addCommand( QFtp::Put, ftp->put( &buf_fileData, file ) );
       
   739     else
       
   740         addCommand( QFtp::Put, ftp->put( fileData, file ) );
       
   741     addCommand( QFtp::Close, ftp->close() );
       
   742 
       
   743     for(int time = 0; time <= fileData.length() / 20000; time += timestep) {
       
   744         QTestEventLoop::instance().enterLoop( timestep );
       
   745         if(ftp->currentCommand() == QFtp::None)
       
   746             break;
       
   747     }
       
   748     delete ftp;
       
   749     if ( QTestEventLoop::instance().timeout() )
       
   750         QFAIL( "Network operation timed out" );
       
   751 
       
   752     it = resultMap.find( QFtp::Put );
       
   753     QVERIFY( it != resultMap.end() );
       
   754     QTEST( it.value().success, "success" );
       
   755     if ( !it.value().success ) {
       
   756         QVERIFY( !fileExists( host, port, user, password, file ) );
       
   757         return; // the following tests are only meaningful if the file could be put
       
   758     }
       
   759     QVERIFY( bytesTotal == (int)fileData.size() );
       
   760     QVERIFY( bytesDone == bytesTotal );
       
   761 
       
   762     QVERIFY( fileExists( host, port, user, password, file ) );
       
   763 
       
   764     //////////////////////////////////////////////////////////////////
       
   765     // fetch file to make sure that it is equal to the uploaded file
       
   766     init();
       
   767     ftp = newFtp();
       
   768     QBuffer buf;
       
   769     buf.open( QIODevice::WriteOnly );
       
   770     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   771     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   772     addCommand( QFtp::Get, ftp->get( file, &buf ) );
       
   773     addCommand( QFtp::Close, ftp->close() );
       
   774 
       
   775     for(int time = 0; time <= fileData.length() / 20000; time += timestep) {
       
   776         QTestEventLoop::instance().enterLoop( timestep );
       
   777         if(ftp->currentCommand() == QFtp::None)
       
   778             break;
       
   779     }
       
   780     delete ftp;
       
   781     if ( QTestEventLoop::instance().timeout() )
       
   782         QFAIL( "Network operation timed out" );
       
   783 
       
   784     QVERIFY( done_success == 1 );
       
   785     QTEST( buf.buffer(), "fileData" );
       
   786 
       
   787     //////////////////////////////////////////////////////////////////
       
   788     // cleanup (i.e. remove the file) -- this also tests the remove command
       
   789     init();
       
   790     ftp = newFtp();
       
   791     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   792     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   793     addCommand( QFtp::Remove, ftp->remove( file ) );
       
   794     addCommand( QFtp::Close, ftp->close() );
       
   795 
       
   796     QTestEventLoop::instance().enterLoop( timestep );
       
   797     delete ftp;
       
   798     if ( QTestEventLoop::instance().timeout() )
       
   799         QFAIL( "Network operation timed out" );
       
   800 
       
   801     it = resultMap.find( QFtp::Remove );
       
   802     QVERIFY( it != resultMap.end() );
       
   803     QCOMPARE( it.value().success, 1 );
       
   804 
       
   805     QVERIFY( !fileExists( host, port, user, password, file ) );
       
   806 }
       
   807 
       
   808 void tst_QFtp::remove()
       
   809 {
       
   810     DEPENDS_ON( "put" );
       
   811 }
       
   812 
       
   813 void tst_QFtp::mkdir_data()
       
   814 {
       
   815     QTest::addColumn<QString>("host");
       
   816     QTest::addColumn<uint>("port");
       
   817     QTest::addColumn<QString>("user");
       
   818     QTest::addColumn<QString>("password");
       
   819     QTest::addColumn<QString>("cdDir");
       
   820     QTest::addColumn<QString>("dirToCreate");
       
   821     QTest::addColumn<int>("success");
       
   822 
       
   823     QTest::newRow( "relPath01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   824             << "qtest/upload" << QString("rel01_%1") << 1;
       
   825     QTest::newRow( "relPath02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")
       
   826             << "qtest/upload" << QString("rel02_%1") << 1;
       
   827     QTest::newRow( "relPath03" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")
       
   828             << "qtest/upload" << QString("rel03_%1") << 1;
       
   829 
       
   830     QTest::newRow( "absPath01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   831             << "." << QString("/qtest/upload/abs01_%1") << 1;
       
   832     QTest::newRow( "absPath02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")
       
   833             << "." << QString("/var/ftp/qtest/upload/abs02_%1") << 1;
       
   834 
       
   835     //    QTest::newRow( "nonExist01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("foo")  << 0;
       
   836     QTest::newRow( "nonExist01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   837             << "." << QString("foo")  << 0;
       
   838     QTest::newRow( "nonExist02" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString()
       
   839             << "." << QString("/foo") << 0;
       
   840 }
       
   841 
       
   842 void tst_QFtp::mkdir()
       
   843 {
       
   844     QFETCH( QString, host );
       
   845     QFETCH( uint, port );
       
   846     QFETCH( QString, user );
       
   847     QFETCH( QString, password );
       
   848     QFETCH( QString, cdDir );
       
   849     QFETCH( QString, dirToCreate );
       
   850 
       
   851     if(dirToCreate.contains('%'))
       
   852         dirToCreate = dirToCreate.arg(uniqueExtension);
       
   853 
       
   854     //////////////////////////////////////////////////////////////////
       
   855     // create the directory
       
   856     init();
       
   857     ftp = newFtp();
       
   858     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   859     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   860     addCommand( QFtp::Cd, ftp->cd( cdDir ) );
       
   861     addCommand( QFtp::Mkdir, ftp->mkdir( dirToCreate ) );
       
   862     addCommand( QFtp::Close, ftp->close() );
       
   863 
       
   864     QTestEventLoop::instance().enterLoop( 30 );
       
   865     delete ftp;
       
   866     if ( QTestEventLoop::instance().timeout() )
       
   867         QFAIL( "Network operation timed out" );
       
   868 
       
   869     ResMapIt it = resultMap.find( QFtp::Mkdir );
       
   870     QVERIFY( it != resultMap.end() );
       
   871     QTEST( it.value().success, "success" );
       
   872     if ( !it.value().success ) {
       
   873         QVERIFY( !dirExists( host, port, user, password, cdDir, dirToCreate ) );
       
   874         return; // the following tests are only meaningful if the dir could be created
       
   875     }
       
   876     QVERIFY( dirExists( host, port, user, password, cdDir, dirToCreate ) );
       
   877 
       
   878     //////////////////////////////////////////////////////////////////
       
   879     // create the directory again (should always fail!)
       
   880     init();
       
   881     ftp = newFtp();
       
   882     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   883     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   884     addCommand( QFtp::Cd, ftp->cd( cdDir ) );
       
   885     addCommand( QFtp::Mkdir, ftp->mkdir( dirToCreate ) );
       
   886     addCommand( QFtp::Close, ftp->close() );
       
   887 
       
   888     QTestEventLoop::instance().enterLoop( 30 );
       
   889     delete ftp;
       
   890     if ( QTestEventLoop::instance().timeout() )
       
   891         QFAIL( "Network operation timed out" );
       
   892 
       
   893     it = resultMap.find( QFtp::Mkdir );
       
   894     QVERIFY( it != resultMap.end() );
       
   895     QCOMPARE( it.value().success, 0 );
       
   896 
       
   897     //////////////////////////////////////////////////////////////////
       
   898     // remove the directory
       
   899     init();
       
   900     ftp = newFtp();
       
   901     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
   902     addCommand( QFtp::Login, ftp->login( user, password ) );
       
   903     addCommand( QFtp::Cd, ftp->cd( cdDir ) );
       
   904     addCommand( QFtp::Rmdir, ftp->rmdir( dirToCreate ) );
       
   905     addCommand( QFtp::Close, ftp->close() );
       
   906 
       
   907     QTestEventLoop::instance().enterLoop( 30 );
       
   908     delete ftp;
       
   909     if ( QTestEventLoop::instance().timeout() )
       
   910         QFAIL( "Network operation timed out" );
       
   911 
       
   912     it = resultMap.find( QFtp::Rmdir );
       
   913     QVERIFY( it != resultMap.end() );
       
   914     QCOMPARE( it.value().success, 1 );
       
   915 
       
   916     QVERIFY( !dirExists( host, port, user, password, cdDir, dirToCreate ) );
       
   917 }
       
   918 
       
   919 void tst_QFtp::mkdir2()
       
   920 {
       
   921     ftp = new QFtp;
       
   922     ftp->connectToHost(QtNetworkSettings::serverName());
       
   923     ftp->login();
       
   924     current_id = ftp->cd("kake/test");
       
   925 
       
   926     QEventLoop loop;
       
   927     connect(ftp, SIGNAL(done(bool)), &loop, SLOT(quit()));
       
   928     connect(ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(mkdir2Slot(int, bool)));
       
   929     QTimer::singleShot(5000, &loop, SLOT(quit()));
       
   930 
       
   931     QSignalSpy commandStartedSpy(ftp, SIGNAL(commandStarted(int)));
       
   932     QSignalSpy commandFinishedSpy(ftp, SIGNAL(commandFinished(int, bool)));
       
   933 
       
   934     loop.exec();
       
   935 
       
   936     QCOMPARE(commandStartedSpy.count(), 4); // connect, login, cd, mkdir
       
   937     QCOMPARE(commandFinishedSpy.count(), 4);
       
   938 
       
   939     for (int i = 0; i < 4; ++i)
       
   940         QCOMPARE(commandFinishedSpy.at(i).at(0), commandStartedSpy.at(i).at(0));
       
   941 
       
   942     QVERIFY(!commandFinishedSpy.at(0).at(1).toBool());
       
   943     QVERIFY(!commandFinishedSpy.at(1).at(1).toBool());
       
   944     QVERIFY(commandFinishedSpy.at(2).at(1).toBool());
       
   945     QVERIFY(commandFinishedSpy.at(3).at(1).toBool());
       
   946 
       
   947     delete ftp;
       
   948 }
       
   949 
       
   950 void tst_QFtp::mkdir2Slot(int id, bool)
       
   951 {
       
   952     if (id == current_id)
       
   953         ftp->mkdir("kake/test");
       
   954 }
       
   955 
       
   956 void tst_QFtp::rmdir()
       
   957 {
       
   958     DEPENDS_ON( "mkdir" );
       
   959 }
       
   960 
       
   961 void tst_QFtp::rename_data()
       
   962 {
       
   963     QTest::addColumn<QString>("host");
       
   964     QTest::addColumn<QString>("user");
       
   965     QTest::addColumn<QString>("password");
       
   966     QTest::addColumn<QString>("cdDir");
       
   967     QTest::addColumn<QString>("oldfile");
       
   968     QTest::addColumn<QString>("newfile");
       
   969     QTest::addColumn<QString>("createFile");
       
   970     QTest::addColumn<QString>("renamedFile");
       
   971     QTest::addColumn<int>("success");
       
   972 
       
   973     QTest::newRow("relPath01") << QtNetworkSettings::serverName() << QString() << QString()
       
   974             << "qtest/upload"
       
   975             << QString("rel_old01_%1") << QString("rel_new01_%1")
       
   976             << QString("qtest/upload/rel_old01_%1") << QString("qtest/upload/rel_new01_%1")
       
   977             << 1;
       
   978     QTest::newRow("relPath02") << QtNetworkSettings::serverName() << QString("ftptest")     << "password"
       
   979             << "qtest/upload"
       
   980             << QString("rel_old02_%1") << QString("rel_new02_%1")
       
   981             << QString("qtest/upload/rel_old02_%1") << QString("qtest/upload/rel_new02_%1")
       
   982             << 1;
       
   983     QTest::newRow("relPath03") << QtNetworkSettings::serverName() << QString("ftptest")     << "password"
       
   984             << "qtest/upload"
       
   985             << QString("rel_old03_%1")<< QString("rel_new03_%1")
       
   986             << QString("qtest/upload/rel_old03_%1") << QString("qtest/upload/rel_new03_%1")
       
   987             << 1;
       
   988 
       
   989     QTest::newRow("absPath01") << QtNetworkSettings::serverName() << QString() << QString()
       
   990             << QString()
       
   991             << QString("/qtest/upload/abs_old01_%1") << QString("/qtest/upload/abs_new01_%1")
       
   992             << QString("/qtest/upload/abs_old01_%1") << QString("/qtest/upload/abs_new01_%1")
       
   993             << 1;
       
   994     QTest::newRow("absPath02") << QtNetworkSettings::serverName() << QString("ftptest")     << "password"
       
   995             << QString()
       
   996             << QString("/var/ftp/qtest/upload/abs_old02_%1") << QString("/var/ftp/qtest/upload/abs_new02_%1")
       
   997             << QString("/var/ftp/qtest/upload/abs_old02_%1") << QString("/var/ftp/qtest/upload/abs_new02_%1")
       
   998             << 1;
       
   999 
       
  1000     QTest::newRow("nonExist01") << QtNetworkSettings::serverName() << QString() << QString()
       
  1001             << QString()
       
  1002             << QString("foo") << "new_foo"
       
  1003             << QString() << QString()
       
  1004             << 0;
       
  1005     QTest::newRow("nonExist02") << QtNetworkSettings::serverName() << QString() << QString()
       
  1006             << QString()
       
  1007             << QString("/foo") << QString("/new_foo")
       
  1008             << QString() << QString()
       
  1009             << 0;
       
  1010 }
       
  1011 
       
  1012 void tst_QFtp::renameInit( const QString &host, const QString &user, const QString &password, const QString &createFile )
       
  1013 {
       
  1014     if ( !createFile.isNull() ) {
       
  1015         // upload the file
       
  1016         init();
       
  1017         ftp = newFtp();
       
  1018         addCommand( QFtp::ConnectToHost, ftp->connectToHost( host ) );
       
  1019         addCommand( QFtp::Login, ftp->login( user, password ) );
       
  1020         addCommand( QFtp::Put, ftp->put( QByteArray(), createFile ) );
       
  1021         addCommand( QFtp::Close, ftp->close() );
       
  1022 
       
  1023         QTestEventLoop::instance().enterLoop( 30 );
       
  1024         delete ftp;
       
  1025         if ( QTestEventLoop::instance().timeout() )
       
  1026             QFAIL( "Network operation timed out" );
       
  1027 
       
  1028         ResMapIt it = resultMap.find( QFtp::Put );
       
  1029         QVERIFY( it != resultMap.end() );
       
  1030         QVERIFY( it.value().success == 1 );
       
  1031 
       
  1032         QVERIFY( fileExists( host, 21, user, password, createFile ) );
       
  1033     }
       
  1034 }
       
  1035 
       
  1036 void tst_QFtp::renameCleanup( const QString &host, const QString &user, const QString &password, const QString &fileToDelete )
       
  1037 {
       
  1038     if ( !fileToDelete.isNull() ) {
       
  1039         // cleanup (i.e. remove the file)
       
  1040         init();
       
  1041         ftp = newFtp();
       
  1042         addCommand( QFtp::ConnectToHost, ftp->connectToHost( host ) );
       
  1043         addCommand( QFtp::Login, ftp->login( user, password ) );
       
  1044         addCommand( QFtp::Remove, ftp->remove( fileToDelete ) );
       
  1045         addCommand( QFtp::Close, ftp->close() );
       
  1046 
       
  1047         QTestEventLoop::instance().enterLoop( 30 );
       
  1048         delete ftp;
       
  1049         if ( QTestEventLoop::instance().timeout() )
       
  1050             QFAIL( "Network operation timed out" );
       
  1051 
       
  1052         ResMapIt it = resultMap.find( QFtp::Remove );
       
  1053         QVERIFY( it != resultMap.end() );
       
  1054         QVERIFY( it.value().success == 1 );
       
  1055 
       
  1056         QVERIFY( !fileExists( host, 21, user, password, fileToDelete ) );
       
  1057     }
       
  1058 }
       
  1059 
       
  1060 void tst_QFtp::rename()
       
  1061 {
       
  1062     QFETCH( QString, host );
       
  1063     QFETCH( QString, user );
       
  1064     QFETCH( QString, password );
       
  1065     QFETCH( QString, cdDir );
       
  1066     QFETCH( QString, oldfile );
       
  1067     QFETCH( QString, newfile );
       
  1068     QFETCH( QString, createFile );
       
  1069     QFETCH( QString, renamedFile );
       
  1070 
       
  1071     if(oldfile.contains('%'))
       
  1072         oldfile = oldfile.arg(uniqueExtension);
       
  1073     if(newfile.contains('%'))
       
  1074         newfile = newfile.arg(uniqueExtension);
       
  1075     if(createFile.contains('%'))
       
  1076         createFile = createFile.arg(uniqueExtension);
       
  1077     if(renamedFile.contains('%'))
       
  1078         renamedFile = renamedFile.arg(uniqueExtension);
       
  1079 
       
  1080     renameInit( host, user, password, createFile );
       
  1081 
       
  1082     init();
       
  1083     ftp = newFtp();
       
  1084     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host ) );
       
  1085     addCommand( QFtp::Login, ftp->login( user, password ) );
       
  1086     if ( !cdDir.isNull() )
       
  1087         addCommand( QFtp::Cd, ftp->cd( cdDir ) );
       
  1088     addCommand( QFtp::Rename, ftp->rename( oldfile, newfile ) );
       
  1089     addCommand( QFtp::Close, ftp->close() );
       
  1090 
       
  1091     QTestEventLoop::instance().enterLoop( 30 );
       
  1092     delete ftp;
       
  1093     if ( QTestEventLoop::instance().timeout() )
       
  1094         QFAIL( "Network operation timed out" );
       
  1095 
       
  1096     ResMapIt it = resultMap.find( QFtp::Rename );
       
  1097     QVERIFY( it != resultMap.end() );
       
  1098     QTEST( it.value().success, "success" );
       
  1099 
       
  1100     if ( it.value().success ) {
       
  1101         QVERIFY( !fileExists( host, 21, user, password, oldfile, cdDir ) );
       
  1102         QVERIFY( fileExists( host, 21, user, password, newfile, cdDir ) );
       
  1103         QVERIFY( fileExists( host, 21, user, password, renamedFile ) );
       
  1104     } else {
       
  1105         QVERIFY( !fileExists( host, 21, user, password, newfile, cdDir ) );
       
  1106         QVERIFY( !fileExists( host, 21, user, password, renamedFile ) );
       
  1107     }
       
  1108 
       
  1109     renameCleanup( host, user, password, renamedFile );
       
  1110 }
       
  1111 
       
  1112 /*
       
  1113   The commandSequence() test does not test any particular function. It rather
       
  1114   tests a sequence of arbitrary commands specified in the test data.
       
  1115 */
       
  1116 class FtpCommand
       
  1117 {
       
  1118 public:
       
  1119     FtpCommand() :
       
  1120             cmd(QFtp::None)
       
  1121     { }
       
  1122 
       
  1123     FtpCommand( QFtp::Command command ) :
       
  1124             cmd(command)
       
  1125     { }
       
  1126 
       
  1127     FtpCommand( QFtp::Command command, const QStringList &arguments ) :
       
  1128             cmd(command), args(arguments)
       
  1129     { }
       
  1130 
       
  1131     FtpCommand( const FtpCommand &c )
       
  1132     { *this = c; }
       
  1133 
       
  1134     FtpCommand &operator=( const FtpCommand &c )
       
  1135                          {
       
  1136         this->cmd  = c.cmd;
       
  1137         this->args = c.args;
       
  1138         return *this;
       
  1139     }
       
  1140 
       
  1141     QFtp::Command cmd;
       
  1142     QStringList args;
       
  1143 };
       
  1144 QDataStream &operator<<( QDataStream &s, const FtpCommand &command )
       
  1145 {
       
  1146     s << (int)command.cmd;
       
  1147     s << command.args;
       
  1148     return s;
       
  1149 }
       
  1150 QDataStream &operator>>( QDataStream &s, FtpCommand &command )
       
  1151 {
       
  1152     int tmp;
       
  1153     s >> tmp;
       
  1154     command.cmd = (QFtp::Command)tmp;
       
  1155     s >> command.args;
       
  1156     return s;
       
  1157 }
       
  1158 Q_DECLARE_METATYPE(QList<FtpCommand>)
       
  1159 
       
  1160 void tst_QFtp::commandSequence_data()
       
  1161 {
       
  1162     // some "constants"
       
  1163     QStringList argConnectToHost01;
       
  1164     argConnectToHost01 << QtNetworkSettings::serverName() << "21";
       
  1165 
       
  1166     QStringList argLogin01, argLogin02, argLogin03, argLogin04;
       
  1167     argLogin01 << QString() << QString();
       
  1168     argLogin02 << "ftp"         << QString();
       
  1169     argLogin03 << "ftp"         << "foo";
       
  1170     argLogin04 << QString("ftptest")     << "password";
       
  1171 
       
  1172     FtpCommand connectToHost01( QFtp::ConnectToHost, argConnectToHost01 );
       
  1173     FtpCommand login01( QFtp::Login, argLogin01 );
       
  1174     FtpCommand login02( QFtp::Login, argLogin01 );
       
  1175     FtpCommand login03( QFtp::Login, argLogin01 );
       
  1176     FtpCommand login04( QFtp::Login, argLogin01 );
       
  1177     FtpCommand close01( QFtp::Close );
       
  1178 
       
  1179     QTest::addColumn<QList<FtpCommand> >("cmds");
       
  1180     QTest::addColumn<int>("success");
       
  1181 
       
  1182     // success data
       
  1183     {
       
  1184         QList<FtpCommand> cmds;
       
  1185         cmds << connectToHost01;
       
  1186         QTest::newRow( "simple_ok01" ) << cmds << 1;
       
  1187     }
       
  1188     {
       
  1189         QList<FtpCommand> cmds;
       
  1190         cmds << connectToHost01;
       
  1191         cmds << login01;
       
  1192         QTest::newRow( "simple_ok02" ) << cmds << 1;
       
  1193     }
       
  1194     {
       
  1195         QList<FtpCommand> cmds;
       
  1196         cmds << connectToHost01;
       
  1197         cmds << login01;
       
  1198         cmds << close01;
       
  1199         QTest::newRow( "simple_ok03" ) << cmds << 1;
       
  1200     }
       
  1201     {
       
  1202         QList<FtpCommand> cmds;
       
  1203         cmds << connectToHost01;
       
  1204         cmds << close01;
       
  1205         QTest::newRow( "simple_ok04" ) << cmds << 1;
       
  1206     }
       
  1207     {
       
  1208         QList<FtpCommand> cmds;
       
  1209         cmds << connectToHost01;
       
  1210         cmds << login01;
       
  1211         cmds << close01;
       
  1212         cmds << connectToHost01;
       
  1213         cmds << login02;
       
  1214         cmds << close01;
       
  1215         QTest::newRow( "connect_twice" ) << cmds << 1;
       
  1216     }
       
  1217 
       
  1218     // error data
       
  1219     {
       
  1220         QList<FtpCommand> cmds;
       
  1221         cmds << close01;
       
  1222         QTest::newRow( "error01" ) << cmds << 0;
       
  1223     }
       
  1224     {
       
  1225         QList<FtpCommand> cmds;
       
  1226         cmds << login01;
       
  1227         QTest::newRow( "error02" ) << cmds << 0;
       
  1228     }
       
  1229     {
       
  1230         QList<FtpCommand> cmds;
       
  1231         cmds << login01;
       
  1232         cmds << close01;
       
  1233         QTest::newRow( "error03" ) << cmds << 0;
       
  1234     }
       
  1235     {
       
  1236         QList<FtpCommand> cmds;
       
  1237         cmds << connectToHost01;
       
  1238         cmds << login01;
       
  1239         cmds << close01;
       
  1240         cmds << login01;
       
  1241         QTest::newRow( "error04" ) << cmds << 0;
       
  1242     }
       
  1243 }
       
  1244 
       
  1245 void tst_QFtp::commandSequence()
       
  1246 {
       
  1247     QFETCH( QList<FtpCommand>, cmds );
       
  1248 
       
  1249     ftp = newFtp();
       
  1250     QList<FtpCommand>::iterator it;
       
  1251     for ( it = cmds.begin(); it != cmds.end(); ++it ) {
       
  1252         switch ( (*it).cmd ) {
       
  1253         case QFtp::ConnectToHost:
       
  1254             {
       
  1255                 QVERIFY( (*it).args.count() == 2 );
       
  1256                 uint port;
       
  1257                 bool portOk;
       
  1258                 port = (*it).args[1].toUInt( &portOk );
       
  1259                 QVERIFY( portOk );
       
  1260                 ids << ftp->connectToHost( (*it).args[0], port );
       
  1261             }
       
  1262             break;
       
  1263         case QFtp::Login:
       
  1264             QVERIFY( (*it).args.count() == 2 );
       
  1265             ids << ftp->login( (*it).args[0], (*it).args[1] );
       
  1266             break;
       
  1267         case QFtp::Close:
       
  1268             QVERIFY( (*it).args.count() == 0 );
       
  1269             ids << ftp->close();
       
  1270             break;
       
  1271         default:
       
  1272             QFAIL( "Error in test: unexpected enum value" );
       
  1273             break;
       
  1274         }
       
  1275     }
       
  1276 
       
  1277     QTestEventLoop::instance().enterLoop( 30 );
       
  1278     delete ftp;
       
  1279     if ( QTestEventLoop::instance().timeout() )
       
  1280         QFAIL( "Network operation timed out" );
       
  1281 
       
  1282     QTEST( commandSequence_success, "success" );
       
  1283 }
       
  1284 
       
  1285 void tst_QFtp::abort_data()
       
  1286 {
       
  1287     QTest::addColumn<QString>("host");
       
  1288     QTest::addColumn<uint>("port");
       
  1289     QTest::addColumn<QString>("file");
       
  1290     QTest::addColumn<QByteArray>("uploadData");
       
  1291 
       
  1292     QTest::newRow( "get_fluke01" ) << QtNetworkSettings::serverName() << (uint)21 << QString("qtest/bigfile") << QByteArray();
       
  1293     QTest::newRow( "get_fluke02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("qtest/rfc3252") << QByteArray();
       
  1294 
       
  1295     // Qt/CE and Symbian test environment has to less memory for this test
       
  1296 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
       
  1297     QByteArray bigData( 10*1024*1024, 0 );
       
  1298     bigData.fill( 'B' );
       
  1299 
       
  1300     QTest::newRow( "put_fluke01" ) << QtNetworkSettings::serverName() << (uint)21 << QString("qtest/upload/abort_put") << bigData;
       
  1301 #endif
       
  1302 }
       
  1303 
       
  1304 void tst_QFtp::abort()
       
  1305 {
       
  1306     QFETCH( QString, host );
       
  1307     QFETCH( uint, port );
       
  1308     QFETCH( QString, file );
       
  1309     QFETCH( QByteArray, uploadData );
       
  1310 
       
  1311     QFtp::Command cmd;
       
  1312     if ( uploadData.size() == 0 )
       
  1313         cmd = QFtp::Get;
       
  1314     else
       
  1315         cmd = QFtp::Put;
       
  1316 
       
  1317     ftp = newFtp();
       
  1318     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
  1319     addCommand( QFtp::Login, ftp->login() );
       
  1320     if ( cmd == QFtp::Get )
       
  1321         addCommand( cmd, ftp->get( file ) );
       
  1322     else
       
  1323         addCommand( cmd, ftp->put( uploadData, file ) );
       
  1324     addCommand( QFtp::Close, ftp->close() );
       
  1325 
       
  1326     for(int time = 0; time <= uploadData.length() / 30000; time += 30) {
       
  1327         QTestEventLoop::instance().enterLoop( 30 );
       
  1328         if(ftp->currentCommand() == QFtp::None)
       
  1329             break;
       
  1330     }
       
  1331     delete ftp;
       
  1332     if ( QTestEventLoop::instance().timeout() )
       
  1333         QFAIL( "Network operation timed out" );
       
  1334 
       
  1335     ResMapIt it = resultMap.find( cmd );
       
  1336     QVERIFY( it != resultMap.end() );
       
  1337     // ### how to test the abort?
       
  1338     if ( it.value().success ) {
       
  1339         // The FTP server on fluke is sadly returning a success, even when
       
  1340         // the operation was aborted. So we have to use some heuristics.
       
  1341         if ( host == QtNetworkSettings::serverName() ) {
       
  1342             if ( cmd == QFtp::Get ) {
       
  1343                 QVERIFY(bytesDone <= bytesTotal);
       
  1344             } else {
       
  1345                 // put commands should always be aborted, since we use really
       
  1346                 // big data
       
  1347                 QVERIFY( bytesDone != bytesTotal );
       
  1348             }
       
  1349         } else {
       
  1350             // this could be tested by verifying that no more progress signals are emited
       
  1351             QVERIFY(bytesDone <= bytesTotal);
       
  1352         }
       
  1353     } else {
       
  1354         QVERIFY( bytesDone != bytesTotal );
       
  1355     }
       
  1356 
       
  1357     if ( cmd == QFtp::Put ) {
       
  1358         //////////////////////////////////////
       
  1359         // cleanup (i.e. remove the file)
       
  1360         init();
       
  1361         ftp = newFtp();
       
  1362         addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
  1363         addCommand( QFtp::Login, ftp->login() );
       
  1364         addCommand( QFtp::Remove, ftp->remove( file ) );
       
  1365         addCommand( QFtp::Close, ftp->close() );
       
  1366 
       
  1367         QTestEventLoop::instance().enterLoop( 30 );
       
  1368         delete ftp;
       
  1369         if ( QTestEventLoop::instance().timeout() )
       
  1370             QFAIL( "Network operation timed out" );
       
  1371 
       
  1372         it = resultMap.find( QFtp::Remove );
       
  1373         QVERIFY( it != resultMap.end() );
       
  1374         QVERIFY( it.value().success == 1 );
       
  1375     }
       
  1376 }
       
  1377 
       
  1378 void tst_QFtp::bytesAvailable_data()
       
  1379 {
       
  1380     QTest::addColumn<QString>("host");
       
  1381     QTest::addColumn<QString>("file");
       
  1382     QTest::addColumn<int>("type");
       
  1383     QTest::addColumn<qlonglong>("bytesAvailFinishedGet");
       
  1384     QTest::addColumn<qlonglong>("bytesAvailFinished");
       
  1385     QTest::addColumn<qlonglong>("bytesAvailDone");
       
  1386 
       
  1387     QTest::newRow( "fluke01" ) << QtNetworkSettings::serverName() << QString("qtest/bigfile") << 0 << (qlonglong)519240 << (qlonglong)519240 << (qlonglong)519240;
       
  1388     QTest::newRow( "fluke02" ) << QtNetworkSettings::serverName() << QString("qtest/rfc3252") << 0 << (qlonglong)25962 << (qlonglong)25962 << (qlonglong)25962;
       
  1389 
       
  1390     QTest::newRow( "fluke03" ) << QtNetworkSettings::serverName() << QString("qtest/bigfile") << 1 << (qlonglong)519240 << (qlonglong)0 << (qlonglong)0;
       
  1391     QTest::newRow( "fluke04" ) << QtNetworkSettings::serverName() << QString("qtest/rfc3252") << 1 << (qlonglong)25962 << (qlonglong)0 << (qlonglong)0;
       
  1392 }
       
  1393 
       
  1394 void tst_QFtp::bytesAvailable()
       
  1395 {
       
  1396     QFETCH( QString, host );
       
  1397     QFETCH( QString, file );
       
  1398     QFETCH( int, type );
       
  1399 
       
  1400     ftp = newFtp();
       
  1401     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host ) );
       
  1402     addCommand( QFtp::Login, ftp->login() );
       
  1403     addCommand( QFtp::Get, ftp->get( file ) );
       
  1404     if ( type != 0 )
       
  1405         addCommand( QFtp::Close, ftp->close() );
       
  1406 
       
  1407     QTestEventLoop::instance().enterLoop( 30 );
       
  1408     if ( QTestEventLoop::instance().timeout() )
       
  1409         QFAIL( "Network operation timed out" );
       
  1410 
       
  1411     ResMapIt it = resultMap.find( QFtp::Get );
       
  1412     QVERIFY( it != resultMap.end() );
       
  1413     QVERIFY( it.value().success );
       
  1414 
       
  1415     QFETCH(qlonglong, bytesAvailFinishedGet);
       
  1416     QCOMPARE(bytesAvailable_finishedGet, bytesAvailFinishedGet);
       
  1417 
       
  1418     QFETCH(qlonglong, bytesAvailFinished);
       
  1419     QCOMPARE(bytesAvailable_finished, bytesAvailFinished);
       
  1420 
       
  1421     QFETCH(qlonglong, bytesAvailDone);
       
  1422     QCOMPARE(bytesAvailable_done, bytesAvailDone);
       
  1423 
       
  1424     ftp->readAll();
       
  1425     QVERIFY( ftp->bytesAvailable() == 0 );
       
  1426     delete ftp;
       
  1427 }
       
  1428 
       
  1429 void tst_QFtp::activeMode()
       
  1430 {
       
  1431     QFile file("tst_QFtp_activeMode_inittab");
       
  1432     file.open(QIODevice::ReadWrite);
       
  1433     QFtp ftp;
       
  1434     ftp.setTransferMode(QFtp::Active);
       
  1435     ftp.connectToHost(QtNetworkSettings::serverName(), 21);
       
  1436     ftp.login();
       
  1437     ftp.list();
       
  1438     ftp.get("/qtest/rfc3252.txt", &file);
       
  1439     connect(&ftp, SIGNAL(done(bool)), SLOT(activeModeDone(bool)));
       
  1440     QTestEventLoop::instance().enterLoop(900);
       
  1441     QFile::remove("tst_QFtp_activeMode_inittab");
       
  1442     QVERIFY(done_success == 1);
       
  1443 
       
  1444 }
       
  1445 
       
  1446 void tst_QFtp::activeModeDone(bool error)
       
  1447 {
       
  1448     done_success = error ? -1 : 1;
       
  1449     QTestEventLoop::instance().exitLoop();
       
  1450 }
       
  1451 
       
  1452 void tst_QFtp::proxy_data()
       
  1453 {
       
  1454     QTest::addColumn<QString>("host");
       
  1455     QTest::addColumn<uint>("port");
       
  1456     QTest::addColumn<QString>("user");
       
  1457     QTest::addColumn<QString>("password");
       
  1458     QTest::addColumn<QString>("dir");
       
  1459     QTest::addColumn<int>("success");
       
  1460     QTest::addColumn<QStringList>("entryNames"); // ### we should rather use a QList<QUrlInfo> here
       
  1461 
       
  1462     QStringList flukeRoot;
       
  1463     flukeRoot << "qtest";
       
  1464     QStringList flukeQtest;
       
  1465     flukeQtest << "bigfile";
       
  1466     flukeQtest << "nonASCII";
       
  1467     flukeQtest << "rfc3252";
       
  1468     flukeQtest << "rfc3252.txt";
       
  1469     flukeQtest << "upload";
       
  1470 
       
  1471     QTest::newRow( "proxy_relPath01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("qtest") << 1 << flukeQtest;
       
  1472     QTest::newRow( "proxy_relPath02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")     << QString("qtest") << 1 << flukeQtest;
       
  1473 
       
  1474     QTest::newRow( "proxy_absPath01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("/qtest") << 1 << flukeQtest;
       
  1475     QTest::newRow( "proxy_absPath02" ) << QtNetworkSettings::serverName() << (uint)21 << QString("ftptest")     << QString("password")     << QString("/var/ftp/qtest") << 1 << flukeQtest;
       
  1476 
       
  1477     QTest::newRow( "proxy_nonExist01" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("foo")  << 0 << QStringList();
       
  1478     QTest::newRow( "proxy_nonExist03" ) << QtNetworkSettings::serverName() << (uint)21 << QString() << QString() << QString("/foo") << 0 << QStringList();
       
  1479 }
       
  1480 
       
  1481 void tst_QFtp::proxy()
       
  1482 {
       
  1483     QFETCH( QString, host );
       
  1484     QFETCH( uint, port );
       
  1485     QFETCH( QString, user );
       
  1486     QFETCH( QString, password );
       
  1487     QFETCH( QString, dir );
       
  1488 
       
  1489     ftp = newFtp();
       
  1490     addCommand( QFtp::SetProxy, ftp->setProxy( QtNetworkSettings::serverName(), 2121 ) );
       
  1491     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
  1492     addCommand( QFtp::Login, ftp->login( user, password ) );
       
  1493     addCommand( QFtp::Cd, ftp->cd( dir ) );
       
  1494     addCommand( QFtp::List, ftp->list() );
       
  1495 
       
  1496     QTestEventLoop::instance().enterLoop( 30 );
       
  1497 
       
  1498     delete ftp;
       
  1499     if ( QTestEventLoop::instance().timeout() ) {
       
  1500         QFAIL( "Network operation timed out" );
       
  1501     }
       
  1502 
       
  1503     ResMapIt it = resultMap.find( QFtp::Cd );
       
  1504     QVERIFY( it != resultMap.end() );
       
  1505     QFETCH( int, success );
       
  1506     QCOMPARE( it.value().success, success );
       
  1507     QFETCH( QStringList, entryNames );
       
  1508     QCOMPARE( listInfo_i.count(), entryNames.count() );
       
  1509     for ( uint i=0; i < (uint) entryNames.count(); i++ ) {
       
  1510         QCOMPARE( listInfo_i[i].name(), entryNames[i] );
       
  1511     }
       
  1512 }
       
  1513 
       
  1514 
       
  1515 void tst_QFtp::binaryAscii()
       
  1516 {
       
  1517     QString file = "asciifile%1.txt";
       
  1518 
       
  1519     if(file.contains('%'))
       
  1520         file = file.arg(uniqueExtension);
       
  1521 
       
  1522     QByteArray putData = "a line of text\r\n";
       
  1523 
       
  1524     init();
       
  1525     ftp = newFtp();
       
  1526     addCommand(QFtp::ConnectToHost, ftp->connectToHost(QtNetworkSettings::serverName(), 21));
       
  1527     addCommand(QFtp::Login, ftp->login("ftptest", "password"));
       
  1528     addCommand(QFtp::Cd, ftp->cd("qtest/upload"));
       
  1529     addCommand(QFtp::Put, ftp->put(putData, file, QFtp::Ascii));
       
  1530     addCommand(QFtp::Close, ftp->close());
       
  1531 
       
  1532     QTestEventLoop::instance().enterLoop( 30 );
       
  1533     if ( QTestEventLoop::instance().timeout() )
       
  1534         QFAIL( "Network operation timed out" );
       
  1535 
       
  1536     ResMapIt it = resultMap.find(QFtp::Put);
       
  1537     QVERIFY(it != resultMap.end());
       
  1538     QVERIFY(it.value().success);
       
  1539 
       
  1540     QByteArray getData;
       
  1541     QBuffer getBuf(&getData);
       
  1542     getBuf.open(QBuffer::WriteOnly);
       
  1543 
       
  1544     init();
       
  1545     ftp = newFtp();
       
  1546     addCommand(QFtp::ConnectToHost, ftp->connectToHost(QtNetworkSettings::serverName(), 21));
       
  1547     addCommand(QFtp::Login, ftp->login("ftptest", "password"));
       
  1548     addCommand(QFtp::Cd, ftp->cd("qtest/upload"));
       
  1549     addCommand(QFtp::Get, ftp->get(file, &getBuf, QFtp::Binary));
       
  1550     addCommand(QFtp::Close, ftp->close());
       
  1551 
       
  1552     QTestEventLoop::instance().enterLoop( 30 );
       
  1553     if ( QTestEventLoop::instance().timeout() )
       
  1554         QFAIL( "Network operation timed out" );
       
  1555 
       
  1556     ResMapIt it2 = resultMap.find(QFtp::Get);
       
  1557     QVERIFY(it2 != resultMap.end());
       
  1558     QVERIFY(it2.value().success);
       
  1559     // most modern ftp servers leave the file as it is by default
       
  1560     // (and do not remove the windows line ending), the -1 below could be
       
  1561     // deleted in the future
       
  1562     QVERIFY(getData.size() == putData.size()-1);
       
  1563     //////////////////////////////////////////////////////////////////
       
  1564     // cleanup (i.e. remove the file) -- this also tests the remove command
       
  1565     init();
       
  1566     ftp = newFtp();
       
  1567     addCommand(QFtp::ConnectToHost, ftp->connectToHost(QtNetworkSettings::serverName(), 21));
       
  1568     addCommand(QFtp::Login, ftp->login("ftptest", "password"));
       
  1569     addCommand(QFtp::Cd, ftp->cd("qtest/upload"));
       
  1570     addCommand(QFtp::Remove, ftp->remove(file));
       
  1571     addCommand(QFtp::Close, ftp->close());
       
  1572 
       
  1573     QTestEventLoop::instance().enterLoop( 30 );
       
  1574     delete ftp;
       
  1575     if ( QTestEventLoop::instance().timeout() )
       
  1576         QFAIL( "Network operation timed out" );
       
  1577 
       
  1578     it = resultMap.find( QFtp::Remove );
       
  1579     QVERIFY( it != resultMap.end() );
       
  1580     QCOMPARE( it.value().success, 1 );
       
  1581 
       
  1582     QVERIFY(!fileExists(QtNetworkSettings::serverName(), 21, "ftptest", "password", file));
       
  1583 }
       
  1584 
       
  1585 
       
  1586 // test QFtp::currentId() and QFtp::currentCommand()
       
  1587 #define CURRENTCOMMAND_TEST \
       
  1588 { \
       
  1589   ResMapIt it; \
       
  1590   for ( it = resultMap.begin(); it != resultMap.end(); ++it ) { \
       
  1591                                                                 if ( it.value().id == ftp->currentId() ) { \
       
  1592                                                                                                            QVERIFY( it.key() == ftp->currentCommand() ); \
       
  1593                                                                                                        } \
       
  1594 } \
       
  1595 }
       
  1596 
       
  1597 void tst_QFtp::commandStarted( int id )
       
  1598 {
       
  1599 #if defined( DUMP_SIGNALS )
       
  1600     qDebug( "%d:commandStarted( %d )", ftp->currentId(), id );
       
  1601 #endif
       
  1602     // make sure that the commandStarted and commandFinished are nested correctly
       
  1603     QVERIFY( current_id == 0 );
       
  1604     current_id = id;
       
  1605 
       
  1606     QVERIFY( !ids.isEmpty() );
       
  1607     QVERIFY( ids.first() == id );
       
  1608     if ( ids.count() > 1 ) {
       
  1609         QVERIFY( ftp->hasPendingCommands() );
       
  1610     } else {
       
  1611         QVERIFY( !ftp->hasPendingCommands() );
       
  1612     }
       
  1613 
       
  1614     QVERIFY( ftp->currentId() == id );
       
  1615     QVERIFY( cur_state == ftp->state() );
       
  1616     CURRENTCOMMAND_TEST;
       
  1617 
       
  1618     QVERIFY( ftp->error() == QFtp::NoError );
       
  1619 }
       
  1620 
       
  1621 void tst_QFtp::commandFinished( int id, bool error )
       
  1622 {
       
  1623 #if defined( DUMP_SIGNALS )
       
  1624     qDebug( "%d:commandFinished( %d, %d ) -- errorString: '%s'",
       
  1625             ftp->currentId(), id, (int)error, ftp->errorString().toLatin1().constData() );
       
  1626 #endif
       
  1627     if ( ftp->currentCommand() == QFtp::Get ) {
       
  1628         bytesAvailable_finishedGet = ftp->bytesAvailable();
       
  1629     }
       
  1630     bytesAvailable_finished = ftp->bytesAvailable();
       
  1631 
       
  1632     // make sure that the commandStarted and commandFinished are nested correctly
       
  1633     QVERIFY( current_id == id );
       
  1634     current_id = 0;
       
  1635 
       
  1636     QVERIFY( !ids.isEmpty() );
       
  1637     QVERIFY( ids.first() == id );
       
  1638     if ( !error && ids.count() > 1) {
       
  1639         QVERIFY( ftp->hasPendingCommands() );
       
  1640     } else {
       
  1641         QVERIFY( !ftp->hasPendingCommands() );
       
  1642     }
       
  1643     if ( error ) {
       
  1644         QVERIFY( ftp->error() != QFtp::NoError );
       
  1645         ids.clear();
       
  1646     } else {
       
  1647         QVERIFY( ftp->error() == QFtp::NoError );
       
  1648         ids.pop_front();
       
  1649     }
       
  1650 
       
  1651     QVERIFY( ftp->currentId() == id );
       
  1652     QVERIFY( cur_state == ftp->state() );
       
  1653     CURRENTCOMMAND_TEST;
       
  1654 
       
  1655     if ( QTest::currentTestFunction() != QLatin1String("commandSequence") ) {
       
  1656         ResMapIt it = resultMap.find( ftp->currentCommand() );
       
  1657         QVERIFY( it != resultMap.end() );
       
  1658         QVERIFY( it.value().success == -1 );
       
  1659         if ( error )
       
  1660             it.value().success = 0;
       
  1661         else
       
  1662             it.value().success = 1;
       
  1663     }
       
  1664 }
       
  1665 
       
  1666 void tst_QFtp::done( bool error )
       
  1667 {
       
  1668 #if defined( DUMP_SIGNALS )
       
  1669     qDebug( "%d:done( %d )", ftp->currentId(), (int)error );
       
  1670 #endif
       
  1671     bytesAvailable_done = ftp->bytesAvailable();
       
  1672 
       
  1673     QVERIFY( ftp->currentId() == 0 );
       
  1674     QVERIFY( current_id == 0 );
       
  1675     QVERIFY( ids.isEmpty() );
       
  1676     QVERIFY( cur_state == ftp->state() );
       
  1677     QVERIFY( !ftp->hasPendingCommands() );
       
  1678 
       
  1679     if ( QTest::currentTestFunction() == QLatin1String("commandSequence") ) {
       
  1680         QVERIFY( commandSequence_success == -1 );
       
  1681         if ( error )
       
  1682             commandSequence_success = 0;
       
  1683         else
       
  1684             commandSequence_success = 1;
       
  1685     }
       
  1686     QVERIFY( done_success == -1 );
       
  1687     if ( error ) {
       
  1688         QVERIFY( ftp->error() != QFtp::NoError );
       
  1689         done_success = 0;
       
  1690     } else {
       
  1691         QVERIFY( ftp->error() == QFtp::NoError );
       
  1692         done_success = 1;
       
  1693     }
       
  1694     QTestEventLoop::instance().exitLoop();
       
  1695 }
       
  1696 
       
  1697 void tst_QFtp::stateChanged( int state )
       
  1698 {
       
  1699 #if defined( DUMP_SIGNALS )
       
  1700     qDebug( "%d:  stateChanged( %d )", ftp->currentId(), state );
       
  1701 #endif
       
  1702     QCOMPARE( ftp->currentId(), current_id );
       
  1703     CURRENTCOMMAND_TEST;
       
  1704 
       
  1705     QVERIFY( state != cur_state );
       
  1706     QCOMPARE( state, (int)ftp->state() );
       
  1707     if ( state != QFtp::Unconnected ) {
       
  1708         // make sure that the states are always emitted in the right order (for
       
  1709         // this, we assume an ordering on the enum values, which they have at
       
  1710         // the moment)
       
  1711         QVERIFY( cur_state < state );
       
  1712 
       
  1713         // make sure that state changes are only emitted in response to certain
       
  1714         // commands
       
  1715         switch ( state ) {
       
  1716         case QFtp::HostLookup:
       
  1717         case QFtp::Connecting:
       
  1718         case QFtp::Connected:
       
  1719             QCOMPARE( (int)ftp->currentCommand(), (int)QFtp::ConnectToHost );
       
  1720             break;
       
  1721         case QFtp::LoggedIn:
       
  1722             QCOMPARE( (int)ftp->currentCommand(), (int)QFtp::Login );
       
  1723             break;
       
  1724         case QFtp::Closing:
       
  1725             QCOMPARE( (int)ftp->currentCommand(), (int)QFtp::Close );
       
  1726             break;
       
  1727         default:
       
  1728             QWARN( QString("Unexpected state '%1'").arg(state).toLatin1().constData() );
       
  1729             break;
       
  1730         }
       
  1731     }
       
  1732     cur_state = state;
       
  1733 
       
  1734     if ( QTest::currentTestFunction() == QLatin1String("connectToHost") ) {
       
  1735         switch ( state ) {
       
  1736         case QFtp::HostLookup:
       
  1737         case QFtp::Connecting:
       
  1738         case QFtp::LoggedIn:
       
  1739         case QFtp::Closing:
       
  1740             // ignore
       
  1741             break;
       
  1742         case QFtp::Connected:
       
  1743         case QFtp::Unconnected:
       
  1744             QVERIFY( connectToHost_state == -1 );
       
  1745             connectToHost_state = state;
       
  1746             break;
       
  1747         default:
       
  1748             QWARN( QString("Unknown state '%1'").arg(state).toLatin1().constData() );
       
  1749             break;
       
  1750         }
       
  1751     } else if ( QTest::currentTestFunction() == QLatin1String("close") ) {
       
  1752         ResMapIt it = resultMap.find( QFtp::Close );
       
  1753         if ( it!=resultMap.end() && ftp->currentId()==it.value().id ) {
       
  1754             if ( state == QFtp::Closing ) {
       
  1755                 QVERIFY( close_state == -1 );
       
  1756                 close_state = state;
       
  1757             } else if ( state == QFtp::Unconnected ) {
       
  1758                 QVERIFY( close_state == QFtp::Closing );
       
  1759                 close_state = state;
       
  1760             }
       
  1761         }
       
  1762     } else if ( QTest::currentTestFunction() == QLatin1String("login") ) {
       
  1763         ResMapIt it = resultMap.find( QFtp::Login );
       
  1764         if ( it!=resultMap.end() && ftp->currentId()==it.value().id ) {
       
  1765             if ( state == QFtp::LoggedIn ) {
       
  1766                 QVERIFY( login_state == -1 );
       
  1767                 login_state = state;
       
  1768             }
       
  1769         }
       
  1770     }
       
  1771 }
       
  1772 
       
  1773 void tst_QFtp::listInfo( const QUrlInfo &i )
       
  1774 {
       
  1775 #if defined( DUMP_SIGNALS )
       
  1776     qDebug( "%d:  listInfo( %s )", ftp->currentId(), i.name().toLatin1().constData() );
       
  1777 #endif
       
  1778     QCOMPARE( ftp->currentId(), current_id );
       
  1779     if ( ids.count() > 1 ) {
       
  1780         QVERIFY( ftp->hasPendingCommands() );
       
  1781     } else {
       
  1782         QVERIFY( !ftp->hasPendingCommands() );
       
  1783     }
       
  1784     QVERIFY( cur_state == ftp->state() );
       
  1785     CURRENTCOMMAND_TEST;
       
  1786 
       
  1787     if ( QTest::currentTestFunction()==QLatin1String("list") || QTest::currentTestFunction()==QLatin1String("cd") || QTest::currentTestFunction()==QLatin1String("proxy") || inFileDirExistsFunction ) {
       
  1788         ResMapIt it = resultMap.find( QFtp::List );
       
  1789         QVERIFY( it != resultMap.end() );
       
  1790         QVERIFY( ftp->currentId() == it.value().id );
       
  1791         listInfo_i << i;
       
  1792     }
       
  1793 }
       
  1794 
       
  1795 void tst_QFtp::readyRead()
       
  1796 {
       
  1797 #if defined( DUMP_SIGNALS )
       
  1798     qDebug( "%d:  readyRead(), bytesAvailable == %lu", ftp->currentId(), ftp->bytesAvailable() );
       
  1799 #endif
       
  1800     QCOMPARE( ftp->currentId(), current_id );
       
  1801     if ( ids.count() > 1 ) {
       
  1802         QVERIFY( ftp->hasPendingCommands() );
       
  1803     } else {
       
  1804         QVERIFY( !ftp->hasPendingCommands() );
       
  1805     }
       
  1806     QVERIFY( cur_state == ftp->state() );
       
  1807     CURRENTCOMMAND_TEST;
       
  1808 
       
  1809     if ( QTest::currentTestFunction() != QLatin1String("bytesAvailable") ) {
       
  1810         int oldSize = newData_ba.size();
       
  1811         qlonglong bytesAvail = ftp->bytesAvailable();
       
  1812         QByteArray ba = ftp->readAll();
       
  1813         QVERIFY( ba.size() == (int) bytesAvail );
       
  1814         newData_ba.resize( oldSize + ba.size() );
       
  1815         memcpy( newData_ba.data()+oldSize, ba.data(), ba.size() );
       
  1816 
       
  1817         if ( bytesTotal != -1 ) {
       
  1818             QVERIFY( (int)newData_ba.size() <= bytesTotal );
       
  1819         }
       
  1820         QVERIFY( (int)newData_ba.size() == bytesDone );
       
  1821     }
       
  1822 }
       
  1823 
       
  1824 void tst_QFtp::dataTransferProgress( qint64 done, qint64 total )
       
  1825 {
       
  1826 #if defined( DUMP_SIGNALS )
       
  1827     qDebug( "%d:  dataTransferProgress( %lli, %lli )", ftp->currentId(), done, total );
       
  1828 #endif
       
  1829     QCOMPARE( ftp->currentId(), current_id );
       
  1830     if ( ids.count() > 1 ) {
       
  1831         QVERIFY( ftp->hasPendingCommands() );
       
  1832     } else {
       
  1833         QVERIFY( !ftp->hasPendingCommands() );
       
  1834     }
       
  1835     QVERIFY( cur_state == ftp->state() );
       
  1836     CURRENTCOMMAND_TEST;
       
  1837 
       
  1838     if ( bytesTotal == bytesTotal_init ) {
       
  1839         bytesTotal = total;
       
  1840     } else {
       
  1841         QVERIFY( bytesTotal == total );
       
  1842     }
       
  1843 
       
  1844     QVERIFY( bytesTotal != bytesTotal_init );
       
  1845     QVERIFY( bytesDone <= done );
       
  1846     bytesDone = done;
       
  1847     if ( bytesTotal != -1 ) {
       
  1848         QVERIFY( bytesDone <= bytesTotal );
       
  1849     }
       
  1850 
       
  1851     if ( QTest::currentTestFunction() == QLatin1String("abort") ) {
       
  1852         // ### it would be nice if we could specify in our testdata when to do
       
  1853         // the abort
       
  1854         if ( done >= total/100000 ) {
       
  1855             if ( ids.count() != 1 ) {
       
  1856                 // do abort only once
       
  1857                 int tmpId = ids.first();
       
  1858                 ids.clear();
       
  1859                 ids << tmpId;
       
  1860                 ftp->abort();
       
  1861             }
       
  1862         }
       
  1863     }
       
  1864 }
       
  1865 
       
  1866 
       
  1867 QFtp *tst_QFtp::newFtp()
       
  1868 {
       
  1869     QFtp *nFtp = new QFtp( this );
       
  1870     connect( nFtp, SIGNAL(commandStarted(int)),
       
  1871              SLOT(commandStarted(int)) );
       
  1872     connect( nFtp, SIGNAL(commandFinished(int,bool)),
       
  1873              SLOT(commandFinished(int,bool)) );
       
  1874     connect( nFtp, SIGNAL(done(bool)),
       
  1875              SLOT(done(bool)) );
       
  1876     connect( nFtp, SIGNAL(stateChanged(int)),
       
  1877              SLOT(stateChanged(int)) );
       
  1878     connect( nFtp, SIGNAL(listInfo(const QUrlInfo&)),
       
  1879              SLOT(listInfo(const QUrlInfo&)) );
       
  1880     connect( nFtp, SIGNAL(readyRead()),
       
  1881              SLOT(readyRead()) );
       
  1882     connect( nFtp, SIGNAL(dataTransferProgress(qint64, qint64)),
       
  1883              SLOT(dataTransferProgress(qint64, qint64)) );
       
  1884 
       
  1885     return nFtp;
       
  1886 }
       
  1887 
       
  1888 void tst_QFtp::addCommand( QFtp::Command cmd, int id )
       
  1889 {
       
  1890     ids << id;
       
  1891     CommandResult res;
       
  1892     res.id = id;
       
  1893     res.success = -1;
       
  1894     resultMap[ cmd ] = res;
       
  1895 }
       
  1896 
       
  1897 bool tst_QFtp::fileExists( const QString &host, quint16 port, const QString &user, const QString &password, const QString &file, const QString &cdDir )
       
  1898 {
       
  1899     init();
       
  1900     ftp = newFtp();
       
  1901     // ### make these tests work
       
  1902     if (ftp->currentId() != 0) {
       
  1903         qWarning("ftp->currentId() != 0");
       
  1904         return FALSE;
       
  1905     }
       
  1906 
       
  1907     if (ftp->state() != QFtp::Unconnected) {
       
  1908         qWarning("ftp->state() != QFtp::Unconnected");
       
  1909         return FALSE;
       
  1910     }
       
  1911 
       
  1912     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
  1913     addCommand( QFtp::Login, ftp->login( user, password ) );
       
  1914     if ( !cdDir.isNull() )
       
  1915         addCommand( QFtp::Cd, ftp->cd( cdDir ) );
       
  1916     addCommand( QFtp::List, ftp->list( file ) );
       
  1917     addCommand( QFtp::Close, ftp->close() );
       
  1918 
       
  1919     inFileDirExistsFunction = TRUE;
       
  1920     QTestEventLoop::instance().enterLoop( 30 );
       
  1921     delete ftp;
       
  1922     if ( QTestEventLoop::instance().timeout() ) {
       
  1923         // ### make this test work
       
  1924         qWarning("Network operation timed out");
       
  1925         return FALSE;
       
  1926     }
       
  1927     inFileDirExistsFunction = FALSE;
       
  1928 
       
  1929     ResMapIt it = resultMap.find( QFtp::ConnectToHost );
       
  1930     // ### make these tests work
       
  1931     if (it == resultMap.end()) {
       
  1932         qWarning("it != resultMap.end()");
       
  1933         return FALSE;
       
  1934     }
       
  1935 
       
  1936     if (it.value().success == -1) {
       
  1937         qWarning("it.value().success != -1");
       
  1938         return FALSE;
       
  1939     }
       
  1940 
       
  1941     if ( it.value().success == 1 ) {
       
  1942         for ( uint i=0; i < (uint) listInfo_i.count(); i++ ) {
       
  1943             if ( QFileInfo(listInfo_i[i].name()).fileName() == QFileInfo(file).fileName() )
       
  1944                 return TRUE;
       
  1945         }
       
  1946     }
       
  1947 
       
  1948     //this is not a good warning considering sometime this function is used to test that a file does not exist
       
  1949     //qWarning("file doesn't exist");
       
  1950     return FALSE;
       
  1951 }
       
  1952 
       
  1953 bool tst_QFtp::dirExists( const QString &host, quint16 port, const QString &user, const QString &password, const QString &cdDir, const QString &dirToCreate )
       
  1954 {
       
  1955     init();
       
  1956     ftp = newFtp();
       
  1957     // ### make these tests work
       
  1958     //    QCOMPARE( ftp->currentId(), 0 );
       
  1959     //    QCOMPARE( (int)ftp->state(), (int)QFtp::Unconnected );
       
  1960 
       
  1961     addCommand( QFtp::ConnectToHost, ftp->connectToHost( host, port ) );
       
  1962     addCommand( QFtp::Login, ftp->login( user, password ) );
       
  1963     if ( dirToCreate.startsWith( "/" ) )
       
  1964         addCommand( QFtp::Cd, ftp->cd( dirToCreate ) );
       
  1965     else
       
  1966         addCommand( QFtp::Cd, ftp->cd( cdDir + "/" + dirToCreate ) );
       
  1967     addCommand( QFtp::Close, ftp->close() );
       
  1968 
       
  1969     inFileDirExistsFunction = TRUE;
       
  1970     QTestEventLoop::instance().enterLoop( 30 );
       
  1971     delete ftp;
       
  1972     if ( QTestEventLoop::instance().timeout() ) {
       
  1973         // ### make this test work
       
  1974         // QFAIL( "Network operation timed out" );
       
  1975         return FALSE;
       
  1976     }
       
  1977     inFileDirExistsFunction = FALSE;
       
  1978 
       
  1979     ResMapIt it = resultMap.find( QFtp::Cd );
       
  1980     // ### make these tests work
       
  1981     //    QVERIFY( it != resultMap.end() );
       
  1982     //    QVERIFY( it.value().success != -1 );
       
  1983     return it.value().success == 1;
       
  1984 }
       
  1985 
       
  1986 void tst_QFtp::doneSignal()
       
  1987 {
       
  1988     QFtp ftp;
       
  1989     QSignalSpy spy(&ftp, SIGNAL(done(bool)));
       
  1990 
       
  1991     ftp.connectToHost(QtNetworkSettings::serverName());
       
  1992     ftp.login("anonymous");
       
  1993     ftp.list();
       
  1994     ftp.close();
       
  1995 
       
  1996     done_success = 0;
       
  1997     while ( ftp.hasPendingCommands() )
       
  1998         QCoreApplication::instance()->processEvents();
       
  1999     QTest::qWait(200);
       
  2000 
       
  2001     QCOMPARE(spy.count(), 1);
       
  2002     QCOMPARE(spy.first().first().toBool(), false);
       
  2003 }
       
  2004 
       
  2005 void tst_QFtp::queueMoreCommandsInDoneSlot()
       
  2006 {
       
  2007     QSKIP("Task 127050 && 113966", SkipSingle);
       
  2008 
       
  2009     QFtp ftp;
       
  2010     QSignalSpy doneSpy(&ftp, SIGNAL(done(bool)));
       
  2011     QSignalSpy commandFinishedSpy(&ftp, SIGNAL(commandFinished(int, bool)));
       
  2012 
       
  2013     this->ftp = &ftp;
       
  2014     connect(&ftp, SIGNAL(done(bool)), this, SLOT(cdUpSlot(bool)));
       
  2015 
       
  2016     ftp.connectToHost("ftp.qt.nokia.com");
       
  2017     ftp.login();
       
  2018     ftp.cd("qt");
       
  2019     ftp.rmdir("qtest-removedir-noexist");
       
  2020 
       
  2021     while ( ftp.hasPendingCommands() || ftp.currentCommand() != QFtp::None ) {
       
  2022         QCoreApplication::instance()->processEvents(QEventLoop::AllEvents
       
  2023                                                     | QEventLoop::WaitForMoreEvents);
       
  2024     }
       
  2025 
       
  2026     QCOMPARE(doneSpy.count(), 2);
       
  2027     QCOMPARE(doneSpy.first().first().toBool(), true);
       
  2028     QCOMPARE(doneSpy.last().first().toBool(), false);
       
  2029 
       
  2030     QCOMPARE(commandFinishedSpy.count(), 6);
       
  2031     int firstId = commandFinishedSpy.at(0).at(0).toInt();
       
  2032     QCOMPARE(commandFinishedSpy.at(0).at(1).toBool(), false);
       
  2033     QCOMPARE(commandFinishedSpy.at(1).at(0).toInt(), firstId + 1);
       
  2034     QCOMPARE(commandFinishedSpy.at(1).at(1).toBool(), false);
       
  2035     QCOMPARE(commandFinishedSpy.at(2).at(0).toInt(), firstId + 2);
       
  2036     QCOMPARE(commandFinishedSpy.at(2).at(1).toBool(), false);
       
  2037     QCOMPARE(commandFinishedSpy.at(3).at(0).toInt(), firstId + 3);
       
  2038     QCOMPARE(commandFinishedSpy.at(3).at(1).toBool(), true);
       
  2039     QCOMPARE(commandFinishedSpy.at(4).at(0).toInt(), firstId + 4);
       
  2040     QCOMPARE(commandFinishedSpy.at(4).at(1).toBool(), false);
       
  2041     QCOMPARE(commandFinishedSpy.at(5).at(0).toInt(), firstId + 5);
       
  2042     QCOMPARE(commandFinishedSpy.at(5).at(1).toBool(), false);
       
  2043 
       
  2044     this->ftp = 0;
       
  2045 }
       
  2046 
       
  2047 void tst_QFtp::cdUpSlot(bool error)
       
  2048 {
       
  2049     if (error) {
       
  2050         ftp->cd("..");
       
  2051         ftp->cd("qt");
       
  2052     }
       
  2053 }
       
  2054 
       
  2055 QTEST_MAIN(tst_QFtp)
       
  2056 
       
  2057 #include "tst_qftp.moc"