Commit 9b41023b authored by Nikolai Kosjar's avatar Nikolai Kosjar Committed by Erik Verbruggen

CppEditor/CppTools: Tests: Fix potential race condition

...when updating the code model.

Change-Id: Ifc55b7d0bb795b9cfd72465990991bc2cc907846
Reviewed-by: default avatarChristian Stenger <christian.stenger@digia.com>
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@digia.com>
parent dad01401
......@@ -86,16 +86,14 @@ TestCase::TestCase(const QByteArray &input)
Utils::FileSaver srcSaver(fileName);
srcSaver.write(originalText);
srcSaver.finalize();
CppTools::CppModelManagerInterface::instance()->updateSourceFiles(QStringList()<<fileName);
// Wait for the parser in the future to give us the document
while (true) {
Snapshot s = CppTools::CppModelManagerInterface::instance()->snapshot();
if (s.contains(fileName))
break;
QCoreApplication::processEvents();
}
// Update Code Model
CppTools::CppModelManagerInterface *mmi = CppTools::CppModelManagerInterface::instance();
mmi->updateSourceFiles(QStringList(fileName)).waitForFinished();
QCoreApplication::processEvents();
QVERIFY(mmi->snapshot().contains(fileName));
// Open Editor
editor = dynamic_cast<CPPEditor *>(EditorManager::openEditor(fileName));
QVERIFY(editor);
editorWidget = dynamic_cast<CPPEditorWidget *>(editor->editorWidget());
......
......@@ -67,20 +67,12 @@ public:
}
// Update Code Model
m_cmm->updateSourceFiles(filePaths);
// Wait for the parser in the future to give us the document
QStringList filePathsNotYetInSnapshot(filePaths);
forever {
const Snapshot snapshot = m_cmm->snapshot();
foreach (const QString &filePath, filePathsNotYetInSnapshot) {
if (snapshot.contains(filePath))
filePathsNotYetInSnapshot.removeOne(filePath);
}
if (filePathsNotYetInSnapshot.isEmpty())
break;
QCoreApplication::processEvents();
}
m_cmm->updateSourceFiles(filePaths).waitForFinished();
QCoreApplication::processEvents();
const Snapshot snapshot = m_cmm->snapshot();
QVERIFY(!snapshot.isEmpty());
foreach (const QString &filePath, filePaths)
QVERIFY(snapshot.contains(filePath));
}
~TestCase()
......
......@@ -209,20 +209,12 @@ void TestCase::init(const QStringList &includePaths)
QStringList filePaths;
foreach (const TestDocumentPtr &testFile, testFiles)
filePaths << testFile->filePath();
cmm->updateSourceFiles(filePaths);
// Wait for the parser in the future to give us the document
QStringList filePathsNotYetInSnapshot(filePaths);
forever {
Snapshot snapshot = cmm->snapshot();
foreach (const QString &filePath, filePathsNotYetInSnapshot) {
if (snapshot.contains(filePath))
filePathsNotYetInSnapshot.removeOne(filePath);
}
if (filePathsNotYetInSnapshot.isEmpty())
break;
QCoreApplication::processEvents();
}
cmm->updateSourceFiles(filePaths).waitForFinished();
QCoreApplication::processEvents();
const Snapshot snapshot = cmm->snapshot();
QVERIFY(!snapshot.isEmpty());
foreach (const QString &filePath, filePaths)
QVERIFY(snapshot.contains(filePath));
// Open Files
foreach (TestDocumentPtr testFile, testFiles) {
......
......@@ -309,21 +309,13 @@ void TestCase::init()
QStringList filePaths;
foreach (const TestDocumentPtr &testFile, m_testFiles)
filePaths << testFile->filePath();
CppTools::CppModelManagerInterface::instance()->updateSourceFiles(filePaths);
// Wait for the indexer to process all files.
// All these files are "Fast Checked", that is the function bodies are not processed.
QStringList filePathsNotYetInSnapshot(filePaths);
forever {
Snapshot snapshot = CppTools::CppModelManagerInterface::instance()->snapshot();
foreach (const QString &filePath, filePathsNotYetInSnapshot) {
if (snapshot.contains(filePath))
filePathsNotYetInSnapshot.removeOne(filePath);
}
if (filePathsNotYetInSnapshot.isEmpty())
break;
QCoreApplication::processEvents();
}
CppModelManagerInterface *mmi = CppTools::CppModelManagerInterface::instance();
mmi->updateSourceFiles(filePaths).waitForFinished();
QCoreApplication::processEvents();
const Snapshot snapshot = mmi->snapshot();
QVERIFY(!snapshot.isEmpty());
foreach (const QString &filePath, filePaths)
QVERIFY(snapshot.contains(filePath));
// Open Files
foreach (TestDocumentPtr testFile, m_testFiles) {
......
......@@ -82,8 +82,8 @@ private:
virtual void doBeforeLocatorRun()
{
m_modelManager->updateSourceFiles(QStringList() << m_fileName).waitForFinished();
QVERIFY(m_modelManager->snapshot().contains(m_fileName));
QCoreApplication::processEvents();
QVERIFY(m_modelManager->snapshot().contains(m_fileName));
}
virtual void doAfterLocatorRun()
......
......@@ -200,6 +200,15 @@ private:
const QString &m_filePath;
};
static QStringList updateProjectInfo(CppModelManager *modelManager, ModelManagerTestHelper *helper,
const ProjectInfo &projectInfo)
{
helper->resetRefreshedSourceFiles();
modelManager->updateProjectInfo(projectInfo).waitForFinished();
QCoreApplication::processEvents();
return helper->waitForRefreshedSourceFiles();
}
} // anonymous namespace
/// Check: The preprocessor cleans include and framework paths.
......@@ -304,10 +313,8 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files()
part->includePaths = QStringList() << testDataDir.includeDir(false);
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
pi.appendProjectPart(part);
mm->updateProjectInfo(pi);
QStringList refreshedFiles = helper.waitForRefreshedSourceFiles();
QStringList refreshedFiles = updateProjectInfo(mm, &helper, pi);
QCOMPARE(refreshedFiles.size(), 1);
QVERIFY(refreshedFiles.contains(testCpp));
CPlusPlus::Snapshot snapshot = mm->snapshot();
......@@ -323,9 +330,8 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files()
part->projectDefines = QByteArray("#define TEST_DEFINE 1\n");
pi.clearProjectParts();
pi.appendProjectPart(part);
mm->updateProjectInfo(pi);
refreshedFiles = helper.waitForRefreshedSourceFiles();
refreshedFiles = updateProjectInfo(mm, &helper, pi);
QCOMPARE(refreshedFiles.size(), 1);
QVERIFY(refreshedFiles.contains(testCpp));
......@@ -385,11 +391,9 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times()
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
pi.appendProjectPart(part);
mm->updateProjectInfo(pi);
refreshedFiles = helper.waitForRefreshedSourceFiles();
refreshedFiles = updateProjectInfo(mm, &helper, pi);
QCOMPARE(refreshedFiles.size(), 3);
QVERIFY(refreshedFiles.contains(testHeader1));
QVERIFY(refreshedFiles.contains(testHeader2));
QVERIFY(refreshedFiles.contains(testCpp));
......@@ -432,8 +436,10 @@ void CppToolsPlugin::test_modelmanager_refresh_test_for_changes()
pi.appendProjectPart(part);
// Reindexing triggers a reparsing thread
helper.resetRefreshedSourceFiles();
QFuture<void> firstFuture = mm->updateProjectInfo(pi);
QVERIFY(firstFuture.isStarted() || firstFuture.isRunning());
firstFuture.waitForFinished();
const QStringList refreshedFiles = helper.waitForRefreshedSourceFiles();
QCOMPARE(refreshedFiles.size(), 1);
QVERIFY(refreshedFiles.contains(testCpp));
......@@ -470,8 +476,7 @@ void CppToolsPlugin::test_modelmanager_refresh_added_and_purge_removed()
CPlusPlus::Snapshot snapshot;
QStringList refreshedFiles;
mm->updateProjectInfo(pi);
refreshedFiles = helper.waitForRefreshedSourceFiles();
refreshedFiles = updateProjectInfo(mm, &helper, pi);
QCOMPARE(refreshedFiles.size(), 2);
QVERIFY(refreshedFiles.contains(testHeader1));
......@@ -490,8 +495,7 @@ void CppToolsPlugin::test_modelmanager_refresh_added_and_purge_removed()
newPart->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader));
pi.appendProjectPart(newPart);
mm->updateProjectInfo(pi);
refreshedFiles = helper.waitForRefreshedSourceFiles();
refreshedFiles = updateProjectInfo(mm, &helper, pi);
// Only the added project file was reparsed
QCOMPARE(refreshedFiles.size(), 1);
......@@ -530,8 +534,7 @@ void CppToolsPlugin::test_modelmanager_refresh_timeStampModified_if_sourcefiles_
CPlusPlus::Snapshot snapshot;
QStringList refreshedFiles;
mm->updateProjectInfo(pi);
refreshedFiles = helper.waitForRefreshedSourceFiles();
refreshedFiles = updateProjectInfo(mm, &helper, pi);
QCOMPARE(refreshedFiles.size(), initialProjectFiles.size());
snapshot = mm->snapshot();
......@@ -560,8 +563,7 @@ void CppToolsPlugin::test_modelmanager_refresh_timeStampModified_if_sourcefiles_
pi.clearProjectParts();
pi.appendProjectPart(part);
mm->updateProjectInfo(pi);
refreshedFiles = helper.waitForRefreshedSourceFiles();
refreshedFiles = updateProjectInfo(mm, &helper, pi);
QCOMPARE(refreshedFiles.size(), finalProjectFiles.size());
snapshot = mm->snapshot();
......@@ -618,8 +620,7 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects()
<< _("foo.cpp")
<< _("main.cpp"));
mm->updateProjectInfo(project1.projectInfo);
refreshedFiles = helper.waitForRefreshedSourceFiles();
refreshedFiles = updateProjectInfo(mm, &helper, project1.projectInfo);
QCOMPARE(refreshedFiles.toSet(), project1.projectFiles.toSet());
const int snapshotSizeAfterProject1 = mm->snapshot().size();
......@@ -633,8 +634,7 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects()
<< _("bar.cpp")
<< _("main.cpp"));
mm->updateProjectInfo(project2.projectInfo);
refreshedFiles = helper.waitForRefreshedSourceFiles();
refreshedFiles = updateProjectInfo(mm, &helper, project2.projectInfo);
QCOMPARE(refreshedFiles.toSet(), project2.projectFiles.toSet());
const int snapshotSizeAfterProject2 = mm->snapshot().size();
......@@ -710,6 +710,7 @@ void CppToolsPlugin::test_modelmanager_gc_if_last_cppeditor_closed()
const QString file = testDataDirectory.file(_("main.cpp"));
CppModelManager *mm = CppModelManager::instance();
helper.resetRefreshedSourceFiles();
// Open a file in the editor
QCOMPARE(Core::EditorManager::documentModel()->openedDocuments().size(), 0);
......@@ -740,6 +741,7 @@ void CppToolsPlugin::test_modelmanager_dont_gc_opened_files()
const QString file = testDataDirectory.file(_("main.cpp"));
CppModelManager *mm = CppModelManager::instance();
helper.resetRefreshedSourceFiles();
// Open a file in the editor
QCOMPARE(Core::EditorManager::documentModel()->openedDocuments().size(), 0);
......@@ -750,6 +752,7 @@ void CppToolsPlugin::test_modelmanager_dont_gc_opened_files()
// Wait until the file is refreshed and check whether it is in the working copy
helper.waitForRefreshedSourceFiles();
QVERIFY(mm->workingCopy().contains(file));
// Run the garbage collector
......@@ -825,10 +828,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
pi.appendProjectPart(part1);
pi.appendProjectPart(part2);
mm->updateProjectInfo(pi);
helper.waitForRefreshedSourceFiles();
updateProjectInfo(mm, &helper, pi);
QCOMPARE(mm->snapshot().size(), 4);
// Open a file in the editor
......@@ -897,10 +897,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch()
pi.appendProjectPart(part1);
pi.appendProjectPart(part2);
mm->updateProjectInfo(pi);
helper.waitForRefreshedSourceFiles();
updateProjectInfo(mm, &helper, pi);
QCOMPARE(mm->snapshot().size(), 4);
// Open a file in the editor
......@@ -968,9 +965,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
pi.appendProjectPart(part1);
pi.appendProjectPart(part2);
mm->updateProjectInfo(pi);
helper.waitForRefreshedSourceFiles();
updateProjectInfo(mm, &helper, pi);
QCOMPARE(mm->snapshot().size(), 4);
......
......@@ -103,10 +103,14 @@ ModelManagerTestHelper::Project *ModelManagerTestHelper::createProject(const QSt
return tp;
}
QStringList ModelManagerTestHelper::waitForRefreshedSourceFiles()
void ModelManagerTestHelper::resetRefreshedSourceFiles()
{
m_lastRefreshedSourceFiles.clear();
m_refreshHappened = false;
}
QStringList ModelManagerTestHelper::waitForRefreshedSourceFiles()
{
while (!m_refreshHappened)
QCoreApplication::processEvents();
......
......@@ -80,6 +80,7 @@ public:
Project *createProject(const QString &name);
void resetRefreshedSourceFiles();
QStringList waitForRefreshedSourceFiles();
void waitForFinishedGc();
......
......@@ -101,12 +101,12 @@ public:
{
QVERIFY(m_indexingSupportToUse);
QVERIFY(m_modelManager->snapshot().isEmpty());
m_modelManager->updateSourceFiles(QStringList() << m_testFile).waitForFinished();
m_modelManager->updateSourceFiles(QStringList(m_testFile)).waitForFinished();
QCoreApplication::processEvents();
QVERIFY(m_modelManager->snapshot().contains(m_testFile));
m_indexingSupportToRestore = m_modelManager->indexingSupport();
m_modelManager->setIndexingSupport(m_indexingSupportToUse);
QCoreApplication::processEvents();
}
ResultDataList run(const SymbolSearcher::Parameters &searchParameters) const
......
......@@ -127,10 +127,13 @@ public:
// Parse files
m_modelManager->updateSourceFiles(filePaths).waitForFinished();
// Get class for which to generate the hierarchy
QCoreApplication::processEvents();
const Snapshot snapshot = m_modelManager->snapshot();
QVERIFY(!snapshot.isEmpty());
foreach (const QString &filePath, filePaths)
QVERIFY(snapshot.contains(filePath));
// Get class for which to generate the hierarchy
const Document::Ptr firstDocument = snapshot.document(filePaths.first());
Class *clazz = FindFirstClassInDocument()(firstDocument);
QVERIFY(clazz);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment