AutoTest: Re-do completeTestInformation()

Use information provided by the codemodel and the run configurations
as much as possible to avoid guessing.
This also fixes running CMake based tests from within the
AutoTest plugin.

Task-number: QTCREATORBUG-17882
Change-Id: I5639fa947fa602b76faf50e9b58d7a74af4e1f9c
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Christian Stenger
2017-02-01 15:42:55 +01:00
parent a65ce0fe5b
commit 124efb32f5
3 changed files with 58 additions and 126 deletions

View File

@@ -88,9 +88,6 @@ TestConfiguration *GTestTreeItem::testConfiguration() const
config->setTestCaseCount(count); config->setTestCaseCount(count);
config->setProjectFile(proFile()); config->setProjectFile(proFile());
config->setProject(project); config->setProject(project);
// item has no filePath set - so take it of the first children
config->setDisplayName(
TestUtils::getCMakeDisplayNameIfNecessary(childItem(0)->filePath(), proFile()));
} }
break; break;
} }
@@ -103,8 +100,6 @@ TestConfiguration *GTestTreeItem::testConfiguration() const
config->setTestCases(QStringList(testSpecifier)); config->setTestCases(QStringList(testSpecifier));
config->setProjectFile(proFile()); config->setProjectFile(proFile());
config->setProject(project); config->setProject(project);
config->setDisplayName(
TestUtils::getCMakeDisplayNameIfNecessary(filePath(), parent->proFile()));
break; break;
} }
default: default:
@@ -179,7 +174,6 @@ QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
GTestConfiguration *tc = new GTestConfiguration; GTestConfiguration *tc = new GTestConfiguration;
tc->setTestCaseCount(it.value()); tc->setTestCaseCount(it.value());
tc->setProjectFile(key.proFile); tc->setProjectFile(key.proFile);
tc->setDisplayName(key.displayName);
tc->setProject(project); tc->setProject(project);
result << tc; result << tc;
} }
@@ -244,7 +238,6 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
tc->setTestCases(it.value().filters); tc->setTestCases(it.value().filters);
tc->setTestCaseCount(tc->testCaseCount() + it.value().additionalTestCaseCount); tc->setTestCaseCount(tc->testCaseCount() + it.value().additionalTestCaseCount);
tc->setProjectFile(proFileWithDisplayName.proFile); tc->setProjectFile(proFileWithDisplayName.proFile);
tc->setDisplayName(proFileWithDisplayName.displayName);
tc->setProject(project); tc->setProject(project);
result << tc; result << tc;
} }

View File

@@ -111,7 +111,6 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
config->setTestCaseCount(childCount()); config->setTestCaseCount(childCount());
config->setProjectFile(proFile()); config->setProjectFile(proFile());
config->setProject(project); config->setProject(project);
config->setDisplayName(TestUtils::getCMakeDisplayNameIfNecessary(filePath(), proFile()));
break; break;
case TestFunctionOrSet: { case TestFunctionOrSet: {
TestTreeItem *parent = parentItem(); TestTreeItem *parent = parentItem();
@@ -119,8 +118,6 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
config->setTestCases(QStringList(name())); config->setTestCases(QStringList(name()));
config->setProjectFile(parent->proFile()); config->setProjectFile(parent->proFile());
config->setProject(project); config->setProject(project);
config->setDisplayName(
TestUtils::getCMakeDisplayNameIfNecessary(filePath(), parent->proFile()));
break; break;
} }
case TestDataTag: { case TestDataTag: {
@@ -133,8 +130,6 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
config->setTestCases(QStringList(functionWithTag)); config->setTestCases(QStringList(functionWithTag));
config->setProjectFile(parent->proFile()); config->setProjectFile(parent->proFile());
config->setProject(project); config->setProject(project);
config->setDisplayName(TestUtils::getCMakeDisplayNameIfNecessary(filePath(),
parent->proFile()));
break; break;
} }
default: default:
@@ -166,8 +161,6 @@ QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
tc->setTestCaseCount(child->childCount()); tc->setTestCaseCount(child->childCount());
tc->setProjectFile(child->proFile()); tc->setProjectFile(child->proFile());
tc->setProject(project); tc->setProject(project);
tc->setDisplayName(TestUtils::getCMakeDisplayNameIfNecessary(child->filePath(),
child->proFile()));
result << tc; result << tc;
} }
return result; return result;
@@ -193,8 +186,6 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
testConfiguration->setTestCaseCount(child->childCount()); testConfiguration->setTestCaseCount(child->childCount());
testConfiguration->setProjectFile(child->proFile()); testConfiguration->setProjectFile(child->proFile());
testConfiguration->setProject(project); testConfiguration->setProject(project);
testConfiguration->setDisplayName(
TestUtils::getCMakeDisplayNameIfNecessary(child->filePath(), child->proFile()));
result << testConfiguration; result << testConfiguration;
continue; continue;
case Qt::PartiallyChecked: case Qt::PartiallyChecked:
@@ -220,8 +211,6 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
testConfiguration->setTestCases(testCases); testConfiguration->setTestCases(testCases);
testConfiguration->setProjectFile(child->proFile()); testConfiguration->setProjectFile(child->proFile());
testConfiguration->setProject(project); testConfiguration->setProject(project);
testConfiguration->setDisplayName(
TestUtils::getCMakeDisplayNameIfNecessary(child->filePath(), child->proFile()));
result << testConfiguration; result << testConfiguration;
} }
} }

View File

@@ -54,30 +54,6 @@ TestConfiguration::~TestConfiguration()
m_testCases.clear(); m_testCases.clear();
} }
void completeBasicProjectInformation(Project *project, const QString &proFile, QString *displayName,
Project **targetProject)
{
CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
QVector<CppTools::ProjectPart::Ptr> projParts = cppMM->projectInfo(project).projectParts();
if (displayName->isEmpty()) {
foreach (const CppTools::ProjectPart::Ptr &part, projParts) {
if (part->projectFile == proFile) {
*displayName = part->displayName;
*targetProject = part->project;
return;
}
}
} else { // for CMake based projects we've got the displayname already
foreach (const CppTools::ProjectPart::Ptr &part, projParts) {
if (part->displayName == *displayName) {
*targetProject = part->project;
return;
}
}
}
}
static bool isLocal(RunConfiguration *runConfiguration) static bool isLocal(RunConfiguration *runConfiguration)
{ {
Target *target = runConfiguration ? runConfiguration->target() : 0; Target *target = runConfiguration ? runConfiguration->target() : 0;
@@ -93,106 +69,80 @@ void TestConfiguration::completeTestInformation(int runMode)
if (!project) if (!project)
return; return;
QString executable;
QString targetName;
QString workDir;
QString displayName = m_displayName;
QString buildDir;
Project *targetProject = 0;
Utils::Environment env;
Target *runConfigTarget = 0;
bool hasDesktopTarget = false;
bool guessedRunConfiguration = false;
setProject(0);
completeBasicProjectInformation(project, m_projectFile, &displayName, &targetProject);
Target *target = project->activeTarget(); Target *target = project->activeTarget();
if (!target) if (!target)
return; return;
BuildTargetInfoList appTargets = target->applicationTargets(); const auto cppMM = CppTools::CppModelManager::instance();
if (m_displayName.isEmpty()) { const QVector<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectInfo(project).projectParts();
foreach (const BuildTargetInfo &bti, appTargets.list) { const QVector<CppTools::ProjectPart::Ptr> relevantParts
// some project manager store line/column information as well inside ProjectPart = Utils::filtered(projectParts, [this] (const CppTools::ProjectPart::Ptr &part) {
if (bti.isValid() && m_projectFile.startsWith(bti.projectFilePath.toString())) { return part->selectedForBuilding && part->projectFile == m_projectFile;
executable = bti.targetFilePath.toString(); });
if (Utils::HostOsInfo::isWindowsHost() && !executable.toLower().endsWith(".exe")) const QSet<QString> buildSystemTargets
executable = Utils::HostOsInfo::withExecutableSuffix(executable); = Utils::transform<QSet>(relevantParts, [] (const CppTools::ProjectPart::Ptr &part) {
targetName = bti.targetName; return part->buildSystemTarget;
break; });
}
}
} else { // CMake based projects have no specific pro file, but target name matches displayname
foreach (const BuildTargetInfo &bti, appTargets.list) {
if (bti.isValid() && m_displayName == bti.targetName) {
// for CMake base projects targetFilePath has executable suffix already
executable = bti.targetFilePath.toString();
targetName = m_displayName;
break;
}
}
}
if (targetProject) { const BuildTargetInfo targetInfo
if (auto buildConfig = target->activeBuildConfiguration()) { = Utils::findOrDefault(target->applicationTargets().list, [&buildSystemTargets] (const BuildTargetInfo &bti) {
const QString buildBase = buildConfig->buildDirectory().toString(); return buildSystemTargets.contains(bti.targetName);
const QString projBase = targetProject->projectDirectory().toString(); });
if (m_projectFile.startsWith(projBase)) const Utils::FileName executable = targetInfo.targetFilePath; // empty if BTI is default created
buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath(); for (RunConfiguration *runConfig : target->runConfigurations()) {
} if (!isLocal(runConfig)) // TODO add device support
} continue;
QList<RunConfiguration *> rcs = target->runConfigurations(); if (buildSystemTargets.contains(runConfig->buildSystemTarget())) {
foreach (RunConfiguration *rc, rcs) { Runnable runnable = runConfig->runnable();
Runnable runnable = rc->runnable(); if (!runnable.is<StandardRunnable>())
if (isLocal(rc) && runnable.is<StandardRunnable>()) { continue;
StandardRunnable stdRunnable = runnable.as<StandardRunnable>(); StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
// we might have an executable that gets installed - in such a case the // TODO this might pick up the wrong executable
// runnable's executable and executable won't match - but the (unique) display name m_executableFile = stdRunnable.executable;
// of the run configuration should match targetName m_displayName = runConfig->displayName();
if (stdRunnable.executable == executable m_workingDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory);
|| (!targetName.isEmpty() && rc->displayName() == targetName)) { m_environment = stdRunnable.environment;
executable = stdRunnable.executable; m_project = project;
workDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory); if (runMode == TestRunner::Debug)
env = stdRunnable.environment; m_runConfig = new TestRunConfiguration(runConfig->target(), this);
hasDesktopTarget = true; break;
runConfigTarget = rc->target();
break;
}
} }
} }
// RunConfiguration for this target could be explicitly removed or not created at all
// if we could not figure out the run configuration if (m_displayName.isEmpty() && !executable.isEmpty()) {
// try to use the run configuration of the parent project // we failed to find a valid runconfiguration - but we've got the executable already
if (!hasDesktopTarget && targetProject && !executable.isEmpty()) {
if (auto rc = target->activeRunConfiguration()) { if (auto rc = target->activeRunConfiguration()) {
Runnable runnable = rc->runnable(); if (isLocal(rc)) { // FIXME for now only Desktop support
if (isLocal(rc) && runnable.is<StandardRunnable>()) { Runnable runnable = rc->runnable();
StandardRunnable stdRunnable = runnable.as<StandardRunnable>(); if (runnable.is<StandardRunnable>()) {
workDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory); StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
env = stdRunnable.environment; m_environment = stdRunnable.environment;
hasDesktopTarget = true; // when guessing we might have no extension
guessedRunConfiguration = true; const QString &exeString = executable.toString();
runConfigTarget = rc->target(); if (Utils::HostOsInfo::isWindowsHost() && !exeString.toLower().endsWith(".exe"))
m_executableFile = Utils::HostOsInfo::withExecutableSuffix(exeString);
else
m_executableFile = exeString;
m_project = project;
m_guessedConfiguration = true;
if (runMode == TestRunner::Debug)
m_runConfig = new TestRunConfiguration(rc->target(), this);
}
} }
} }
} }
setDisplayName(displayName); if (auto buildConfig = target->activeBuildConfiguration()) {
const QString buildBase = buildConfig->buildDirectory().toString();
if (hasDesktopTarget) { const QString projBase = project->projectDirectory().toString();
setExecutableFile(executable); if (m_projectFile.startsWith(projBase))
setWorkingDirectory(workDir); m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath();
setBuildDirectory(buildDir);
setEnvironment(env);
setProject(project);
setGuessedConfiguration(guessedRunConfiguration);
if (runMode == TestRunner::Debug)
m_runConfig = new TestRunConfiguration(runConfigTarget, this);
} }
}
if (m_displayName.isEmpty()) // happens e.g. when guessing the TestConfiguration or error
m_displayName = buildSystemTargets.isEmpty() ? "unknown" : *buildSystemTargets.begin();
}
/** /**
* @brief sets the test cases for this test configuration. * @brief sets the test cases for this test configuration.