CppTools: Fix race condition when opening projects for tests

The ClangTools plugin tests open a project and immediately trigger a
build afterwards. We checked whether CppModelManager got already data
from the project manager, but this alone was racy for the mentioned use
case as e.g. the QbsProjectManager might still be in parsing mode and
thus the build was not triggerable. Check for the parsing state, too.

While at it, simplify the code by using QTest::qWaitFor(), which also
takes care of posted events.

Change-Id: Id298695b2e67578def42275bac4ea31f4a39edf2
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Nikolai Kosjar
2019-11-21 15:09:08 +01:00
parent e53e0a808b
commit 818f2d0c5c
3 changed files with 11 additions and 17 deletions

View File

@@ -237,7 +237,7 @@ bool OpenProjectCommand::run()
Project *project = openProjectSucceeded.project();
project->configureAsExampleProject();
return CppTools::Tests::TestCase::waitUntilCppModelManagerIsAwareOf(project, timeOutInMs());
return CppTools::Tests::TestCase::waitUntilProjectIsFullyOpened(project, timeOutInMs());
}
Command::Ptr OpenProjectCommand::parse(BatchFileLineTokenizer &arguments,

View File

@@ -226,22 +226,17 @@ QList<CPlusPlus::Document::Ptr> TestCase::waitForFilesInGlobalSnapshot(const QSt
return result;
}
bool TestCase::waitUntilCppModelManagerIsAwareOf(Project *project, int timeOutInMs)
bool TestCase::waitUntilProjectIsFullyOpened(Project *project, int timeOutInMs)
{
if (!project)
return false;
QElapsedTimer t;
t.start();
CppModelManager *modelManager = CppModelManager::instance();
forever {
if (modelManager->projectInfo(project).isValid())
return true;
if (t.elapsed() > timeOutInMs)
return false;
QCoreApplication::processEvents();
}
return QTest::qWaitFor(
[project]() {
return !project->isParsing()
&& CppModelManager::instance()->projectInfo(project).isValid();
},
timeOutInMs);
}
bool TestCase::writeFile(const QString &filePath, const QByteArray &contents)
@@ -293,7 +288,7 @@ ProjectInfo ProjectOpenerAndCloser::open(const QString &projectFile, bool config
if (configureAsExampleProject)
project->configureAsExampleProject();
if (TestCase::waitUntilCppModelManagerIsAwareOf(project)) {
if (TestCase::waitUntilProjectIsFullyOpened(project)) {
m_openProjects.append(project);
return CppModelManager::instance()->projectInfo(project);
}

View File

@@ -92,9 +92,8 @@ public:
static bool waitForProcessedEditorDocument(const QString &filePath, int timeOutInMs = 5000);
enum { defaultTimeOutInMs = 30 * 1000 /*= 30 secs*/ };
static bool waitUntilCppModelManagerIsAwareOf(
ProjectExplorer::Project *project,
int timeOutInMs = defaultTimeOutInMs);
static bool waitUntilProjectIsFullyOpened(ProjectExplorer::Project *project,
int timeOutInMs = defaultTimeOutInMs);
static CPlusPlus::Document::Ptr waitForFileInGlobalSnapshot(
const QString &filePath,
int timeOutInMs = defaultTimeOutInMs);