Skip to content

Commit

Permalink
Add initialize and teardown functions call (#675)
Browse files Browse the repository at this point in the history
* Add option to add initial and teardown function calls
  • Loading branch information
ladisgin authored Mar 25, 2024
1 parent 65d919b commit a70416c
Show file tree
Hide file tree
Showing 45 changed files with 470 additions and 280 deletions.
10 changes: 10 additions & 0 deletions integration-tests/c-example/itf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"default init": "",
"default teardown": "",
"init": {
"init_global": "_init_vals"
},
"teardown": {
"init_global": ""
}
}
12 changes: 12 additions & 0 deletions integration-tests/c-example/lib/inits.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
int a;

void _init_vals() {
a = 42;
}

int init_global() {
if(a == 42) {
return 42;
}
return 0;
}
1 change: 1 addition & 0 deletions integration-tests/c-example/lib/inits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bool init_global();
1 change: 1 addition & 0 deletions server/proto/testgen.proto
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ message ProjectContext {
string testDirPath = 3;
string buildDirRelativePath = 4;
string clientProjectPath = 5;
string itfPath = 6;
}

enum ErrorMode {
Expand Down
2 changes: 1 addition & 1 deletion server/src/Paths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ namespace Paths {
return path3;
}

fs::path getCCJsonFileFullPath(const std::string &filename, const fs::path &directory) {
fs::path getFileFullPath(const std::string &filename, const fs::path &directory) {
fs::path path1(filename);
fs::path path2 = fs::weakly_canonical(directory / path1);
return fs::exists(path2) ? path2 : path1;
Expand Down
2 changes: 1 addition & 1 deletion server/src/Paths.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ namespace Paths {
return getBaseLogDir() / "clients.json";
}

fs::path getCCJsonFileFullPath(const std::string &filename, const fs::path &directory);
fs::path getFileFullPath(const std::string &filename, const fs::path &directory);

bool isPath(const std::string &possibleFilePath) noexcept;
//endregion
Expand Down
27 changes: 15 additions & 12 deletions server/src/ProjectContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,28 @@ namespace utbot {
fs::path projectPath,
fs::path testDirPath,
fs::path buildDirRelativePath,
fs::path clientProjectPath)
fs::path clientProjectPath,
fs::path itfPath)
: projectName(std::move(projectName)), projectPath(std::move(projectPath)),
testDirPath(std::move(testDirPath)),
buildDirRelativePath(std::move(buildDirRelativePath)),
clientProjectPath(clientProjectPath) {}
clientProjectPath(std::move(clientProjectPath)),
itfPath(std::move(itfPath)) {
}

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

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()),
clientProjectPath(request.projectcontext().clientprojectpath()) {}
: ProjectContext(request.projectcontext().projectname(), request.projectcontext().projectpath(),
request.projectcontext().testdirpath(), request.projectcontext().builddirrelativepath(),
request.projectcontext().clientprojectpath(),
request.projectcontext().itfpath()) {}

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 @@ -17,7 +17,8 @@ class ProjectContext {
fs::path projectPath,
fs::path testDirPath,
fs::path buildDirRelativePath,
fs::path serverBuildDir);
fs::path serverBuildDir,
fs::path itfPath);

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

Expand All @@ -30,6 +31,7 @@ class ProjectContext {
const fs::path testDirPath;
const fs::path buildDirRelativePath;
const fs::path clientProjectPath;
const fs::path itfPath;
};
}

Expand Down
47 changes: 47 additions & 0 deletions server/src/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "utils/stats/TestsGenerationStats.h"
#include "utils/stats/TestsExecutionStats.h"
#include "utils/TypeUtils.h"
#include "utils/JsonUtils.h"
#include "building/ProjectBuildDatabase.h"

#include <thread>
Expand Down Expand Up @@ -237,6 +238,49 @@ Status Server::TestsGenServiceImpl::ProcessBaseTestRequest(BaseTestGen &testGen,

FeaturesFilter::filter(testGen.settingsContext, typesHandler, testGen.tests);
StubsCollector(typesHandler).collect(testGen.tests);
if (!testGen.projectContext.itfPath.string().empty()) {
try {
fs::path fullFilePath = Paths::getFileFullPath(testGen.projectContext.itfPath,
testGen.projectContext.projectPath);
if (!fs::exists(fullFilePath)) {
std::string message = "File with init and teardown functions, doesn't exists";
LOG_S(ERROR) << message;
throw EnvironmentException(message);
}
LOG_S(INFO) << "Use init and teardown functions from: " << fullFilePath;
nlohmann::json itfJson = JsonUtils::getJsonFromFile(fullFilePath);
auto defaultInitIt = itfJson.find("default init");
std::string defaultInitial = itfJson.value("default init", "");
std::string defaultTeardown = itfJson.value("default teardown", "");

std::optional<nlohmann::json> initJson = std::nullopt;
if (itfJson.contains("init")) {
initJson = itfJson.at("init");
}

std::optional<nlohmann::json> teardownJson = std::nullopt;
if (itfJson.contains("teardown")) {
teardownJson = itfJson.at("teardown");
}
for (tests::TestsMap::iterator it = testGen.tests.begin(); it != testGen.tests.end(); ++it) {
tests::Tests &tests = it.value();
for (tests::Tests::MethodsMap::iterator testsIt = tests.methods.begin();
testsIt != tests.methods.end(); testsIt++) {
const std::string &methodName = testsIt.key();
tests::Tests::MethodDescription &method = testsIt.value();
if (initJson.has_value()) {
method.initFunction = initJson->value(methodName, defaultInitial);
}
if (teardownJson.has_value()) {
method.teardownFunction = teardownJson->value(methodName, defaultTeardown);
}
}
}
} catch (const std::exception &e) {
LOG_S(ERROR) << e.what();
throw EnvironmentException(e.what());
}
}

PathSubstitution pathSubstitution = {};
if (lineTestGen != nullptr) {
Expand Down Expand Up @@ -627,7 +671,10 @@ Server::TestsGenServiceImpl::ConfigureProject(ServerContext *context,

MEASURE_FUNCTION_EXECUTION_TIME

LOG_S(ERROR) << "ITF request path: " << request->projectcontext().itfpath();
utbot::ProjectContext utbotProjectContext{request->projectcontext()};
LOG_S(ERROR) << "ITF request2 path: " << utbotProjectContext.itfPath;

fs::path buildDirPath =
fs::path(utbotProjectContext.projectPath) / utbotProjectContext.buildDirRelativePath;
switch (request->configmode()) {
Expand Down
10 changes: 7 additions & 3 deletions server/src/Tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,14 +404,15 @@ namespace tests {
std::shared_ptr<AbstractValueView> view;
std::vector<MethodParam> lazyParams;
std::vector<TestCaseParamValue> lazyValues;

TestCaseParamValue() = default;

TestCaseParamValue(std::string _name,
const std::optional<size_t> &_alignment,
std::shared_ptr<AbstractValueView> _view)
: name(std::move(_name)),
alignment(_alignment),
view(std::move(_view)) {}
: name(std::move(_name)),
alignment(_alignment),
view(std::move(_view)) {}
};

struct FileInfo {
Expand Down Expand Up @@ -504,6 +505,9 @@ namespace tests {
SuiteNameToCodeTextMap codeText;
std::string paramsString;

std::string initFunction = "";
std::string teardownFunction = "";

types::Type returnType;
bool hasIncompleteReturnType = false;

Expand Down
2 changes: 1 addition & 1 deletion server/src/building/BuildDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ void BuildDatabase::addLibrariesForCommand(utbot::BaseCommand &command,
name = sharedLibraryFiles.at(name).at(libraryDir);
}
}
fs::path fullPath = Paths::getCCJsonFileFullPath(name, libraryDir);
fs::path fullPath = Paths::getFileFullPath(name, libraryDir);
if (CollectionUtils::containsKey(targetInfos, fullPath)) {
info.addFile(fullPath);
LOG_IF_S(WARNING, objectFiles) << "Object file " << command.getOutput()
Expand Down
4 changes: 2 additions & 2 deletions server/src/building/CompileCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ namespace utbot {
auto it = findOutput();
if (it != commandLine.end()) {
this->output = it;
*this->output = Paths::getCCJsonFileFullPath(*it, this->directory);
*this->output = Paths::getFileFullPath(*it, this->directory);
} else {
auto path = Paths::getCCJsonFileFullPath(Paths::replaceExtension(*this->sourcePath, ".o"), this->directory);
auto path = Paths::getFileFullPath(Paths::replaceExtension(*this->sourcePath, ".o"), this->directory);
this->output = std::next(addFlagsToBegin({"-o", path}));
}
}
Expand Down
2 changes: 1 addition & 1 deletion server/src/building/LinkCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ namespace utbot {
auto it = findOutput();
if (it != commandLine.end()) {
this->output = it;
*this->output = Paths::getCCJsonFileFullPath(*it, this->directory);
*this->output = Paths::getFileFullPath(*it, this->directory);
} else if (isArchiveCommand()) {
it = std::find_if(commandLine.begin(), commandLine.end(), [](const std::string &argument) {
return Paths::isStaticLibraryFile(argument);
Expand Down
6 changes: 3 additions & 3 deletions server/src/building/ProjectBuildDatabse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "Paths.h"

static std::string tryConvertToFullPath(const std::string &possibleFilePath, const fs::path &dirPath) {
fs::path fullFilePath = Paths::getCCJsonFileFullPath(possibleFilePath, dirPath);
fs::path fullFilePath = Paths::getFileFullPath(possibleFilePath, dirPath);
return fs::exists(fullFilePath) ? fullFilePath.string() : possibleFilePath;
}

Expand Down Expand Up @@ -82,7 +82,7 @@ void ProjectBuildDatabase::initObjects(const nlohmann::json &compileCommandsJson

fs::path directory = compileCommand.at("directory").get<std::string>();
fs::path jsonFile = compileCommand.at("file").get<std::string>();
fs::path sourceFile = Paths::getCCJsonFileFullPath(jsonFile, directory);
fs::path sourceFile = Paths::getFileFullPath(jsonFile, directory);

std::vector<std::string> jsonArguments;
if (compileCommand.contains("command")) {
Expand Down Expand Up @@ -218,7 +218,7 @@ void ProjectBuildDatabase::initInfo(const nlohmann::json &linkCommandsJson, bool
}
for (nlohmann::json const &jsonFile: linkCommand.at("files")) {
auto filename = jsonFile.get<std::string>();
fs::path currentFile = Paths::getCCJsonFileFullPath(filename, command.getDirectory());
fs::path currentFile = Paths::getFileFullPath(filename, command.getDirectory());
if (ignoredOutput.count(currentFile)) {
continue;
}
Expand Down
Loading

0 comments on commit a70416c

Please sign in to comment.