summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAssam Boudjelthia <[email protected]>2023-11-20 15:28:02 +0200
committerQt Cherry-pick Bot <[email protected]>2023-11-28 19:14:27 +0000
commit8f1a026c393df746a287022991831537d08eb3f6 (patch)
tree4a3147237d8fa74084b0451e057b5003adcc91ee
parente531199f732b9e893f688df7fec1580ef178211c (diff)
AndroidTestRunner: print logcat and crash stacktrace when a test fails
For better debugging for test failures, print both logcat and crash stacktrace (since the start of the current test only), to have an immediate idea of the reason of the failure or crash if any. The crash report and the logcat for Android before level 23, is fetched from the device's time of the app start since those two cases don't have an option for filtering by pid. Task-number: QTQAINFRA-5928 Fixes: QTBUG-114898 Change-Id: I7760985032f342da4165cdb7573d4cfe5369ae03 Reviewed-by: Dimitrios Apostolou <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Axel Spoerl <[email protected]> (cherry picked from commit 518ac20dcb3cebf0956a399f40cbf51e9f3c188e) Reviewed-by: Qt Cherry-pick Bot <[email protected]> (cherry picked from commit f3c1bad7e58135bd5557f430c118cfd8921a05c2)
-rw-r--r--src/tools/androidtestrunner/main.cpp88
1 files changed, 72 insertions, 16 deletions
diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp
index a30e57cc1f7..7d8b67b85ea 100644
--- a/src/tools/androidtestrunner/main.cpp
+++ b/src/tools/androidtestrunner/main.cpp
@@ -487,6 +487,65 @@ struct RunnerLocker
QSystemSemaphore runner{QStringLiteral("androidtestrunner"), 1, QSystemSemaphore::Open};
};
+void printLogcat(const QString &formattedTime)
+{
+ QString logcatCmd = "%1 logcat "_L1.arg(g_options.adbCommand);
+ if (g_options.sdkVersion <= 23 || g_options.pid == -1)
+ logcatCmd += "-t '%1'"_L1.arg(formattedTime);
+ else
+ logcatCmd += "-d --pid=%1"_L1.arg(QString::number(g_options.pid));
+
+ QByteArray logcat;
+ if (!execCommand(logcatCmd, &logcat)) {
+ qCritical() << "Error: failed to fetch logcat of the test";
+ return;
+ }
+
+ if (logcat.isEmpty()) {
+ qWarning() << "The retrieved logcat is empty";
+ return;
+ }
+
+ qDebug() << "****** Begin logcat output ******";
+ qDebug().noquote() << logcat;
+ qDebug() << "****** End logcat output ******";
+}
+
+void printLogcatCrashBuffer(const QString &formattedTime)
+{
+ QString crashCmd = "%1 logcat -b crash -t '%2'"_L1.arg(g_options.adbCommand, formattedTime);
+
+ QByteArray crashLogcat;
+ if (!execCommand(crashCmd, &crashLogcat)) {
+ qCritical() << "Error: failed to fetch logcat crash buffer";
+ return;
+ }
+
+ if (crashLogcat.isEmpty()) {
+ qDebug() << "The retrieved logcat crash buffer is empty";
+ return;
+ }
+
+ qDebug() << "****** Begin logcat crash buffer output ******";
+ qDebug().noquote() << crashLogcat;
+ qDebug() << "****** End logcat crash buffer output ******";
+}
+
+static QString getCurrentTimeString()
+{
+ const QString timeFormat = (g_options.sdkVersion <= 23) ?
+ "%m-%d\\ %H:%M:%S.000"_L1 : "%Y-%m-%d\\ %H:%M:%S.%3N"_L1;
+
+ QString dateCmd = "%1 shell date +'%2'"_L1.arg(g_options.adbCommand, timeFormat);
+ QByteArray output;
+ if (!execCommand(dateCmd, &output)) {
+ qWarning() << "Date/time adb command failed";
+ return {};
+ }
+
+ return QString::fromUtf8(output.simplified());
+}
+
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
@@ -541,28 +600,25 @@ int main(int argc, char *argv[])
if (!parseTestArgs())
return 1;
+ const QString formattedTime = getCurrentTimeString();
+
// start the tests
- bool res = execCommand(QStringLiteral("%1 %2").arg(g_options.adbCommand, g_options.testArgs),
+ bool res = execCommand("%1 %2"_L1.arg(g_options.adbCommand, g_options.testArgs),
nullptr, g_options.verbose)
&& waitToFinish();
- // get logcat output
- if (res && g_options.showLogcatOutput) {
- if (g_options.sdkVersion <= 23) {
- fprintf(stderr, "Cannot show logcat output on Android 23 and below.\n");
- fflush(stderr);
- } else if (g_options.pid > 0) {
- fprintf(stdout, "Logcat output:\n");
- res &= execCommand(QStringLiteral("%1 logcat -d --pid=%2")
- .arg(g_options.adbCommand)
- .arg(g_options.pid),
- nullptr, true);
- fprintf(stdout, "End Logcat output.\n");
- }
- }
-
if (res)
res &= pullFiles();
+
+ // 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 (!res) {
+ printLogcat(formattedTime);
+ printLogcatCrashBuffer(formattedTime);
+ } else if (g_options.showLogcatOutput) {
+ printLogcat(formattedTime);
+ }
+
res &= execCommand(QStringLiteral("%1 uninstall %2").arg(g_options.adbCommand, g_options.package),
nullptr, g_options.verbose);
fflush(stdout);