AutoTest: Provide more details on failure or guess

If a test case cannot be started or does crash while executing
these information might help to sort out configuration problems.

Change-Id: I406d5e69475d05931d4c4c4738f8528c6d74c585
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2017-04-03 09:17:58 +02:00
parent 750f25d9e6
commit f173dc82df
3 changed files with 42 additions and 14 deletions

View File

@@ -130,6 +130,7 @@ void TestConfiguration::completeTestInformation(int runMode)
m_executableFile = exeString; m_executableFile = exeString;
m_project = project; m_project = project;
m_guessedConfiguration = true; m_guessedConfiguration = true;
m_guessedFrom = rc->displayName();
if (runMode == TestRunner::Debug) if (runMode == TestRunner::Debug)
m_runConfig = new TestRunConfiguration(rc->target(), this); m_runConfig = new TestRunConfiguration(rc->target(), this);
} }
@@ -203,11 +204,6 @@ void TestConfiguration::setProject(Project *project)
m_project = project; m_project = project;
} }
void TestConfiguration::setGuessedConfiguration(bool guessed)
{
m_guessedConfiguration = guessed;
}
QString TestConfiguration::executableFilePath() const QString TestConfiguration::executableFilePath() const
{ {
if (m_executableFile.isEmpty()) if (m_executableFile.isEmpty())

View File

@@ -66,7 +66,6 @@ public:
void setDisplayName(const QString &displayName); void setDisplayName(const QString &displayName);
void setEnvironment(const Utils::Environment &env); void setEnvironment(const Utils::Environment &env);
void setProject(ProjectExplorer::Project *project); void setProject(ProjectExplorer::Project *project);
void setGuessedConfiguration(bool guessed);
QStringList testCases() const { return m_testCases; } QStringList testCases() const { return m_testCases; }
int testCaseCount() const { return m_testCaseCount; } int testCaseCount() const { return m_testCaseCount; }
@@ -77,7 +76,9 @@ public:
Utils::Environment environment() const { return m_environment; } Utils::Environment environment() const { return m_environment; }
ProjectExplorer::Project *project() const { return m_project.data(); } ProjectExplorer::Project *project() const { return m_project.data(); }
TestRunConfiguration *runConfiguration() const { return m_runConfig; } TestRunConfiguration *runConfiguration() const { return m_runConfig; }
bool guessedConfiguration() const { return m_guessedConfiguration; } bool isGuessed() const { return m_guessedConfiguration; }
QString runConfigDisplayName() const { return m_guessedConfiguration ? m_guessedFrom
: m_displayName; }
virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi, virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
QProcess *app) const = 0; QProcess *app) const = 0;
@@ -91,6 +92,7 @@ private:
QString m_workingDir; QString m_workingDir;
QString m_buildDir; QString m_buildDir;
QString m_displayName; QString m_displayName;
QString m_guessedFrom;
Utils::Environment m_environment; Utils::Environment m_environment;
QPointer<ProjectExplorer::Project> m_project; QPointer<ProjectExplorer::Project> m_project;
bool m_guessedConfiguration = false; bool m_guessedConfiguration = false;

View File

@@ -42,6 +42,7 @@
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <utils/hostosinfo.h>
#include <QFuture> #include <QFuture>
#include <QFutureInterface> #include <QFutureInterface>
@@ -95,6 +96,28 @@ void TestRunner::setSelectedTests(const QList<TestConfiguration *> &selected)
m_selectedTests = selected; m_selectedTests = selected;
} }
static QString processInformation(const QProcess &proc)
{
QString information("\nCommand line: " + proc.program() + ' ' + proc.arguments().join(' '));
QStringList important = { "PATH" };
if (Utils::HostOsInfo::isLinuxHost())
important.append("LD_LIBRARY_PATH");
else if (Utils::HostOsInfo::isMacHost())
important.append({ "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH" });
const QProcessEnvironment &environment = proc.processEnvironment();
for (const QString &var : important)
information.append('\n' + var + ": " + environment.value(var));
return information;
}
static QString rcInfo(const TestConfiguration * const config)
{
QString info = '\n' + TestRunner::tr("Run configuration:") + ' ';
if (config->isGuessed())
info += TestRunner::tr("guessed from");
return info + " \"" + config->runConfigDisplayName() + '"';
}
static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface, static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
const QList<TestConfiguration *> selectedTests, const QList<TestConfiguration *> selectedTests,
const TestSettings &settings) const TestSettings &settings)
@@ -107,11 +130,14 @@ static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
config->completeTestInformation(TestRunner::Run); config->completeTestInformation(TestRunner::Run);
if (config->project()) { if (config->project()) {
testCaseCount += config->testCaseCount(); testCaseCount += config->testCaseCount();
if (!omitRunConfigWarnings && config->guessedConfiguration()) { if (!omitRunConfigWarnings && config->isGuessed()) {
futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageWarn, QString message = TestRunner::tr(
TestRunner::tr("Project's run configuration was guessed for \"%1\".\n" "Project's run configuration was guessed for \"%1\".\n"
"This might cause trouble during execution." "This might cause trouble during execution.\n"
).arg(config->displayName())))); "(guessed from \"%2\")");
message = message.arg(config->displayName()).arg(config->runConfigDisplayName());
futureInterface.reportResult(
TestResultPtr(new FaultyTestResult(Result::MessageWarn, message)));
} }
} else { } else {
futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageWarn, futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageWarn,
@@ -172,11 +198,15 @@ static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
} }
} else { } else {
futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal, futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
TestRunner::tr("Failed to start test for project \"%1\".").arg(testConfiguration->displayName())))); TestRunner::tr("Failed to start test for project \"%1\".")
.arg(testConfiguration->displayName()) + processInformation(testProcess)
+ rcInfo(testConfiguration))));
} }
if (testProcess.exitStatus() == QProcess::CrashExit) { if (testProcess.exitStatus() == QProcess::CrashExit) {
futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal, futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
TestRunner::tr("Test for project \"%1\" crashed.").arg(testConfiguration->displayName())))); TestRunner::tr("Test for project \"%1\" crashed.")
.arg(testConfiguration->displayName()) + processInformation(testProcess)
+ rcInfo(testConfiguration))));
} }
if (canceledByTimeout) { if (canceledByTimeout) {