forked from qt-creator/qt-creator
AutoTest: Handle async updates of executable information
When opening or creating a project for the first time the executable path of the application targets may be empty until the build system has updated this after the first successful build. This update happens asynchronously, so we might need to postpone the test execution a bit and wait for the respective update. Change-Id: I63b5c45f6ecb194020ea36bbb5c9486a4dcc004c Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#include <projectexplorer/buildconfiguration.h>
|
#include <projectexplorer/buildconfiguration.h>
|
||||||
#include <projectexplorer/buildmanager.h>
|
#include <projectexplorer/buildmanager.h>
|
||||||
|
#include <projectexplorer/buildsystem.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/projectexplorer.h>
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/projectexplorersettings.h>
|
#include <projectexplorer/projectexplorersettings.h>
|
||||||
@@ -64,6 +65,7 @@
|
|||||||
#include <QFutureInterface>
|
#include <QFutureInterface>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
#include <QPointer>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -317,6 +319,7 @@ void TestRunner::resetInternalPointers()
|
|||||||
void TestRunner::prepareToRunTests(TestRunMode mode)
|
void TestRunner::prepareToRunTests(TestRunMode mode)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!m_executingTests, return);
|
QTC_ASSERT(!m_executingTests, return);
|
||||||
|
m_skipTargetsCheck = false;
|
||||||
m_runMode = mode;
|
m_runMode = mode;
|
||||||
ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings =
|
ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings =
|
||||||
ProjectExplorerPlugin::projectExplorerSettings();
|
ProjectExplorerPlugin::projectExplorerSettings();
|
||||||
@@ -448,6 +451,15 @@ int TestRunner::precheckTestConfigurations()
|
|||||||
return testCaseCount;
|
return testCaseCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestRunner::onBuildSystemUpdated()
|
||||||
|
{
|
||||||
|
Target *target = SessionManager::startupTarget();
|
||||||
|
if (QTC_GUARD(target))
|
||||||
|
disconnect(target, &Target::buildSystemUpdated, this, &TestRunner::onBuildSystemUpdated);
|
||||||
|
m_skipTargetsCheck = true;
|
||||||
|
runOrDebugTests();
|
||||||
|
}
|
||||||
|
|
||||||
void TestRunner::runTests()
|
void TestRunner::runTests()
|
||||||
{
|
{
|
||||||
QList<TestConfiguration *> toBeRemoved;
|
QList<TestConfiguration *> toBeRemoved;
|
||||||
@@ -619,8 +631,34 @@ void TestRunner::debugTests()
|
|||||||
AutotestPlugin::popupResultsPane();
|
AutotestPlugin::popupResultsPane();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool executablesEmpty()
|
||||||
|
{
|
||||||
|
Target *target = SessionManager::startupTarget();
|
||||||
|
const QList<RunConfiguration *> configs = target->runConfigurations();
|
||||||
|
QTC_ASSERT(!configs.isEmpty(), return false);
|
||||||
|
if (auto execAspect = configs.first()->aspect<ExecutableAspect>())
|
||||||
|
return execAspect->executable().isEmpty();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void TestRunner::runOrDebugTests()
|
void TestRunner::runOrDebugTests()
|
||||||
{
|
{
|
||||||
|
if (!m_skipTargetsCheck) {
|
||||||
|
if (executablesEmpty()) {
|
||||||
|
m_skipTargetsCheck = true;
|
||||||
|
Target * target = SessionManager::startupTarget();
|
||||||
|
QTimer::singleShot(5000, this, [this, target = QPointer<Target>(target)]() {
|
||||||
|
if (target) {
|
||||||
|
disconnect(target, &Target::buildSystemUpdated,
|
||||||
|
this, &TestRunner::onBuildSystemUpdated);
|
||||||
|
}
|
||||||
|
runOrDebugTests();
|
||||||
|
});
|
||||||
|
connect(target, &Target::buildSystemUpdated, this, &TestRunner::onBuildSystemUpdated);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (m_runMode) {
|
switch (m_runMode) {
|
||||||
case TestRunMode::Run:
|
case TestRunMode::Run:
|
||||||
case TestRunMode::RunWithoutDeploy:
|
case TestRunMode::RunWithoutDeploy:
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ private:
|
|||||||
void runOrDebugTests();
|
void runOrDebugTests();
|
||||||
void reportResult(ResultType type, const QString &description);
|
void reportResult(ResultType type, const QString &description);
|
||||||
explicit TestRunner(QObject *parent = nullptr);
|
explicit TestRunner(QObject *parent = nullptr);
|
||||||
|
bool postponeTestRunWithEmptyExecutable(ProjectExplorer::Project *project);
|
||||||
|
void onBuildSystemUpdated();
|
||||||
|
|
||||||
QFutureWatcher<TestResultPtr> m_futureWatcher;
|
QFutureWatcher<TestResultPtr> m_futureWatcher;
|
||||||
QFutureInterface<TestResultPtr> *m_fakeFutureInterface = nullptr;
|
QFutureInterface<TestResultPtr> *m_fakeFutureInterface = nullptr;
|
||||||
@@ -111,6 +113,7 @@ private:
|
|||||||
QMetaObject::Connection m_finishDebugConnect;
|
QMetaObject::Connection m_finishDebugConnect;
|
||||||
// temporarily used for handling of switching the current target
|
// temporarily used for handling of switching the current target
|
||||||
QMetaObject::Connection m_targetConnect;
|
QMetaObject::Connection m_targetConnect;
|
||||||
|
bool m_skipTargetsCheck = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RunConfigurationSelectionDialog : public QDialog
|
class RunConfigurationSelectionDialog : public QDialog
|
||||||
|
|||||||
Reference in New Issue
Block a user