forked from qt-creator/qt-creator
Utils: Add auto test for SynchronousProcess::runBlocking
QTCREATORBUG-25667 appeared a few Months back in corellation to a seemingly unrelated change, and I was much later scratching my head a day or two. Therefore, it should be fine to have a test for the usage of SynchronousProcess::runBlocking with interactive cli processes. Those cli processes might output lines without terminating \n or \r and thus hang until timeout. We are IMHO lacking process IO tests, anyways. Task-number: QTCREATORBUG-25667 Change-Id: I3b7ea471b2ac9fa4554f0ce51752ce54c4a7d304 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -35,6 +35,8 @@
|
||||
using namespace Utils;
|
||||
|
||||
const char kExitCodeSubProcessCode[] = "QTC_TST_QTCPROCESS_EXITCODE_CODE";
|
||||
const char kRunBlockingStdOutSubProcessMagicWord[] = "42";
|
||||
const char kRunBlockingStdOutSubProcessWithEndl[] = "QTC_TST_QTCPROCESS_RUNBLOCKINGSTDOUT_WITHENDL";
|
||||
|
||||
static void exitCodeSubProcessMain()
|
||||
{
|
||||
@@ -43,6 +45,18 @@ static void exitCodeSubProcessMain()
|
||||
exit(exitCode);
|
||||
}
|
||||
|
||||
static void blockingStdOutSubProcessMain()
|
||||
{
|
||||
std::cout << "Wait for the Answer to the Ultimate Question of Life, "
|
||||
"The Universe, and Everything..." << std::endl;
|
||||
QThread::msleep(300);
|
||||
std::cout << kRunBlockingStdOutSubProcessMagicWord << "...Now wait for the question...";
|
||||
if (qEnvironmentVariable(kRunBlockingStdOutSubProcessWithEndl) == "true")
|
||||
std::cout << std::endl;
|
||||
QThread::msleep(5000);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
class MacroMapExpander : public AbstractMacroExpander {
|
||||
public:
|
||||
virtual bool resolveMacro(const QString &name, QString *ret, QSet<AbstractMacroExpander*> &seen)
|
||||
@@ -86,6 +100,8 @@ private slots:
|
||||
void iteratorEditsLinux();
|
||||
void exitCode_data();
|
||||
void exitCode();
|
||||
void runBlockingStdOut_data();
|
||||
void runBlockingStdOut();
|
||||
|
||||
private:
|
||||
void iteratorEditsHelper(OsType osType);
|
||||
@@ -103,6 +119,8 @@ void tst_QtcProcess::initTestCase()
|
||||
{
|
||||
if (qEnvironmentVariableIsSet(kExitCodeSubProcessCode))
|
||||
exitCodeSubProcessMain();
|
||||
if (qEnvironmentVariableIsSet(kRunBlockingStdOutSubProcessWithEndl))
|
||||
blockingStdOutSubProcessMain();
|
||||
|
||||
homeStr = QLatin1String("@HOME@");
|
||||
home = QDir::homePath();
|
||||
@@ -803,6 +821,54 @@ void tst_QtcProcess::exitCode()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QtcProcess::runBlockingStdOut_data()
|
||||
{
|
||||
QTest::addColumn<bool>("withEndl");
|
||||
QTest::addColumn<int>("timeOutS");
|
||||
|
||||
QTest::newRow("Terminated stdout delivered instantly")
|
||||
<< true
|
||||
<< 2;
|
||||
QTest::newRow("Unterminated stdout lost: early timeout")
|
||||
<< false
|
||||
<< 2;
|
||||
QTest::newRow("Unterminated stdout lost: hanging")
|
||||
<< false
|
||||
<< 20;
|
||||
}
|
||||
|
||||
void tst_QtcProcess::runBlockingStdOut()
|
||||
{
|
||||
QFETCH(bool, withEndl);
|
||||
QFETCH(int, timeOutS);
|
||||
|
||||
SynchronousProcess sp;
|
||||
QStringList args = QCoreApplication::arguments();
|
||||
const QString binary = args.takeFirst();
|
||||
sp.setCommand(CommandLine(binary, args));
|
||||
Environment env = Environment::systemEnvironment();
|
||||
env.set(kRunBlockingStdOutSubProcessWithEndl, withEndl ? "true" : "false");
|
||||
sp.setEnvironment(env);
|
||||
sp.setTimeoutS(timeOutS);
|
||||
bool readLastLine = false;
|
||||
sp.setStdOutCallback([&readLastLine, &sp](const QString &out) {
|
||||
if (out.startsWith(kRunBlockingStdOutSubProcessMagicWord)) {
|
||||
readLastLine = true;
|
||||
sp.kill();
|
||||
}
|
||||
});
|
||||
sp.runBlocking();
|
||||
|
||||
// See also QTCREATORBUG-25667 for why it is a bad idea to use SynchronousProcess::runBlocking
|
||||
// with interactive cli tools.
|
||||
QEXPECT_FAIL("Unterminated stdout lost: early timeout", "", Continue);
|
||||
QVERIFY2(sp.result() != QtcProcess::Hang, "Process run did not time out.");
|
||||
|
||||
QEXPECT_FAIL("Unterminated stdout lost: early timeout", "", Continue);
|
||||
QEXPECT_FAIL("Unterminated stdout lost: hanging", "", Continue);
|
||||
QVERIFY2(readLastLine, "Last line was read.");
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QtcProcess)
|
||||
|
||||
#include "tst_qtcprocess.moc"
|
||||
|
Reference in New Issue
Block a user