Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to launch a UTBot on open source projects (libbpf and curl) #575

Merged
merged 7 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions server/proto/testgen.proto
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ message ProjectContext {
string projectPath = 2;
string testDirPath = 3;
string buildDirRelativePath = 4;
string clientProjectPath = 5;
}

enum ErrorMode {
Expand Down
12 changes: 8 additions & 4 deletions server/src/ProjectContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,26 @@ namespace utbot {
ProjectContext::ProjectContext(std::string projectName,
fs::path projectPath,
fs::path testDirPath,
fs::path buildDirRelativePath)
fs::path buildDirRelativePath,
fs::path clientProjectPath)
: projectName(std::move(projectName)), projectPath(std::move(projectPath)),
testDirPath(std::move(testDirPath)),
buildDirRelativePath(std::move(buildDirRelativePath)) {}
buildDirRelativePath(std::move(buildDirRelativePath)),
clientProjectPath(clientProjectPath) {}

ProjectContext::ProjectContext(const testsgen::ProjectContext &projectContext)
: ProjectContext(projectContext.projectname(),
projectContext.projectpath(),
projectContext.testdirpath(),
projectContext.builddirrelativepath()) {}
projectContext.builddirrelativepath(),
projectContext.clientprojectpath()) {}

ProjectContext::ProjectContext(const testsgen::SnippetRequest &request, fs::path serverBuildDir)
: projectName(request.projectcontext().projectname()),
projectPath(request.projectcontext().projectpath()),
testDirPath(request.projectcontext().testdirpath()),
buildDirRelativePath(request.projectcontext().builddirrelativepath()) { }
buildDirRelativePath(request.projectcontext().builddirrelativepath()),
clientProjectPath(request.projectcontext().clientprojectpath()) {}

fs::path ProjectContext::buildDir() const {
return projectPath / buildDirRelativePath;
Expand Down
4 changes: 3 additions & 1 deletion server/src/ProjectContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class ProjectContext {
ProjectContext(std::string projectName,
fs::path projectPath,
fs::path testDirPath,
fs::path buildDirRelativePath);
fs::path buildDirRelativePath,
fs::path serverBuildDir);

explicit ProjectContext(const testsgen::ProjectContext &projectContext);

Expand All @@ -28,6 +29,7 @@ class ProjectContext {
const fs::path projectPath;
const fs::path testDirPath;
const fs::path buildDirRelativePath;
const fs::path clientProjectPath;
};
}

Expand Down
12 changes: 10 additions & 2 deletions server/src/Synchronizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ bool Synchronizer::isProbablyOutdatedStubs(const fs::path &srcFilePath) const {
} catch (...) {
return true;
}
srcTimestamp = Synchronizer::getFileOutdatedTime(srcFilePath);
if (!fs::exists(srcFilePath)) {
srcTimestamp = time(nullptr);
} else {
srcTimestamp = Synchronizer::getFileOutdatedTime(srcFilePath);
}
return stubTimestamp <= srcTimestamp;
}

Expand All @@ -75,7 +79,11 @@ bool Synchronizer::isProbablyOutdatedWrappers(const fs::path &srcFilePath) const
}
long long wrapperTimestamp, srcTimestamp;
wrapperTimestamp = Synchronizer::getFileOutdatedTime(wrapperFilePath);
srcTimestamp = Synchronizer::getFileOutdatedTime(srcFilePath);
if (!fs::exists(srcFilePath)) {
srcTimestamp = time(nullptr);
} else {
srcTimestamp = Synchronizer::getFileOutdatedTime(srcFilePath);
}
return wrapperTimestamp <= srcTimestamp;
}

Expand Down
1 change: 0 additions & 1 deletion server/src/building/CompileCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,5 @@ namespace utbot {
auto path = Paths::getCCJsonFileFullPath(Paths::replaceExtension(*this->sourcePath, ".o"), this->directory);
this->output = std::next(addFlagsToBegin({"-o", path}));
}

}
}
15 changes: 11 additions & 4 deletions server/src/building/ProjectBuildDatabse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,19 @@ void ProjectBuildDatabase::initInfo(const nlohmann::json &linkCommandsJson) {
}
targetInfo->addFile(currentFile);
if (Paths::isObjectFile(currentFile)) {
if (!CollectionUtils::containsKey(objectFileInfos, currentFile)) {
if (!CollectionUtils::containsKey(objectFileInfos, currentFile) &&
!CollectionUtils::containsKey(objectFileInfos,
relative(currentFile, directory))) {
throw CompilationDatabaseException(
"compile_commands.json doesn't contain a command for object file "
+ currentFile.string());
"compile_commands.json doesn't contain a command for object file " +
currentFile.string());
}
if (CollectionUtils::containsKey(objectFileInfos, currentFile)) {
objectFileInfos[currentFile]->linkUnit = output;
} else if (CollectionUtils::containsKey(objectFileInfos,
relative(currentFile, directory))) {
objectFileInfos[relative(currentFile, directory)]->linkUnit = output;
}
objectFileInfos[currentFile]->linkUnit = output;
}
}
targetInfo->commands.emplace_back(command);
Expand Down
7 changes: 4 additions & 3 deletions server/src/coverage/TestRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,10 @@ std::vector<UnitTest> TestRunner::getTestsToLaunch() {
}
} else {
if (!StringUtils::endsWith(testFilePath.c_str(), "_test.h") &&
!StringUtils::endsWith(testFilePath.stem().c_str(), "_stub")) {
LOG_S(WARNING)
<< "Found extra file in test directory: " << testFilePath;
!StringUtils::endsWith(testFilePath.stem().c_str(), "_stub") &&
!StringUtils::endsWith(testFilePath.c_str(), "_wrapper.c") &&
!StringUtils::endsWith(testFilePath.c_str(), ".mk")) {
LOG_S(WARNING) << "Found extra file in test directory: " << testFilePath;
}
}
});
Expand Down
33 changes: 14 additions & 19 deletions server/src/utils/CompilationUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,16 @@ namespace CompilationUtils {
}
}

void substituteRemotePathToCCJsonForFile(const fs::path &projectPath,
const std::string &buildDirRelativePath,
const std::string &jsonFileName,
const fs::path &newJsonDir) {
fs::path compileCommandsJsonPath = projectPath / buildDirRelativePath / jsonFileName;
fs::create_directories(newJsonDir);
void substituteRemotePathToCCJsonForFile(const utbot::ProjectContext &projectContext,
const std::string &jsonFileName) {
fs::path compileCommandsJsonPath = projectContext.buildDir() / jsonFileName;
fs::create_directories(Paths::getUTBotBuildDir(projectContext));
if (!fs::exists(compileCommandsJsonPath)) {
throw CompilationDatabaseException("Can't find " + compileCommandsJsonPath.string());
}
std::ifstream ifs(compileCommandsJsonPath);
json json = json::parse(ifs);
std::string projectPathStr = Paths::normalizedTrimmed(fs::absolute(projectPath)).string();
std::string projectPathStr = Paths::normalizedTrimmed(fs::absolute(projectContext.projectPath)).string();
Paths::removeBackTrailedSlash(projectPathStr);

const std::string directoryFieldName = "directory";
Expand All @@ -79,8 +77,7 @@ namespace CompilationUtils {

for (auto &cmd : json) {
std::string directoryField = cmd[directoryFieldName];
std::string userSystemProjectPath =
Paths::subtractPath(directoryField, buildDirRelativePath);
std::string userSystemProjectPath = Paths::normalizedTrimmed(projectContext.clientProjectPath);
Paths::removeBackTrailedSlash(userSystemProjectPath);

if (cmd.contains(commandFieldName)) {
Expand All @@ -106,25 +103,23 @@ namespace CompilationUtils {
} else {
for (auto &currentFile : cmd[filesFieldName]) {
std::string currentFileField = currentFile;
StringUtils::replaceAll(currentFileField, userSystemProjectPath,
projectPathStr);
StringUtils::replaceAll(currentFileField, userSystemProjectPath, projectPathStr);
currentFile = currentFileField;
}
}
}
fs::path newJsonPath = newJsonDir / jsonFileName;
fs::path newJsonPath = Paths::getUTBotBuildDir(projectContext) / jsonFileName;
JsonUtils::writeJsonToFile(newJsonPath, json);
LOG_S(DEBUG) << jsonFileName << " for mount is written to: " << newJsonDir;
LOG_S(DEBUG) << jsonFileName << " for mount is written to: " << newJsonPath;
}

fs::path substituteRemotePathToCompileCommandsJsonPath(const utbot::ProjectContext &projectContext) {
const std::string ccJsonFileName = "compile_commands.json";
fs::path utbotBuildDir = Paths::getUTBotBuildDir(projectContext);
substituteRemotePathToCCJsonForFile(projectContext.projectPath, projectContext.buildDirRelativePath,
ccJsonFileName, utbotBuildDir);
substituteRemotePathToCCJsonForFile(projectContext.projectPath, projectContext.buildDirRelativePath,
"link_commands.json", utbotBuildDir);
return utbotBuildDir;
const std::string lcJsonFileName = "link_commands.json";

substituteRemotePathToCCJsonForFile(projectContext, ccJsonFileName);
substituteRemotePathToCCJsonForFile(projectContext, lcJsonFileName);
return Paths::getUTBotBuildDir(projectContext);
}

fs::path getClangCompileCommandsJsonPath(const fs::path &buildCommandsJsonPath) {
Expand Down
3 changes: 3 additions & 0 deletions server/src/utils/StringUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ namespace StringUtils {
}

void replaceAll(std::string &str, const std::string &from, const std::string &to) {
if (from.empty()) {
return;
}
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
Expand Down
26 changes: 16 additions & 10 deletions server/src/visitors/ParametrizedAssertsVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,25 @@ namespace visitor {
auto returnType = methodDescription.returnType.maybeReturnArray()
? methodDescription.returnType.arrayClone(usage, pointerSize)
: methodDescription.returnType;

functionCall = printer->constrVisitorFunctionCall(methodDescription, testCase, false, errorMode);
if (testCase.returnValue.view->getEntryValue(nullptr) == PrinterUtils::C_NULL) {
additionalPointersCount = methodDescription.returnType.countReturnPointers(true);
printer->writeCodeLine(
StringUtils::stringFormat("EXPECT_TRUE(%s)",
PrinterUtils::getEqualString(functionCall, PrinterUtils::C_NULL)));
return;
if (!types::TypesHandler::skipTypeInReturn(methodDescription.returnType) && !testCase.isError()) {
if (testCase.returnValue.view->getEntryValue(nullptr) == PrinterUtils::C_NULL) {
additionalPointersCount = methodDescription.returnType.countReturnPointers(true);
printer->writeCodeLine(
StringUtils::stringFormat("EXPECT_TRUE(%s)",
PrinterUtils::getEqualString(functionCall, PrinterUtils::C_NULL)));
return;
} else {
additionalPointersCount = 0;
visitAny(returnType, "", testCase.returnValue.view.get(), PrinterUtils::DEFAULT_ACCESS, 0);
functionCall = {};
additionalPointersCount = 0;
}
} else {
additionalPointersCount = 0;
printer->writeCodeLine(functionCall);
return;
}
visitAny(returnType, "", testCase.returnValue.view.get(), PrinterUtils::DEFAULT_ACCESS, 0);
functionCall = {};
additionalPointersCount = 0;
}

void ParametrizedAssertsVisitor::visitArray(const types::Type &type,
Expand Down
1 change: 1 addition & 0 deletions server/test/framework/BaseTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class BaseTest : public testing::Test {

CompilerName compilerName = CompilerName::CLANG;
std::string buildDirRelativePath;
std::string clientProjectPath = "";
fs::path buildPath;
std::vector<fs::path> srcPaths;

Expand Down
20 changes: 10 additions & 10 deletions server/test/framework/Server_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1204,7 +1204,7 @@ namespace {

testDirPath = getTestFilePath(pregeneratedTestsRelativeDir);
projectContext = std::make_unique<utbot::ProjectContext>(
projectName, suitePath, testDirPath, buildDirRelativePath);
projectName, suitePath, testDirPath, buildDirRelativePath, clientProjectPath);

basic_functions_c = getTestFilePath("basic_functions.c");
simple_loop_uncovered_c = getTestFilePath("simple_loop_uncovered.c");
Expand Down Expand Up @@ -1500,7 +1500,7 @@ namespace {
testUtils::checkMinNumberOfTests(testGen.tests, 11);

auto projectContext = std::make_unique<utbot::ProjectContext>(projectName, suitePath, suitePath / "tests",
buildDirRelativePath);
buildDirRelativePath, clientProjectPath);
auto testFilter = GrpcUtils::createTestFilterForFile(
Paths::sourcePathToTestPath(*projectContext, methods_with_asserts_cpp));
auto runRequest = createCoverageAndResultsRequest(
Expand Down Expand Up @@ -1548,7 +1548,7 @@ namespace {
testUtils::checkMinNumberOfTests(testGen.tests, 11);

auto projectContext = std::make_unique<utbot::ProjectContext>(projectName, suitePath, suitePath / "tests",
buildDirRelativePath);
buildDirRelativePath, clientProjectPath);
auto testFilter = GrpcUtils::createTestFilterForFile(
Paths::sourcePathToTestPath(*projectContext, methods_with_asserts_cpp));
auto runRequest = createCoverageAndResultsRequest(
Expand Down Expand Up @@ -1594,7 +1594,7 @@ namespace {
testUtils::checkMinNumberOfTests(testGen.tests, 8);

auto projectContext = std::make_unique<utbot::ProjectContext>(projectName, suitePath, suitePath / "tests",
buildDirRelativePath);
buildDirRelativePath, clientProjectPath);
auto testFilter = GrpcUtils::createTestFilterForFile(
Paths::sourcePathToTestPath(*projectContext, methods_with_exceptions_cpp));
auto runRequest = createCoverageAndResultsRequest(
Expand Down Expand Up @@ -1640,7 +1640,7 @@ namespace {
testUtils::checkMinNumberOfTests(testGen.tests, 8);

auto projectContext = std::make_unique<utbot::ProjectContext>(projectName, suitePath, suitePath / "tests",
buildDirRelativePath);
buildDirRelativePath, clientProjectPath);
auto testFilter = GrpcUtils::createTestFilterForFile(
Paths::sourcePathToTestPath(*projectContext, methods_with_exceptions_cpp));
auto runRequest = createCoverageAndResultsRequest(
Expand Down Expand Up @@ -1797,7 +1797,7 @@ namespace {
fs::path testsDirPath = getTestFilePath("tests");

fs::path linked_list_test_cpp = Paths::sourcePathToTestPath(
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath),
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath),
linked_list_c);
auto testFilter = GrpcUtils::createTestFilterForFile(linked_list_test_cpp);
auto runRequest = testUtils::createCoverageAndResultsRequest(
Expand Down Expand Up @@ -1835,7 +1835,7 @@ namespace {
fs::path testsDirPath = getTestFilePath("tests");

fs::path tree_test_cpp = Paths::sourcePathToTestPath(
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath),
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath),
tree_c);
auto testFilter = GrpcUtils::createTestFilterForFile(tree_test_cpp);
auto runRequest = testUtils::createCoverageAndResultsRequest(
Expand Down Expand Up @@ -1877,7 +1877,7 @@ namespace {
fs::path testsDirPath = getTestFilePath("tests");

fs::path input_output_test_cpp = Paths::sourcePathToTestPath(
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath),
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath),
input_output_c);
auto testFilter = GrpcUtils::createTestFilterForFile(input_output_test_cpp);
auto runRequest = testUtils::createCoverageAndResultsRequest(
Expand Down Expand Up @@ -1916,7 +1916,7 @@ namespace {
fs::path testsDirPath = getTestFilePath("tests");

fs::path file_test_cpp = Paths::sourcePathToTestPath(
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath),
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath),
file_c);
auto testFilter = GrpcUtils::createTestFilterForFile(file_test_cpp);
auto runRequest = testUtils::createCoverageAndResultsRequest(
Expand Down Expand Up @@ -1954,7 +1954,7 @@ namespace {
fs::path testsDirPath = getTestFilePath("tests");

fs::path hard_linked_list_test_cpp = Paths::sourcePathToTestPath(
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath),
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath),
hard_linked_list_c);
auto testFilter = GrpcUtils::createTestFilterForFile(hard_linked_list_test_cpp);
auto runRequest = testUtils::createCoverageAndResultsRequest(
Expand Down
5 changes: 3 additions & 2 deletions server/test/framework/Stub_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace {

fs::path testsDirPath = getTestFilePath("tests");
utbot::ProjectContext projectContext{ projectName, suitePath, testsDirPath,
buildDirRelativePath };
buildDirRelativePath, clientProjectPath };
fs::path sum_test_cpp =
Paths::sourcePathToTestPath(projectContext, calc_sum_c);

Expand Down Expand Up @@ -319,7 +319,8 @@ namespace {
fs::path testsDirPath = getTestFilePath("tests");

fs::path function_pointers_test_cpp = Paths::sourcePathToTestPath(
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath), function_pointers_c);
utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath),
function_pointers_c);
auto testFilter = GrpcUtils::createTestFilterForFile(function_pointers_test_cpp);
auto runRequest = testUtils::createCoverageAndResultsRequest(
projectName, suitePath, testsDirPath, buildDirRelativePath, std::move(testFilter));
Expand Down
Loading