Files correlati : cg0.exe cg0700a.msk cg0700b.msk cg3.exe cg4.exe Bug : Commento: Merge 1.0 libraries
458 lines
13 KiB
C++
458 lines
13 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2015 The Qt Company Ltd.
|
|
** Contact: http://www.qt.io/licensing/
|
|
**
|
|
** This file is part of the test suite of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:LGPL$
|
|
** Commercial License Usage
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
** accordance with the commercial license agreement provided with the
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
|
** information use the contact form at http://www.qt.io/contact-us.
|
|
**
|
|
** GNU Lesser General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
** General Public License version 2.1 or version 3 as published by the Free
|
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
|
** following information to ensure the GNU Lesser General Public License
|
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
**
|
|
** As a special exception, The Qt Company gives you certain additional
|
|
** rights. These rights are described in The Qt Company LGPL Exception
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
** General Public License version 3.0 as published by the Free Software
|
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
|
** packaging of this file. Please review the following information to
|
|
** ensure the GNU General Public License version 3.0 requirements will be
|
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
|
|
#include <QtTest/QtTest>
|
|
|
|
#include <q3process.h>
|
|
#include <qregexp.h>
|
|
#include <qdir.h>
|
|
#include <qdebug.h>
|
|
|
|
QT_FORWARD_DECLARE_CLASS(Q3Process)
|
|
|
|
//TESTED_CLASS=
|
|
//TESTED_FILES=
|
|
|
|
class tst_Q3Process : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
tst_Q3Process();
|
|
|
|
public slots:
|
|
void initTestCase();
|
|
void init();
|
|
void cleanup();
|
|
private slots:
|
|
void readLineStdout_data();
|
|
void readLineStdout();
|
|
void readLineStderr_data();
|
|
void readLineStderr();
|
|
void communication_data();
|
|
void communication();
|
|
|
|
void canReadLineStdout_data();
|
|
void canReadLineStdout();
|
|
void canReadLineStderr_data();
|
|
void canReadLineStderr();
|
|
void startWithNoEnvironment();
|
|
void startWithEmptyStringArgument();
|
|
|
|
protected slots:
|
|
void processExited();
|
|
void exitLoopSlot();
|
|
|
|
private:
|
|
Q3Process *proc;
|
|
QStringList linesReadStdout;
|
|
QStringList linesReadStderr;
|
|
};
|
|
|
|
tst_Q3Process::tst_Q3Process()
|
|
: proc(0)
|
|
{
|
|
}
|
|
|
|
void tst_Q3Process::initTestCase()
|
|
{
|
|
#ifdef Q_OS_WIN
|
|
// cd up to be able to locate the binary of the sub-process.
|
|
QDir workingDirectory = QDir::current();
|
|
if (workingDirectory.absolutePath().endsWith(QLatin1String("/debug"), Qt::CaseInsensitive)
|
|
|| workingDirectory.absolutePath().endsWith(QLatin1String("/release"), Qt::CaseInsensitive)) {
|
|
QVERIFY(workingDirectory.cdUp());
|
|
QVERIFY(QDir::setCurrent(workingDirectory.absolutePath()));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void tst_Q3Process::init()
|
|
{
|
|
linesReadStdout.clear();
|
|
linesReadStderr.clear();
|
|
}
|
|
|
|
void tst_Q3Process::cleanup()
|
|
{
|
|
if ( proc ) {
|
|
proc->kill();
|
|
delete proc;
|
|
proc = 0;
|
|
}
|
|
}
|
|
|
|
void tst_Q3Process::readLineStdout_data()
|
|
{
|
|
QTest::addColumn<QString>("input");
|
|
QTest::addColumn<QStringList>("res");
|
|
|
|
QStringList l;
|
|
|
|
QTest::newRow( "unix_0" ) << QString("a\nbc\ndef\nghij\n")
|
|
<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
|
|
l.clear();
|
|
QTest::newRow( "unix_1" ) << QString("a\nbc\ndef\nghij")
|
|
<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
|
|
l.clear();
|
|
QTest::newRow( "unix_2" ) << QString("a\nbc\n\ndef\nghij\n")
|
|
<< (QStringList)( l << "a" << "bc" << "" << "def" << "ghij" );
|
|
l.clear();
|
|
|
|
QTest::newRow( "windows_0" ) << QString("a\r\nbc\r\ndef\r\nghij\r\n")
|
|
<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
|
|
l.clear();
|
|
QTest::newRow( "windows_1" ) << QString("a\r\nbc\r\ndef\r\nghij")
|
|
<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
|
|
l.clear();
|
|
QTest::newRow( "windows_2" ) << QString("a\r\nbc\r\n\r\ndef\r\nghij\r\n")
|
|
<< (QStringList)( l << "a" << "bc" << "" << "def" << "ghij" );
|
|
l.clear();
|
|
|
|
QTest::newRow( "mixed_0" ) << QString("a\r\nbc\ndef\r\nghij\n")
|
|
<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
|
|
l.clear();
|
|
QTest::newRow( "mixed_1" ) << QString("a\nbc\r\ndef\nghij\r\n")
|
|
<< (QStringList)( l << "a" << "bc" << "def" << "ghij" );
|
|
l.clear();
|
|
QTest::newRow( "mixed_2" ) << QString("a\nbc\r\r\ndef\r\r\r\nghij\r\r\r\r\n")
|
|
<< (QStringList)( l << "a" << "bc\r" << "def\r\r" << "ghij\r\r\r" );
|
|
l.clear();
|
|
}
|
|
|
|
void tst_Q3Process::readLineStdout()
|
|
{
|
|
QFETCH( QString, input );
|
|
|
|
if (proc) delete proc;
|
|
proc = new Q3Process( QString("cat/cat") );
|
|
connect( proc, SIGNAL(processExited()),
|
|
SLOT(processExited()) );
|
|
|
|
QVERIFY( proc->launch( input ) );
|
|
|
|
QTestEventLoop::instance().enterLoop( 29 );
|
|
if ( QTestEventLoop::instance().timeout() )
|
|
QFAIL( "Operation timed out" );
|
|
|
|
QTEST( linesReadStdout, "res" );
|
|
}
|
|
|
|
void tst_Q3Process::readLineStderr_data()
|
|
{
|
|
readLineStdout_data();
|
|
}
|
|
|
|
void tst_Q3Process::readLineStderr()
|
|
{
|
|
QFETCH( QString, input );
|
|
|
|
if (proc) delete proc;
|
|
proc = new Q3Process( QString("cat/cat -stderr").split(' ') );
|
|
connect( proc, SIGNAL(processExited()),
|
|
SLOT(processExited()) );
|
|
|
|
QVERIFY( proc->launch( input ) );
|
|
|
|
QTestEventLoop::instance().enterLoop( 29 );
|
|
if ( QTestEventLoop::instance().timeout() )
|
|
QFAIL( "Operation timed out" );
|
|
|
|
QTEST( linesReadStderr, "res" );
|
|
}
|
|
|
|
void tst_Q3Process::communication_data()
|
|
{
|
|
QTest::addColumn<QStringList>("command");
|
|
QTest::addColumn<int>("commFlags");
|
|
QTest::addColumn<QString>("input");
|
|
QTest::addColumn<QString>("resStdout");
|
|
QTest::addColumn<QString>("resStderr");
|
|
|
|
QTest::newRow( "no_dup_0" ) << QString("cat/cat").split(' ')
|
|
<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr )
|
|
<< QString("12345")
|
|
<< QString("12345")
|
|
<< QString();
|
|
QTest::newRow( "no_dup_1" ) << QString("cat/cat -stderr").split(' ')
|
|
<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr )
|
|
<< QString("12345")
|
|
<< QString()
|
|
<< QString("12345");
|
|
QTest::newRow( "no_dup_2" ) << QString("cat/cat -stdout_and_stderr").split(' ')
|
|
<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr )
|
|
<< QString("12345")
|
|
<< QString("12345")
|
|
<< QString("23456");
|
|
|
|
QTest::newRow( "dup_0" ) << QString("cat/cat").split(' ')
|
|
<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr | Q3Process::DupStderr )
|
|
<< QString("12345")
|
|
<< QString("12345")
|
|
<< QString();
|
|
QTest::newRow( "dup_1" ) << QString("cat/cat -stderr").split(' ')
|
|
<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr | Q3Process::DupStderr )
|
|
<< QString("12345")
|
|
<< QString("12345")
|
|
<< QString();
|
|
QTest::newRow( "dup_2" ) << QString("cat/cat -stdout_and_stderr").split(' ')
|
|
<< ( Q3Process::Stdin | Q3Process::Stdout | Q3Process::Stderr | Q3Process::DupStderr )
|
|
<< QString("12345")
|
|
<< QString("1223344556")
|
|
<< QString();
|
|
}
|
|
|
|
void tst_Q3Process::communication()
|
|
{
|
|
for ( int i=0; i<2; i++ ) {
|
|
cleanup();
|
|
|
|
QFETCH( QStringList, command );
|
|
QFETCH( int, commFlags );
|
|
QFETCH( QString, input );
|
|
|
|
if (proc) delete proc;
|
|
proc = new Q3Process( command );
|
|
proc->setCommunication( commFlags );
|
|
connect( proc, SIGNAL(processExited()),
|
|
SLOT(processExited()) );
|
|
|
|
QVERIFY( proc->launch( input ) );
|
|
|
|
QTestEventLoop::instance().enterLoop( 29 );
|
|
if ( QTestEventLoop::instance().timeout() )
|
|
QFAIL( "Operation timed out" );
|
|
|
|
if ( i == 0 ) {
|
|
QTEST( QString( proc->readStdout() ), "resStdout" );
|
|
QTEST( QString( proc->readStderr() ), "resStderr" );
|
|
} else {
|
|
QTEST( QString( proc->readStdout() ), "resStdout" );
|
|
QTEST( QString( proc->readStderr() ), "resStderr" );
|
|
}
|
|
}
|
|
}
|
|
|
|
void tst_Q3Process::canReadLineStdout_data()
|
|
{
|
|
readLineStdout_data();
|
|
}
|
|
|
|
void tst_Q3Process::canReadLineStdout()
|
|
{
|
|
// This function tests the busy-loop abilities of the canReadLineStdout()
|
|
// function.
|
|
QFETCH( QString, input );
|
|
QFETCH(QStringList, res);
|
|
|
|
if (proc) delete proc;
|
|
proc = new Q3Process( QString("cat/cat") );
|
|
QVERIFY( proc->start() );
|
|
proc->writeToStdin( input );
|
|
proc->flushStdin();
|
|
proc->closeStdin();
|
|
|
|
do {
|
|
connect(proc, SIGNAL(readyReadStdout()), this, SLOT(exitLoopSlot()));
|
|
QTestEventLoop::instance().enterLoop(5);
|
|
if (QTestEventLoop::instance().timeout()) {
|
|
if (!proc->isRunning())
|
|
break;
|
|
QFAIL("Timed out while waiting for my kids");
|
|
}
|
|
|
|
// q3process can (actually!) emit readyRead() when
|
|
// canReadLineStdout() is called.
|
|
proc->disconnect();
|
|
|
|
while ( proc->canReadLineStdout() )
|
|
linesReadStdout << proc->readLineStdout();
|
|
} while (linesReadStdout.size() < res.size() && proc->isRunning());
|
|
|
|
// q3process can (actually!) emit readyRead() when
|
|
// canReadLineStdout() is called.
|
|
proc->disconnect();
|
|
|
|
// if the last line is not terminated with a newline, we get it only after
|
|
// we determined that the process is not running anymore
|
|
if ( proc->canReadLineStdout() )
|
|
linesReadStdout << proc->readLineStdout();
|
|
|
|
QCOMPARE( linesReadStdout, res );
|
|
}
|
|
|
|
void tst_Q3Process::exitLoopSlot()
|
|
{
|
|
QTestEventLoop::instance().exitLoop();
|
|
}
|
|
|
|
void tst_Q3Process::canReadLineStderr_data()
|
|
{
|
|
readLineStdout_data();
|
|
}
|
|
|
|
void tst_Q3Process::canReadLineStderr()
|
|
{
|
|
// This function tests the busy-loop abilities of the canReadLineStderr()
|
|
// function.
|
|
QFETCH( QString, input );
|
|
QFETCH(QStringList, res);
|
|
|
|
if (proc) delete proc;
|
|
proc = new Q3Process( QString("cat/cat -stderr").split(' ') );
|
|
QVERIFY( proc->start() );
|
|
proc->writeToStdin( input );
|
|
proc->flushStdin();
|
|
proc->closeStdin();
|
|
|
|
do {
|
|
connect(proc, SIGNAL(readyReadStderr()), this, SLOT(exitLoopSlot()));
|
|
QTestEventLoop::instance().enterLoop(5);
|
|
if (QTestEventLoop::instance().timeout()) {
|
|
if (!proc->isRunning())
|
|
break;
|
|
QFAIL("Timed out while waiting for my kids");
|
|
}
|
|
|
|
// q3process can (actually!) emit readyRead() when
|
|
// canReadLineStdout() is called.
|
|
proc->disconnect();
|
|
|
|
while ( proc->canReadLineStderr() )
|
|
linesReadStderr << proc->readLineStderr();
|
|
} while (linesReadStderr.size() < res.size() && proc->isRunning());
|
|
|
|
// q3process can (actually!) emit readyRead() when
|
|
// canReadLineStdout() is called.
|
|
proc->disconnect();
|
|
|
|
// if the last line is not terminated with a newline, we get it only after
|
|
// we determined that the process is not running anymore
|
|
if ( proc->canReadLineStderr() )
|
|
linesReadStderr << proc->readLineStderr();
|
|
|
|
QCOMPARE( linesReadStderr, res );
|
|
}
|
|
|
|
void tst_Q3Process::processExited()
|
|
{
|
|
if ( QTest::currentTestFunction() == QLatin1String("readLineStdout") ) {
|
|
QVERIFY( proc != 0 );
|
|
|
|
// q3process can (actually!) emit readyRead() when
|
|
// canReadLineStdout() is called.
|
|
proc->disconnect();
|
|
|
|
while ( proc->canReadLineStdout() )
|
|
linesReadStdout << proc->readLineStdout();
|
|
|
|
// if canReadLine...() returns FALSE, the readLine...() function should
|
|
// return QString::null
|
|
QVERIFY( proc->readLineStdout().isNull() );
|
|
|
|
QTestEventLoop::instance().exitLoop();
|
|
|
|
} else if ( QTest::currentTestFunction() == QLatin1String("readLineStderr") ) {
|
|
QVERIFY( proc != 0 );
|
|
|
|
// q3process can (actually!) emit readyRead() when
|
|
// canReadLineStdout() is called.
|
|
proc->disconnect();
|
|
|
|
while ( proc->canReadLineStderr() )
|
|
linesReadStderr << proc->readLineStderr();
|
|
|
|
// if canReadLine...() returns FALSE, the readLine...() function should
|
|
// return QString::null
|
|
QVERIFY( proc->readLineStderr().isNull() );
|
|
|
|
QTestEventLoop::instance().exitLoop();
|
|
} else if ( QTest::currentTestFunction() == QLatin1String("communication") ) {
|
|
QTestEventLoop::instance().exitLoop();
|
|
}
|
|
}
|
|
|
|
void tst_Q3Process::startWithNoEnvironment()
|
|
{
|
|
QStringList args;
|
|
QByteArray result;
|
|
#ifdef Q_OS_MACX
|
|
args << "./echo/echo.app";
|
|
result = "./echo/echo.app/Contents/MacOS/echo";
|
|
#elif defined Q_OS_WIN
|
|
args << "./echo/echo";
|
|
result = "echo";
|
|
#else
|
|
args << "./echo/echo";
|
|
result = args[0];
|
|
#endif
|
|
args << "foo";
|
|
proc = new Q3Process(args);
|
|
QVERIFY(proc->start(/* environment = */ 0));
|
|
connect(proc, SIGNAL(readyReadStdout()), this, SLOT(exitLoopSlot()));
|
|
|
|
QTestEventLoop::instance().enterLoop(10);
|
|
QVERIFY(!QTestEventLoop::instance().timeout());
|
|
|
|
#ifdef Q_OS_WIN
|
|
// on different windows compilers the first arg is different,
|
|
// some just pass what was passed to createprocess while others
|
|
// expand the entire path.
|
|
QVERIFY(proc->readStdout().contains(result));
|
|
#else
|
|
QCOMPARE(proc->readStdout(), result);
|
|
#endif
|
|
}
|
|
|
|
void tst_Q3Process::startWithEmptyStringArgument()
|
|
{
|
|
// Test that this doesn't assert (task 122353)
|
|
Q3Process process("cmd");
|
|
process.addArgument(QString());
|
|
|
|
QStringList env;
|
|
process.start(&env);
|
|
}
|
|
|
|
QTEST_MAIN(tst_Q3Process)
|
|
#include "tst_q3process.moc"
|