Skip to content

Commit

Permalink
Changes to launch a UTBot on open source projects (libbpf and curl) (#…
Browse files Browse the repository at this point in the history
…575)

* Changes for running UTbotCpp on libbpf and curl projects.
* Skip searching update time of non-existing files.
* Don't create return value for ERROR suite
* Fix substitute remote path
* Fix warning

---------

Co-authored-by: Vladislav Kalugin <[email protected]>
  • Loading branch information
kichunya and Vladislav Kalugin authored Feb 14, 2023
1 parent 1bb82af commit 93401ae
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 56 deletions.
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

0 comments on commit 93401ae

Please sign in to comment.