Skip to content

Commit a70416c

Browse files
authored
Add initialize and teardown functions call (#675)
* Add option to add initial and teardown function calls
1 parent 65d919b commit a70416c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+470
-280
lines changed

integration-tests/c-example/itf.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"default init": "",
3+
"default teardown": "",
4+
"init": {
5+
"init_global": "_init_vals"
6+
},
7+
"teardown": {
8+
"init_global": ""
9+
}
10+
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
int a;
2+
3+
void _init_vals() {
4+
a = 42;
5+
}
6+
7+
int init_global() {
8+
if(a == 42) {
9+
return 42;
10+
}
11+
return 0;
12+
}
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bool init_global();

server/proto/testgen.proto

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ message ProjectContext {
8989
string testDirPath = 3;
9090
string buildDirRelativePath = 4;
9191
string clientProjectPath = 5;
92+
string itfPath = 6;
9293
}
9394

9495
enum ErrorMode {

server/src/Paths.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ namespace Paths {
113113
return path3;
114114
}
115115

116-
fs::path getCCJsonFileFullPath(const std::string &filename, const fs::path &directory) {
116+
fs::path getFileFullPath(const std::string &filename, const fs::path &directory) {
117117
fs::path path1(filename);
118118
fs::path path2 = fs::weakly_canonical(directory / path1);
119119
return fs::exists(path2) ? path2 : path1;

server/src/Paths.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ namespace Paths {
213213
return getBaseLogDir() / "clients.json";
214214
}
215215

216-
fs::path getCCJsonFileFullPath(const std::string &filename, const fs::path &directory);
216+
fs::path getFileFullPath(const std::string &filename, const fs::path &directory);
217217

218218
bool isPath(const std::string &possibleFilePath) noexcept;
219219
//endregion

server/src/ProjectContext.cpp

+15-12
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,28 @@ namespace utbot {
99
fs::path projectPath,
1010
fs::path testDirPath,
1111
fs::path buildDirRelativePath,
12-
fs::path clientProjectPath)
12+
fs::path clientProjectPath,
13+
fs::path itfPath)
1314
: projectName(std::move(projectName)), projectPath(std::move(projectPath)),
1415
testDirPath(std::move(testDirPath)),
1516
buildDirRelativePath(std::move(buildDirRelativePath)),
16-
clientProjectPath(clientProjectPath) {}
17+
clientProjectPath(std::move(clientProjectPath)),
18+
itfPath(std::move(itfPath)) {
19+
}
1720

1821
ProjectContext::ProjectContext(const testsgen::ProjectContext &projectContext)
19-
: ProjectContext(projectContext.projectname(),
20-
projectContext.projectpath(),
21-
projectContext.testdirpath(),
22-
projectContext.builddirrelativepath(),
23-
projectContext.clientprojectpath()) {}
22+
: ProjectContext(projectContext.projectname(),
23+
projectContext.projectpath(),
24+
projectContext.testdirpath(),
25+
projectContext.builddirrelativepath(),
26+
projectContext.clientprojectpath(),
27+
projectContext.itfpath()) {}
2428

2529
ProjectContext::ProjectContext(const testsgen::SnippetRequest &request, fs::path serverBuildDir)
26-
: projectName(request.projectcontext().projectname()),
27-
projectPath(request.projectcontext().projectpath()),
28-
testDirPath(request.projectcontext().testdirpath()),
29-
buildDirRelativePath(request.projectcontext().builddirrelativepath()),
30-
clientProjectPath(request.projectcontext().clientprojectpath()) {}
30+
: ProjectContext(request.projectcontext().projectname(), request.projectcontext().projectpath(),
31+
request.projectcontext().testdirpath(), request.projectcontext().builddirrelativepath(),
32+
request.projectcontext().clientprojectpath(),
33+
request.projectcontext().itfpath()) {}
3134

3235
fs::path ProjectContext::buildDir() const {
3336
return projectPath / buildDirRelativePath;

server/src/ProjectContext.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ class ProjectContext {
1717
fs::path projectPath,
1818
fs::path testDirPath,
1919
fs::path buildDirRelativePath,
20-
fs::path serverBuildDir);
20+
fs::path serverBuildDir,
21+
fs::path itfPath);
2122

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

@@ -30,6 +31,7 @@ class ProjectContext {
3031
const fs::path testDirPath;
3132
const fs::path buildDirRelativePath;
3233
const fs::path clientProjectPath;
34+
const fs::path itfPath;
3335
};
3436
}
3537

server/src/Server.cpp

+47
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "utils/stats/TestsGenerationStats.h"
3333
#include "utils/stats/TestsExecutionStats.h"
3434
#include "utils/TypeUtils.h"
35+
#include "utils/JsonUtils.h"
3536
#include "building/ProjectBuildDatabase.h"
3637

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

238239
FeaturesFilter::filter(testGen.settingsContext, typesHandler, testGen.tests);
239240
StubsCollector(typesHandler).collect(testGen.tests);
241+
if (!testGen.projectContext.itfPath.string().empty()) {
242+
try {
243+
fs::path fullFilePath = Paths::getFileFullPath(testGen.projectContext.itfPath,
244+
testGen.projectContext.projectPath);
245+
if (!fs::exists(fullFilePath)) {
246+
std::string message = "File with init and teardown functions, doesn't exists";
247+
LOG_S(ERROR) << message;
248+
throw EnvironmentException(message);
249+
}
250+
LOG_S(INFO) << "Use init and teardown functions from: " << fullFilePath;
251+
nlohmann::json itfJson = JsonUtils::getJsonFromFile(fullFilePath);
252+
auto defaultInitIt = itfJson.find("default init");
253+
std::string defaultInitial = itfJson.value("default init", "");
254+
std::string defaultTeardown = itfJson.value("default teardown", "");
255+
256+
std::optional<nlohmann::json> initJson = std::nullopt;
257+
if (itfJson.contains("init")) {
258+
initJson = itfJson.at("init");
259+
}
260+
261+
std::optional<nlohmann::json> teardownJson = std::nullopt;
262+
if (itfJson.contains("teardown")) {
263+
teardownJson = itfJson.at("teardown");
264+
}
265+
for (tests::TestsMap::iterator it = testGen.tests.begin(); it != testGen.tests.end(); ++it) {
266+
tests::Tests &tests = it.value();
267+
for (tests::Tests::MethodsMap::iterator testsIt = tests.methods.begin();
268+
testsIt != tests.methods.end(); testsIt++) {
269+
const std::string &methodName = testsIt.key();
270+
tests::Tests::MethodDescription &method = testsIt.value();
271+
if (initJson.has_value()) {
272+
method.initFunction = initJson->value(methodName, defaultInitial);
273+
}
274+
if (teardownJson.has_value()) {
275+
method.teardownFunction = teardownJson->value(methodName, defaultTeardown);
276+
}
277+
}
278+
}
279+
} catch (const std::exception &e) {
280+
LOG_S(ERROR) << e.what();
281+
throw EnvironmentException(e.what());
282+
}
283+
}
240284

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

628672
MEASURE_FUNCTION_EXECUTION_TIME
629673

674+
LOG_S(ERROR) << "ITF request path: " << request->projectcontext().itfpath();
630675
utbot::ProjectContext utbotProjectContext{request->projectcontext()};
676+
LOG_S(ERROR) << "ITF request2 path: " << utbotProjectContext.itfPath;
677+
631678
fs::path buildDirPath =
632679
fs::path(utbotProjectContext.projectPath) / utbotProjectContext.buildDirRelativePath;
633680
switch (request->configmode()) {

server/src/Tests.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -404,14 +404,15 @@ namespace tests {
404404
std::shared_ptr<AbstractValueView> view;
405405
std::vector<MethodParam> lazyParams;
406406
std::vector<TestCaseParamValue> lazyValues;
407+
407408
TestCaseParamValue() = default;
408409

409410
TestCaseParamValue(std::string _name,
410411
const std::optional<size_t> &_alignment,
411412
std::shared_ptr<AbstractValueView> _view)
412-
: name(std::move(_name)),
413-
alignment(_alignment),
414-
view(std::move(_view)) {}
413+
: name(std::move(_name)),
414+
alignment(_alignment),
415+
view(std::move(_view)) {}
415416
};
416417

417418
struct FileInfo {
@@ -504,6 +505,9 @@ namespace tests {
504505
SuiteNameToCodeTextMap codeText;
505506
std::string paramsString;
506507

508+
std::string initFunction = "";
509+
std::string teardownFunction = "";
510+
507511
types::Type returnType;
508512
bool hasIncompleteReturnType = false;
509513

server/src/building/BuildDatabase.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ void BuildDatabase::addLibrariesForCommand(utbot::BaseCommand &command,
157157
name = sharedLibraryFiles.at(name).at(libraryDir);
158158
}
159159
}
160-
fs::path fullPath = Paths::getCCJsonFileFullPath(name, libraryDir);
160+
fs::path fullPath = Paths::getFileFullPath(name, libraryDir);
161161
if (CollectionUtils::containsKey(targetInfos, fullPath)) {
162162
info.addFile(fullPath);
163163
LOG_IF_S(WARNING, objectFiles) << "Object file " << command.getOutput()

server/src/building/CompileCommand.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ namespace utbot {
115115
auto it = findOutput();
116116
if (it != commandLine.end()) {
117117
this->output = it;
118-
*this->output = Paths::getCCJsonFileFullPath(*it, this->directory);
118+
*this->output = Paths::getFileFullPath(*it, this->directory);
119119
} else {
120-
auto path = Paths::getCCJsonFileFullPath(Paths::replaceExtension(*this->sourcePath, ".o"), this->directory);
120+
auto path = Paths::getFileFullPath(Paths::replaceExtension(*this->sourcePath, ".o"), this->directory);
121121
this->output = std::next(addFlagsToBegin({"-o", path}));
122122
}
123123
}

server/src/building/LinkCommand.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ namespace utbot {
7575
auto it = findOutput();
7676
if (it != commandLine.end()) {
7777
this->output = it;
78-
*this->output = Paths::getCCJsonFileFullPath(*it, this->directory);
78+
*this->output = Paths::getFileFullPath(*it, this->directory);
7979
} else if (isArchiveCommand()) {
8080
it = std::find_if(commandLine.begin(), commandLine.end(), [](const std::string &argument) {
8181
return Paths::isStaticLibraryFile(argument);

server/src/building/ProjectBuildDatabse.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "Paths.h"
1010

1111
static std::string tryConvertToFullPath(const std::string &possibleFilePath, const fs::path &dirPath) {
12-
fs::path fullFilePath = Paths::getCCJsonFileFullPath(possibleFilePath, dirPath);
12+
fs::path fullFilePath = Paths::getFileFullPath(possibleFilePath, dirPath);
1313
return fs::exists(fullFilePath) ? fullFilePath.string() : possibleFilePath;
1414
}
1515

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

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

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

0 commit comments

Comments
 (0)