diff options
Diffstat (limited to 'tests/auto/corelib/io/qprocess/tst_qprocess.cpp')
-rw-r--r-- | tests/auto/corelib/io/qprocess/tst_qprocess.cpp | 127 |
1 files changed, 78 insertions, 49 deletions
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 712e3440d8..e5195000aa 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -1,32 +1,27 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2015 Intel Corporation. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** 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. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** @@ -45,15 +40,7 @@ #include <QtNetwork/QHostInfo> #include <stdlib.h> -#ifndef QT_NO_PROCESS # include <private/qprocess_p.h> // only so we get QPROCESS_USE_SPAWN -# if defined(Q_OS_WIN) -# include <windows.h> -# endif - -Q_DECLARE_METATYPE(QProcess::ExitStatus); -Q_DECLARE_METATYPE(QProcess::ProcessState); -#endif typedef void (QProcess::*QProcessFinishedSignal1)(int); typedef void (QProcess::*QProcessFinishedSignal2)(int, QProcess::ExitStatus); @@ -138,7 +125,8 @@ private slots: void spaceArgsTest(); #if defined(Q_OS_WIN) void nativeArguments(); -#endif + void createProcessArgumentsModifier(); +#endif // Q_OS_WIN void exitCodeTest(); void systemEnvironment(); void lockupsInStartDetached(); @@ -497,9 +485,11 @@ void tst_QProcess::echoTest2() QCOMPARE(process.error(), QProcess::Timedout); process.write("Hello"); + QSignalSpy spy0(&process, &QProcess::channelReadyRead); QSignalSpy spy1(&process, &QProcess::readyReadStandardOutput); QSignalSpy spy2(&process, &QProcess::readyReadStandardError); + QVERIFY(spy0.isValid()); QVERIFY(spy1.isValid()); QVERIFY(spy2.isValid()); @@ -518,6 +508,7 @@ void tst_QProcess::echoTest2() break; } + QVERIFY(spy0.count() > 0); QVERIFY(spy1.count() > 0); QVERIFY(spy2.count() > 0); @@ -840,11 +831,11 @@ void tst_QProcess::openModes() { QProcess proc; QVERIFY(!proc.isOpen()); - QVERIFY(proc.openMode() == QProcess::NotOpen); + QCOMPARE(proc.openMode(), QProcess::NotOpen); proc.start("testProcessEcho3/testProcessEcho3"); QVERIFY(proc.waitForStarted(5000)); QVERIFY(proc.isOpen()); - QVERIFY(proc.openMode() == QProcess::ReadWrite); + QCOMPARE(proc.openMode(), QProcess::ReadWrite); QVERIFY(proc.isReadable()); QVERIFY(proc.isWritable()); @@ -853,7 +844,7 @@ void tst_QProcess::openModes() proc.closeWriteChannel(); QVERIFY(proc.isWritable()); - QVERIFY(proc.openMode() == QProcess::ReadWrite); + QCOMPARE(proc.openMode(), QProcess::ReadWrite); while (proc.bytesAvailable() < 4 && proc.waitForReadyRead(5000)) { } @@ -862,12 +853,12 @@ void tst_QProcess::openModes() proc.closeReadChannel(QProcess::StandardOutput); - QVERIFY(proc.openMode() == QProcess::ReadWrite); + QCOMPARE(proc.openMode(), QProcess::ReadWrite); QVERIFY(proc.isReadable()); proc.closeReadChannel(QProcess::StandardError); - QVERIFY(proc.openMode() == QProcess::ReadWrite); + QCOMPARE(proc.openMode(), QProcess::ReadWrite); QVERIFY(proc.isReadable()); proc.close(); @@ -989,6 +980,9 @@ public: this, &SoftExitProcess::terminateSlot); break; case 4: + setReadChannelMode(QProcess::MergedChannels); + connect(this, SIGNAL(channelReadyRead(int)), this, SLOT(terminateSlot())); + break; default: connect(this, &QProcess::stateChanged, this, &SoftExitProcess::terminateSlot); @@ -1010,8 +1004,8 @@ public: public slots: void terminateSlot() { - writePendingData(); // In cases 3 and 4 we haven't written the data yet. - if (killing || (n == 4 && state() != Running)) { + writePendingData(); // In cases 3 and 5 we haven't written the data yet. + if (killing || (n == 5 && state() != Running)) { // Don't try to kill the process before it is running - that can // be hazardous, as the actual child process might not be running // yet. Also, don't kill it "recursively". @@ -1050,24 +1044,33 @@ private: void tst_QProcess::softExitInSlots_data() { QTest::addColumn<QString>("appName"); + QTest::addColumn<int>("signalToConnect"); + QByteArray dataTagPrefix("gui app "); #ifndef QT_NO_WIDGETS - QTest::newRow("gui app") << "testGuiProcess/testGuiProcess"; + for (int i = 0; i < 6; ++i) { + QTest::newRow(dataTagPrefix + QByteArray::number(i)) + << "testGuiProcess/testGuiProcess" << i; + } #endif - QTest::newRow("console app") << "testProcessEcho2/testProcessEcho2"; + + dataTagPrefix = "console app "; + for (int i = 0; i < 6; ++i) { + QTest::newRow(dataTagPrefix + QByteArray::number(i)) + << "testProcessEcho2/testProcessEcho2" << i; + } } void tst_QProcess::softExitInSlots() { QFETCH(QString, appName); + QFETCH(int, signalToConnect); - for (int i = 0; i < 5; ++i) { - SoftExitProcess proc(i); - proc.writeAfterStart("OLEBOLE", 8); // include the \0 - proc.start(appName); - QTRY_VERIFY_WITH_TIMEOUT(proc.waitedForFinished, 10000); - QCOMPARE(proc.state(), QProcess::NotRunning); - } + SoftExitProcess proc(signalToConnect); + proc.writeAfterStart("OLEBOLE", 8); // include the \0 + proc.start(appName); + QTRY_VERIFY_WITH_TIMEOUT(proc.waitedForFinished, 10000); + QCOMPARE(proc.state(), QProcess::NotRunning); } #endif @@ -1439,11 +1442,11 @@ void tst_QProcess::spaceArgsTest() QCOMPARE(actual, args); #endif - if (program.contains(" ")) - program = "\"" + program + "\""; + if (program.contains(QLatin1Char(' '))) + program = QLatin1Char('"') + program + QLatin1Char('"'); if (!stringArgs.isEmpty()) - program += QString::fromLatin1(" ") + stringArgs; + program += QLatin1Char(' ') + stringArgs; errorMessage.clear(); process.start(program); @@ -1496,9 +1499,9 @@ void tst_QProcess::nativeArguments() char buf[256]; fgets(buf, 256, file); fclose(file); - QStringList actual = QString::fromLatin1(buf).split("|"); + QStringList actual = QString::fromLatin1(buf).split(QLatin1Char('|')); #else - QStringList actual = QString::fromLatin1(proc.readAll()).split("|"); + QStringList actual = QString::fromLatin1(proc.readAll()).split(QLatin1Char('|')); #endif QVERIFY(!actual.isEmpty()); // not interested in the program name, it might be different. @@ -1512,7 +1515,26 @@ void tst_QProcess::nativeArguments() QCOMPARE(actual, expected); } -#endif +void tst_QProcess::createProcessArgumentsModifier() +{ + int calls = 0; + const QString reversedCommand = "lamroNssecorPtset/lamroNssecorPtset"; + QProcess process; + process.setCreateProcessArgumentsModifier([&calls] (QProcess::CreateProcessArguments *args) + { + calls++; + std::reverse(args->arguments, args->arguments + wcslen(args->arguments) - 1); + }); + process.start(reversedCommand); + QVERIFY2(process.waitForStarted(), qUtf8Printable(process.errorString())); + QVERIFY(process.waitForFinished()); + QCOMPARE(calls, 1); + + process.setCreateProcessArgumentsModifier(QProcess::CreateProcessArgumentModifier()); + QVERIFY(!process.waitForStarted()); + QCOMPARE(calls, 1); +} +#endif // Q_OS_WIN void tst_QProcess::exitCodeTest() { @@ -2300,6 +2322,13 @@ void tst_QProcess::setNonExistentWorkingDirectory() QEXPECT_FAIL("", "QProcess cannot detect failure to start when using posix_spawn()", Continue); #endif QCOMPARE(int(process.error()), int(QProcess::FailedToStart)); + +#ifdef Q_OS_UNIX +# ifdef QPROCESS_USE_SPAWN + QEXPECT_FAIL("", "QProcess cannot detect failure to start when using posix_spawn()", Continue); +# endif + QVERIFY2(process.errorString().startsWith("chdir:"), process.errorString().toLocal8Bit()); +#endif } #endif |