Files
qt-creator/tests/unit/unittest/pchcreator-test.cpp
Marco Bubke 80d25cdebd CppRefactoring: Disable failing tests
Has to fixed later or removed completely.

Change-Id: I3a62b4ecde60f6877164e994e664f7b015b9d3fc
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
2020-10-28 11:33:29 +00:00

441 lines
18 KiB
C++

/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "googletest.h"
#include "fakeprocess.h"
#include "filesystem-utilities.h"
#include "testenvironment.h"
#include "mockbuilddependenciesstorage.h"
#include "mockclangpathwatcher.h"
#include "mockpchmanagerclient.h"
#include "testenvironment.h"
#include <filepathcaching.h>
#include <generatedfiles.h>
#include <pchcreator.h>
#include <precompiledheadersupdatedmessage.h>
#include <progressmessage.h>
#include <refactoringdatabaseinitializer.h>
#include <updateprojectpartsmessage.h>
#include <sqlitedatabase.h>
#include <QFileInfo>
namespace {
using ClangBackEnd::FilePath;
using ClangBackEnd::FilePathId;
using ClangBackEnd::FilePathIds;
using ClangBackEnd::FilePathView;
using ClangBackEnd::GeneratedFiles;
using ClangBackEnd::IdPaths;
using ClangBackEnd::IncludeSearchPathType;
using ClangBackEnd::PchTask;
using ClangBackEnd::PrecompiledHeadersUpdatedMessage;
using ClangBackEnd::ProjectChunkId;
using ClangBackEnd::ProjectPartContainer;
using ClangBackEnd::ProjectPartPch;
using ClangBackEnd::SourceEntries;
using ClangBackEnd::SourceEntry;
using ClangBackEnd::SourceType;
using ClangBackEnd::V2::FileContainer;
using Utils::PathString;
using Utils::SmallString;
using UnitTests::EndsWith;
MATCHER_P2(HasIdAndType,
sourceId,
sourceType,
std::string(negation ? "hasn't" : "has")
+ PrintToString(ClangBackEnd::SourceEntry(sourceId, sourceType, -1)))
{
const ClangBackEnd::SourceEntry &entry = arg;
return entry.sourceId == sourceId && entry.sourceType == sourceType;
}
class PchCreator: public ::testing::Test
{
protected:
PchCreator()
{
creator.setUnsavedFiles({generatedFile});
pchTask1.preIncludeSearchPath = testEnvironment.preIncludeSearchPath();
}
ClangBackEnd::FilePathId id(ClangBackEnd::FilePathView path)
{
return filePathCache.filePathId(path);
}
FilePathIds sorted(FilePathIds &&filePathIds)
{
std::sort(filePathIds.begin(), filePathIds.end());
return std::move(filePathIds);
}
protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
FilePath main1Path = TESTDATA_DIR "/builddependencycollector/project/main3.cpp";
FilePath main2Path = TESTDATA_DIR "/builddependencycollector/project/main2.cpp";
FilePath header1Path = TESTDATA_DIR "/builddependencycollector/project/header1.h";
FilePath header2Path = TESTDATA_DIR "/builddependencycollector/project/header2.h";
FilePath generatedFilePath = TESTDATA_DIR "/builddependencycollector/project/generated_file.h";
TestEnvironment environment;
FileContainer generatedFile{generatedFilePath.clone(), id(generatedFilePath), "#pragma once", {}};
NiceMock<MockPchManagerClient> mockPchManagerClient;
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage;
ClangBackEnd::PchCreator creator{environment,
filePathCache,
mockPchManagerClient,
mockClangPathWatcher,
mockBuildDependenciesStorage};
PchTask pchTask1{
1,
sorted({id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")}),
sorted({id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
id(TESTDATA_DIR "/builddependencycollector/system/system2.h"),
id(generatedFilePath)}),
sorted({id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
id(generatedFilePath)}),
sorted({id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
id(generatedFilePath)}),
sorted({id(main2Path), id(generatedFilePath)}),
{},
{},
{{TESTDATA_DIR "/builddependencycollector/system", 2, IncludeSearchPathType::BuiltIn},
{TESTDATA_DIR "/builddependencycollector/external", 1, IncludeSearchPathType::System}},
{{TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User}},
};
TestEnvironment testEnvironment;
};
using PchCreatorSlowTest = PchCreator;
using PchCreatorVerySlowTest = PchCreator;
TEST_F(PchCreator, CreateProjectPartPchFileContent)
{
auto content = creator.generatePchIncludeFileContent(pchTask1.includes);
ASSERT_THAT(std::string(content),
AllOf(HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/project/header2.h\"\n"),
HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external1.h\"\n"),
HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external2.h\"\n")));
}
TEST_F(PchCreator, CreateProjectPartClangCompilerArguments)
{
auto arguments = creator.generateClangCompilerArguments(std::move(pchTask1), "project.pch");
ASSERT_THAT(arguments,
ElementsAre("clang++",
"-w",
"-DNOMINMAX",
"-x",
"c++-header",
"-std=c++98",
"-nostdinc",
"-nostdinc++",
"-isystem",
toNativePath(TESTDATA_DIR "/preincludes"),
"-I",
toNativePath(TESTDATA_DIR "/builddependencycollector/project"),
"-isystem",
toNativePath(TESTDATA_DIR "/builddependencycollector/external"),
"-isystem",
toNativePath(TESTDATA_DIR "/builddependencycollector/system"),
"-o",
"project.pch"));
}
TEST_F(PchCreator, CreateProjectPartClangCompilerArgumentsWithSystemPch)
{
pchTask1.systemPchPath = "system.pch";
auto arguments = creator.generateClangCompilerArguments(std::move(pchTask1), "project.pch");
ASSERT_THAT(arguments,
ElementsAre("clang++",
"-w",
"-DNOMINMAX",
"-x",
"c++-header",
"-std=c++98",
"-nostdinc",
"-nostdinc++",
"-isystem",
toNativePath(TESTDATA_DIR "/preincludes"),
"-I",
toNativePath(TESTDATA_DIR "/builddependencycollector/project"),
"-isystem",
toNativePath(TESTDATA_DIR "/builddependencycollector/external"),
"-isystem",
toNativePath(TESTDATA_DIR "/builddependencycollector/system"),
"-Xclang",
"-include-pch",
"-Xclang",
"system.pch",
"-o",
"project.pch"));
}
TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient)
{
creator.generatePch(std::move(pchTask1));
EXPECT_CALL(mockPchManagerClient,
precompiledHeadersUpdated(
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds,
ElementsAre(Eq(creator.projectPartPch().projectPartId)))));
creator.doInMainThreadAfterFinished();
}
TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterSucess)
{
creator.generatePch(std::move(pchTask1));
EXPECT_CALL(
mockClangPathWatcher,
updateIdPaths(UnorderedElementsAre(
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
Field(&ClangBackEnd::IdPaths::filePathIds, UnorderedElementsAre(id(main2Path)))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
creator.doInMainThreadAfterFinished();
}
TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterFail)
{
pchTask1.systemIncludeSearchPaths = {};
pchTask1.projectIncludeSearchPaths = {};
creator.generatePch(std::move(pchTask1));
EXPECT_CALL(
mockClangPathWatcher,
updateIdPaths(UnorderedElementsAre(
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
Field(&ClangBackEnd::IdPaths::filePathIds, UnorderedElementsAre(id(main2Path)))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
creator.doInMainThreadAfterFinished();
}
TEST_F(PchCreatorVerySlowTest, PchCreationTimeStampsAreUpdated)
{
creator.generatePch(std::move(pchTask1));
EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(_, Eq(1)));
creator.doInMainThreadAfterFinished();
}
TEST_F(PchCreator, DoNothingInTheMainThreadIfGenerateWasNotCalled)
{
EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(_, _)).Times(0);
EXPECT_CALL(mockClangPathWatcher, updateIdPaths(_)).Times(0);
EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(_)).Times(0);
creator.doInMainThreadAfterFinished();
}
TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForPchTask)
{
creator.generatePch(std::move(pchTask1));
ASSERT_THAT(creator.projectPartPch(),
AllOf(Field(&ProjectPartPch::projectPartId, Eq(1)),
Field(&ProjectPartPch::pchPath, Not(IsEmpty())),
Field(&ProjectPartPch::lastModified, Not(Eq(-1)))));
}
TEST_F(PchCreatorVerySlowTest, ProjectPartPchCleared)
{
creator.generatePch(std::move(pchTask1));
creator.clear();
ASSERT_FALSE(creator.projectPartPch().isValid());
}
TEST_F(PchCreatorVerySlowTest, WatchedSystemIncludesCleared)
{
creator.generatePch(std::move(pchTask1));
creator.clear();
ASSERT_THAT(creator.watchedSystemIncludes(), IsEmpty());
}
TEST_F(PchCreatorVerySlowTest, WatchedProjectIncludesCleared)
{
creator.generatePch(std::move(pchTask1));
creator.clear();
ASSERT_THAT(creator.watchedProjectIncludes(), IsEmpty());
}
TEST_F(PchCreatorVerySlowTest, WatchedUserIncludesCleared)
{
creator.generatePch(std::move(pchTask1));
creator.clear();
ASSERT_THAT(creator.watchedUserIncludes(), IsEmpty());
}
TEST_F(PchCreatorVerySlowTest, WatchedSourcesCleared)
{
creator.generatePch(std::move(pchTask1));
creator.clear();
ASSERT_THAT(creator.watchedSources(), IsEmpty());
}
TEST_F(PchCreatorVerySlowTest, ClangToolCleared)
{
creator.generatePch(std::move(pchTask1));
creator.clear();
ASSERT_TRUE(creator.clangTool().isClean());
}
TEST_F(PchCreatorVerySlowTest, DISABLED_FaultyProjectPartPchForCreatesFaultyPchForPchTask)
{
PchTask faultyPchTask{
0,
{id(TESTDATA_DIR "/builddependencycollector/project/faulty.cpp")},
{},
{},
{},
{},
{{"DEFINE", "1", 1}},
{},
{{TESTDATA_DIR "/builddependencycollector/external", 1, IncludeSearchPathType::System}},
{{TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User}}};
creator.generatePch(std::move(faultyPchTask));
ASSERT_THAT(creator.projectPartPch(),
AllOf(Field(&ProjectPartPch::projectPartId, Eq(0)),
Field(&ProjectPartPch::pchPath, IsEmpty()),
Field(&ProjectPartPch::lastModified, Gt(0))));
}
TEST_F(PchCreatorSlowTest, NoIncludes)
{
pchTask1.includes = {};
creator.generatePch(std::move(pchTask1));
ASSERT_THAT(creator.projectPartPch(),
AllOf(Field(&ProjectPartPch::projectPartId, Eq(pchTask1.projectPartId())),
Field(&ProjectPartPch::pchPath, IsEmpty()),
Field(&ProjectPartPch::lastModified, Gt(0))));
}
TEST_F(PchCreatorSlowTest, NoIncludesInTheMainThreadCalls)
{
pchTask1.includes = {};
creator.generatePch(std::move(pchTask1));
EXPECT_CALL(mockPchManagerClient,
precompiledHeadersUpdated(
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds,
ElementsAre(Eq(creator.projectPartPch().projectPartId)))));
EXPECT_CALL(
mockClangPathWatcher,
updateIdPaths(UnorderedElementsAre(
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
Field(&ClangBackEnd::IdPaths::filePathIds, UnorderedElementsAre(id(main2Path)))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(Gt(0), Eq(1)));
creator.doInMainThreadAfterFinished();
}
TEST_F(PchCreatorVerySlowTest, GeneratedFile)
{
creator.clear();
creator.setUnsavedFiles({generatedFile});
ASSERT_FALSE(creator.clangTool().isClean());
}
}