AndroidTestRunner: get test exit code instead of parsing results

Write the exit code for qt tests at the end of the test run where
it would be available to androidtestrunner to find out the exact
number of failed tests, this would make the custom parses in the
androidtestrunner redandant.

Fixes: QTBUG-129976
Pick-to: 6.8
Change-Id: I3c2ea9780505f1d4a2a46ae94534cd1e4f07334c
Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
This commit is contained in:
Assam Boudjelthia 2024-10-20 17:20:19 +03:00
parent 0c68277020
commit 8d4022187b
2 changed files with 53 additions and 12 deletions

View File

@ -111,6 +111,10 @@
#include <emscripten.h>
#endif
#ifdef Q_OS_ANDROID
#include <QtCore/QStandardPaths>
#endif
#include <vector>
QT_BEGIN_NAMESPACE
@ -1790,6 +1794,14 @@ static void initEnvironment()
qputenv("QT_QTESTLIB_RUNNING", "1");
}
#ifdef Q_OS_ANDROID
static QFile androidExitCodeFile()
{
const QString testHome = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
return QFile(testHome + "/qtest_last_exit_code"_L1);
}
#endif
/*!
Executes tests declared in \a testObject. In addition, the private slots
\c{initTestCase()}, \c{cleanupTestCase()}, \c{init()} and \c{cleanup()}
@ -1890,6 +1902,10 @@ void QTest::qInit(QObject *testObject, int argc, char **argv)
if (QBenchmarkGlobalData::current->mode() != QBenchmarkGlobalData::CallgrindParentProcess)
#endif
QTestLog::startLogging();
#ifdef Q_OS_ANDROID
androidExitCodeFile().remove();
#endif
}
/*! \internal
@ -1984,7 +2000,19 @@ int QTest::qRun()
#endif
// make sure our exit code is never going above 127
// since that could wrap and indicate 0 test fails
return qMin(QTestLog::failCount(), 127);
const int exitCode = qMin(QTestLog::failCount(), 127);
#ifdef Q_OS_ANDROID
QFile exitCodeFile = androidExitCodeFile();
if (exitCodeFile.open(QIODevice::WriteOnly)) {
exitCodeFile.write(qPrintable(QString::number(exitCode)));
} else {
qWarning("Failed to open %s for writing test exit code: %s",
qPrintable(exitCodeFile.fileName()), qPrintable(exitCodeFile.errorString()));
}
#endif
return exitCode;
}
/*! \internal

View File

@ -547,7 +547,7 @@ static QString runCommandAsUserArgs(const QString &cmd)
return "run-as %1 --user %2 %3"_L1.arg(g_options.package, g_testInfo.userId, cmd);
}
static bool pullFiles()
static bool pullResults()
{
bool ret = true;
for (auto it = g_options.outFiles.constBegin(); it != g_options.outFiles.end(); ++it) {
@ -702,6 +702,19 @@ static QString getCurrentTimeString()
return QString::fromUtf8(output.simplified());
}
static int testExitCode()
{
QByteArray exitCodeOutput;
const QString exitCodeCmd = "cat files/qtest_last_exit_code 2> /dev/null"_L1;
if (!execAdbCommand({ "shell"_L1, runCommandAsUserArgs(exitCodeCmd) }, &exitCodeOutput))
return 1;
bool ok;
int exitCode = exitCodeOutput.toInt(&ok);
return ok ? exitCode : 1;
}
static bool uninstallTestPackage()
{
return execAdbCommand({ "uninstall"_L1, g_options.package }, nullptr);
@ -814,24 +827,24 @@ int main(int argc, char *argv[])
const QString formattedTime = getCurrentTimeString();
// start the tests
bool success = execAdbCommand(g_options.amStarttestArgs, nullptr);
if (!execAdbCommand(g_options.amStarttestArgs, nullptr))
return 1;
waitForStartedAndFinished();
if (success) {
success &= pullFiles();
if (g_options.showLogcatOutput)
printLogcat(formattedTime);
}
int exitCode = testExitCode();
// If we have a failure, attempt to print both logcat and the crash buffer which
// includes the crash stacktrace that is not included in the default logcat.
if (!success) {
if (exitCode != 0 || g_options.showLogcatOutput)
printLogcat(formattedTime);
if (exitCode != 0)
printLogcatCrashBuffer(formattedTime);
}
success &= uninstallTestPackage();
exitCode = pullResults() ? exitCode : 1;
if (!uninstallTestPackage())
return 1;
testRunnerLock.release();
@ -840,5 +853,5 @@ int main(int argc, char *argv[])
return 1;
}
return success ? 0 : 1;
return exitCode;
}