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