ProcessLauncher: Don't emit error twice on process crash

Behave the same as QProcess in this circumstances.

Change-Id: If8175ccb7102d6a561584ee73c2e5c5844f2770d
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Jarek Kobus
2022-03-15 14:41:28 +01:00
parent b6f679d777
commit dabe2e1493
2 changed files with 34 additions and 5 deletions

View File

@@ -136,15 +136,19 @@ void LauncherSocketHandler::handleSocketClosed()
void LauncherSocketHandler::handleProcessError() void LauncherSocketHandler::handleProcessError()
{ {
Process * proc = senderProcess(); Process * proc = senderProcess();
// In case of FailedToStart we won't receive finished signal, so we send the error
// packet and remove the process here and now. For all other errors we should expect
// corresponding finished signal to appear, so we will send the error data together with
// the finished packet later on.
if (proc->error() != QProcess::FailedToStart)
return;
ProcessErrorPacket packet(proc->token()); ProcessErrorPacket packet(proc->token());
packet.error = proc->error(); packet.error = proc->error();
packet.errorString = proc->errorString(); packet.errorString = proc->errorString();
sendPacket(packet); sendPacket(packet);
removeProcess(proc->token());
// In case of FailedToStart we won't receive finished signal, so we remove the process here.
// For all other errors we should expect corresponding finished signal to appear.
if (proc->error() == QProcess::FailedToStart)
removeProcess(proc->token());
} }
void LauncherSocketHandler::handleProcessStarted() void LauncherSocketHandler::handleProcessStarted()

View File

@@ -201,6 +201,7 @@ private slots:
void killBlockingProcess_data(); void killBlockingProcess_data();
void killBlockingProcess(); void killBlockingProcess();
void flushFinishedWhileWaitingForReadyRead(); void flushFinishedWhileWaitingForReadyRead();
void emitOneErrorOnCrash();
void cleanupTestCase(); void cleanupTestCase();
@@ -219,6 +220,7 @@ private:
SUB_CREATOR_PROCESS(ProcessChannelForwarding); SUB_CREATOR_PROCESS(ProcessChannelForwarding);
SUB_CREATOR_PROCESS(SubProcessChannelForwarding); SUB_CREATOR_PROCESS(SubProcessChannelForwarding);
SUB_CREATOR_PROCESS(KillBlockingProcess); SUB_CREATOR_PROCESS(KillBlockingProcess);
SUB_CREATOR_PROCESS(EmitOneErrorOnCrash);
// In order to get a value associated with the certain subprocess use SubProcessClass::envVar(). // In order to get a value associated with the certain subprocess use SubProcessClass::envVar().
// The classes above define different custom executables. Inside initTestCase() // The classes above define different custom executables. Inside initTestCase()
@@ -1312,6 +1314,29 @@ void tst_QtcProcess::flushFinishedWhileWaitingForReadyRead()
QVERIFY(reply.contains(simpleTestData)); QVERIFY(reply.contains(simpleTestData));
} }
void tst_QtcProcess::EmitOneErrorOnCrash::main()
{
abort();
}
void tst_QtcProcess::emitOneErrorOnCrash()
{
SubCreatorConfig subConfig(EmitOneErrorOnCrash::envVar(), {});
TestProcess process;
subConfig.setupSubProcess(&process);
int errorCount = 0;
connect(&process, &QtcProcess::errorOccurred, this, [&errorCount] { ++errorCount; });
process.start();
QVERIFY(process.waitForStarted(1000));
QEventLoop loop;
connect(&process, &QtcProcess::finished, &loop, &QEventLoop::quit);
loop.exec();
QCOMPARE(errorCount, 1);
}
QTEST_MAIN(tst_QtcProcess) QTEST_MAIN(tst_QtcProcess)
#include "tst_qtcprocess.moc" #include "tst_qtcprocess.moc"