tests/auto/q3process/tst_q3process.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #include <q3process.h>
       
    46 #include <qregexp.h>
       
    47 #include <qdebug.h>
       
    48 
       
    49 QT_FORWARD_DECLARE_CLASS(Q3Process)
       
    50 
       
    51 //TESTED_CLASS=
       
    52 //TESTED_FILES=
       
    53 
       
    54 class tst_Q3Process : public QObject
       
    55 {
       
    56     Q_OBJECT
       
    57 
       
    58 public:
       
    59     tst_Q3Process();
       
    60     virtual ~tst_Q3Process();
       
    61 
       
    62 
       
    63 public slots:
       
    64     void init();
       
    65     void cleanup();
       
    66 private slots:
       
    67     void readLineStdout_data();
       
    68     void readLineStdout();
       
    69     void readLineStderr_data();
       
    70     void readLineStderr();
       
    71     void communication_data();
       
    72     void communication();
       
    73 
       
    74     void canReadLineStdout_data();
       
    75     void canReadLineStdout();
       
    76     void canReadLineStderr_data();
       
    77     void canReadLineStderr();
       
    78     void startWithNoEnvironment();
       
    79     void startWithEmptyStringArgument();
       
    80     
       
    81 protected slots:
       
    82     void processExited();
       
    83     void exitLoopSlot();
       
    84 
       
    85 private:
       
    86     Q3Process *proc;
       
    87     QStringList linesReadStdout;
       
    88     QStringList linesReadStderr;
       
    89 };
       
    90 
       
    91 tst_Q3Process::tst_Q3Process()
       
    92     : proc(0)
       
    93 {
       
    94 }
       
    95 
       
    96 tst_Q3Process::~tst_Q3Process()
       
    97 {
       
    98 }
       
    99 
       
   100 void tst_Q3Process::init()
       
   101 {
       
   102     linesReadStdout.clear();
       
   103     linesReadStderr.clear();
       
   104 }
       
   105 
       
   106 void tst_Q3Process::cleanup()
       
   107 {
       
   108     if ( proc ) {
       
   109 	proc->kill();
       
   110 	delete proc;
       
   111 	proc = 0;
       
   112     }
       
   113 }
       
   114 
       
   115 void tst_Q3Process::readLineStdout_data()
       
   116 {
       
   117     QTest::addColumn<QString>("input");
       
   118     QTest::addColumn<QStringList>("res");
       
   119 
       
   120     QStringList l;
       
   121 
       
   122     QTest::newRow( "unix_0" ) << QString("a\nbc\ndef\nghij\n")
       
   123 	<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
       
   124     l.clear();
       
   125     QTest::newRow( "unix_1" ) << QString("a\nbc\ndef\nghij")
       
   126 	<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
       
   127     l.clear();
       
   128     QTest::newRow( "unix_2" ) << QString("a\nbc\n\ndef\nghij\n")
       
   129 	<< (QStringList)( l << "a" << "bc" << "" << "def" << "ghij" );
       
   130     l.clear();
       
   131 
       
   132     QTest::newRow( "windows_0" ) << QString("a\r\nbc\r\ndef\r\nghij\r\n")
       
   133 	<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
       
   134     l.clear();
       
   135     QTest::newRow( "windows_1" ) << QString("a\r\nbc\r\ndef\r\nghij")
       
   136 	<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
       
   137     l.clear();
       
   138     QTest::newRow( "windows_2" ) << QString("a\r\nbc\r\n\r\ndef\r\nghij\r\n")
       
   139 	<< (QStringList)( l << "a" << "bc" << "" << "def" << "ghij" );
       
   140     l.clear();
       
   141 
       
   142     QTest::newRow( "mixed_0" ) << QString("a\r\nbc\ndef\r\nghij\n")
       
   143 	<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
       
   144     l.clear();
       
   145     QTest::newRow( "mixed_1" ) << QString("a\nbc\r\ndef\nghij\r\n")
       
   146 	<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
       
   147     l.clear();
       
   148     QTest::newRow( "mixed_2" ) << QString("a\nbc\r\r\ndef\r\r\r\nghij\r\r\r\r\n")
       
   149 	<< (QStringList)( l << "a" << "bc\r" << "def\r\r" << "ghij\r\r\r" );
       
   150     l.clear();
       
   151 }
       
   152 
       
   153 void tst_Q3Process::readLineStdout()
       
   154 {
       
   155     QFETCH( QString, input );
       
   156 
       
   157     if (proc) delete proc;
       
   158     proc = new Q3Process( QString("cat/cat") );
       
   159     connect( proc, SIGNAL(processExited()),
       
   160 	     SLOT(processExited()) );
       
   161 
       
   162     QVERIFY( proc->launch( input ) );
       
   163 
       
   164     QTestEventLoop::instance().enterLoop( 29 );
       
   165     if ( QTestEventLoop::instance().timeout() )
       
   166 	QFAIL( "Operation timed out" );
       
   167 
       
   168     QTEST( linesReadStdout, "res" );
       
   169 }
       
   170 
       
   171 void tst_Q3Process::readLineStderr_data()
       
   172 {
       
   173     readLineStdout_data();
       
   174 }
       
   175 
       
   176 void tst_Q3Process::readLineStderr()
       
   177 {
       
   178     QFETCH( QString, input );
       
   179 
       
   180     if (proc) delete proc;
       
   181     proc = new Q3Process( QString("cat/cat -stderr").split(' ') );
       
   182     connect( proc, SIGNAL(processExited()),
       
   183 	     SLOT(processExited()) );
       
   184 
       
   185     QVERIFY( proc->launch( input ) );
       
   186 
       
   187     QTestEventLoop::instance().enterLoop( 29 );
       
   188     if ( QTestEventLoop::instance().timeout() )
       
   189 	QFAIL( "Operation timed out" );
       
   190 
       
   191     QTEST( linesReadStderr, "res" );
       
   192 }
       
   193 
       
   194 void tst_Q3Process::communication_data()
       
   195 {
       
   196     QTest::addColumn<QStringList>("command");
       
   197     QTest::addColumn<int>("commFlags");
       
   198     QTest::addColumn<QString>("input");
       
   199     QTest::addColumn<QString>("resStdout");
       
   200     QTest::addColumn<QString>("resStderr");
       
   201 
       
   202     QTest::newRow( "no_dup_0" ) << QString("cat/cat").split(' ')
       
   203 	<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr )
       
   204 	<< QString("12345")
       
   205 	<< QString("12345")
       
   206 	<< QString();
       
   207     QTest::newRow( "no_dup_1" ) << QString("cat/cat -stderr").split(' ')
       
   208 	<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr )
       
   209 	<< QString("12345")
       
   210 	<< QString()
       
   211 	<< QString("12345");
       
   212     QTest::newRow( "no_dup_2" ) << QString("cat/cat -stdout_and_stderr").split(' ')
       
   213 	<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr )
       
   214 	<< QString("12345")
       
   215 	<< QString("12345")
       
   216 	<< QString("23456");
       
   217 
       
   218     QTest::newRow( "dup_0" ) << QString("cat/cat").split(' ')
       
   219 	<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr | Q3Process::DupStderr )
       
   220 	<< QString("12345")
       
   221 	<< QString("12345")
       
   222 	<< QString();
       
   223     QTest::newRow( "dup_1" ) << QString("cat/cat -stderr").split(' ')
       
   224 	<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr | Q3Process::DupStderr )
       
   225 	<< QString("12345")
       
   226 	<< QString("12345")
       
   227 	<< QString();
       
   228     QTest::newRow( "dup_2" ) << QString("cat/cat -stdout_and_stderr").split(' ')
       
   229 	<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr | Q3Process::DupStderr )
       
   230 	<< QString("12345")
       
   231 	<< QString("1223344556")
       
   232 	<< QString();
       
   233 }
       
   234 
       
   235 void tst_Q3Process::communication()
       
   236 {
       
   237     for ( int i=0; i<2; i++ ) {
       
   238 	cleanup();
       
   239 
       
   240 	QFETCH( QStringList, command );
       
   241 	QFETCH( int, commFlags );
       
   242 	QFETCH( QString, input );
       
   243 
       
   244         if (proc) delete proc;
       
   245 	proc = new Q3Process( command );
       
   246 	proc->setCommunication( commFlags );
       
   247 	connect( proc, SIGNAL(processExited()),
       
   248 		SLOT(processExited()) );
       
   249 
       
   250 	QVERIFY( proc->launch( input ) );
       
   251 
       
   252 	QTestEventLoop::instance().enterLoop( 29 );
       
   253 	if ( QTestEventLoop::instance().timeout() )
       
   254 	    QFAIL( "Operation timed out" );
       
   255 
       
   256 	if ( i == 0 ) {
       
   257 	    QTEST( QString( proc->readStdout() ), "resStdout" );
       
   258 	    QTEST( QString( proc->readStderr() ), "resStderr" );
       
   259 	} else {
       
   260 	    QTEST( QString( proc->readStdout() ), "resStdout" );
       
   261 	    QTEST( QString( proc->readStderr() ), "resStderr" );
       
   262 	}
       
   263     }
       
   264 }
       
   265 
       
   266 void tst_Q3Process::canReadLineStdout_data()
       
   267 {
       
   268     readLineStdout_data();
       
   269 }
       
   270 
       
   271 void tst_Q3Process::canReadLineStdout()
       
   272 {
       
   273     // This function tests the busy-loop abilities of the canReadLineStdout()
       
   274     // function.
       
   275     QFETCH( QString, input );
       
   276     QFETCH(QStringList, res);
       
   277 
       
   278     if (proc) delete proc;
       
   279     proc = new Q3Process( QString("cat/cat") );
       
   280     QVERIFY( proc->start() );
       
   281     proc->writeToStdin( input );
       
   282     proc->flushStdin();
       
   283     proc->closeStdin();
       
   284 
       
   285     do {
       
   286         connect(proc, SIGNAL(readyReadStdout()), this, SLOT(exitLoopSlot()));
       
   287         QTestEventLoop::instance().enterLoop(5);
       
   288         if (QTestEventLoop::instance().timeout()) {
       
   289             if (!proc->isRunning())
       
   290                 break;
       
   291             QFAIL("Timed out while waiting for my kids");
       
   292         }
       
   293 
       
   294         // q3process can (actually!) emit readyRead() when
       
   295         // canReadLineStdout() is called.
       
   296         proc->disconnect();
       
   297 
       
   298         while ( proc->canReadLineStdout() )
       
   299             linesReadStdout << proc->readLineStdout();
       
   300     } while (linesReadStdout.size() < res.size() && proc->isRunning());
       
   301 
       
   302     // q3process can (actually!) emit readyRead() when
       
   303     // canReadLineStdout() is called.
       
   304     proc->disconnect();
       
   305 
       
   306     // if the last line is not terminated with a newline, we get it only after
       
   307     // we determined that the process is not running anymore
       
   308     if ( proc->canReadLineStdout() )
       
   309         linesReadStdout << proc->readLineStdout();
       
   310 
       
   311     QCOMPARE( linesReadStdout, res );
       
   312 }
       
   313 
       
   314 void tst_Q3Process::exitLoopSlot()
       
   315 {
       
   316     QTestEventLoop::instance().exitLoop();
       
   317 }
       
   318 
       
   319 void tst_Q3Process::canReadLineStderr_data()
       
   320 {
       
   321     readLineStdout_data();
       
   322 }
       
   323 
       
   324 void tst_Q3Process::canReadLineStderr()
       
   325 {
       
   326     // This function tests the busy-loop abilities of the canReadLineStderr()
       
   327     // function.
       
   328     QFETCH( QString, input );
       
   329     QFETCH(QStringList, res);
       
   330 
       
   331     if (proc) delete proc;
       
   332     proc = new Q3Process( QString("cat/cat -stderr").split(' ') );
       
   333     QVERIFY( proc->start() );
       
   334     proc->writeToStdin( input );
       
   335     proc->flushStdin();
       
   336     proc->closeStdin();
       
   337 
       
   338     do {
       
   339         connect(proc, SIGNAL(readyReadStderr()), this, SLOT(exitLoopSlot()));
       
   340         QTestEventLoop::instance().enterLoop(5);
       
   341         if (QTestEventLoop::instance().timeout()) {
       
   342             if (!proc->isRunning())
       
   343                 break;
       
   344             QFAIL("Timed out while waiting for my kids");
       
   345         }
       
   346 
       
   347         // q3process can (actually!) emit readyRead() when
       
   348         // canReadLineStdout() is called.
       
   349         proc->disconnect();
       
   350 
       
   351         while ( proc->canReadLineStderr() )
       
   352             linesReadStderr << proc->readLineStderr();
       
   353     } while (linesReadStderr.size() < res.size() && proc->isRunning());
       
   354 
       
   355     // q3process can (actually!) emit readyRead() when
       
   356     // canReadLineStdout() is called.
       
   357     proc->disconnect();
       
   358 
       
   359     // if the last line is not terminated with a newline, we get it only after
       
   360     // we determined that the process is not running anymore
       
   361     if ( proc->canReadLineStderr() )
       
   362 	linesReadStderr << proc->readLineStderr();
       
   363 
       
   364     QCOMPARE( linesReadStderr, res );
       
   365 }
       
   366 
       
   367 void tst_Q3Process::processExited()
       
   368 {
       
   369     if ( QTest::currentTestFunction() == QLatin1String("readLineStdout") ) {
       
   370 	QVERIFY( proc != 0 );
       
   371 
       
   372         // q3process can (actually!) emit readyRead() when
       
   373         // canReadLineStdout() is called.
       
   374         proc->disconnect();
       
   375 
       
   376         while ( proc->canReadLineStdout() )
       
   377 	    linesReadStdout << proc->readLineStdout();
       
   378 
       
   379 	// if canReadLine...() returns FALSE, the readLine...() function should
       
   380 	// return QString::null
       
   381 	QVERIFY( proc->readLineStdout().isNull() );
       
   382 
       
   383 	QTestEventLoop::instance().exitLoop();
       
   384 
       
   385     } else if ( QTest::currentTestFunction() == QLatin1String("readLineStderr") ) {
       
   386 	QVERIFY( proc != 0 );
       
   387 
       
   388         // q3process can (actually!) emit readyRead() when
       
   389         // canReadLineStdout() is called.
       
   390         proc->disconnect();
       
   391 
       
   392         while ( proc->canReadLineStderr() )
       
   393 	    linesReadStderr << proc->readLineStderr();
       
   394 
       
   395 	// if canReadLine...() returns FALSE, the readLine...() function should
       
   396 	// return QString::null
       
   397 	QVERIFY( proc->readLineStderr().isNull() );
       
   398 
       
   399 	QTestEventLoop::instance().exitLoop();
       
   400     } else if ( QTest::currentTestFunction() == QLatin1String("communication") ) {
       
   401 	QTestEventLoop::instance().exitLoop();
       
   402     }
       
   403 }
       
   404 
       
   405 void tst_Q3Process::startWithNoEnvironment()
       
   406 {
       
   407     QStringList args;
       
   408     QByteArray result;
       
   409 #ifdef Q_OS_MACX
       
   410     args << "./echo/echo.app";
       
   411     result = "./echo/echo.app/Contents/MacOS/echo";
       
   412 #elif defined Q_OS_WIN
       
   413     args << "./echo/echo";
       
   414     result = "echo";
       
   415 #else
       
   416     args << "./echo/echo";
       
   417     result = args[0];
       
   418 #endif
       
   419     args << "foo";
       
   420     proc = new Q3Process(args);
       
   421     QVERIFY(proc->start(/* environment = */ 0));
       
   422     connect(proc, SIGNAL(readyReadStdout()), this, SLOT(exitLoopSlot()));
       
   423 
       
   424     QTestEventLoop::instance().enterLoop(10);
       
   425     QVERIFY(!QTestEventLoop::instance().timeout());
       
   426 
       
   427 #ifdef Q_OS_WIN
       
   428     // on different windows compilers the first arg is different, 
       
   429     // some just pass what was passed to createprocess while others 
       
   430     // expand the entire path.
       
   431     QVERIFY(proc->readStdout().contains(result));
       
   432 #else
       
   433     QCOMPARE(proc->readStdout(), result);
       
   434 #endif
       
   435 }
       
   436 
       
   437 void tst_Q3Process::startWithEmptyStringArgument()
       
   438 {
       
   439     // Test that this doesn't assert (task 122353)
       
   440     Q3Process process("cmd");
       
   441     process.addArgument(QString());
       
   442 
       
   443     QStringList env;
       
   444     process.start(&env);
       
   445 }
       
   446 
       
   447 QTEST_MAIN(tst_Q3Process)
       
   448 #include "tst_q3process.moc"