diff --git a/integration-tests/c-example/itf.json b/integration-tests/c-example/itf.json new file mode 100644 index 000000000..0717492a2 --- /dev/null +++ b/integration-tests/c-example/itf.json @@ -0,0 +1,10 @@ +{ + "default init": "", + "default teardown": "", + "init": { + "init_global": "_init_vals" + }, + "teardown": { + "init_global": "" + } +} diff --git a/integration-tests/c-example/lib/inits.c b/integration-tests/c-example/lib/inits.c new file mode 100644 index 000000000..f0c396819 --- /dev/null +++ b/integration-tests/c-example/lib/inits.c @@ -0,0 +1,12 @@ +int a; + +void _init_vals() { + a = 42; +} + +int init_global() { + if(a == 42) { + return 42; + } + return 0; +} diff --git a/integration-tests/c-example/lib/inits.h b/integration-tests/c-example/lib/inits.h new file mode 100644 index 000000000..fa9731800 --- /dev/null +++ b/integration-tests/c-example/lib/inits.h @@ -0,0 +1 @@ +bool init_global(); diff --git a/server/proto/testgen.proto b/server/proto/testgen.proto index 24a044c1a..de9554456 100644 --- a/server/proto/testgen.proto +++ b/server/proto/testgen.proto @@ -89,6 +89,7 @@ message ProjectContext { string testDirPath = 3; string buildDirRelativePath = 4; string clientProjectPath = 5; + string itfPath = 6; } enum ErrorMode { diff --git a/server/src/Paths.cpp b/server/src/Paths.cpp index def0fd92c..f698fb23b 100644 --- a/server/src/Paths.cpp +++ b/server/src/Paths.cpp @@ -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; diff --git a/server/src/Paths.h b/server/src/Paths.h index 507d84951..c83fcd428 100644 --- a/server/src/Paths.h +++ b/server/src/Paths.h @@ -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 diff --git a/server/src/ProjectContext.cpp b/server/src/ProjectContext.cpp index c906844fa..b9514b678 100644 --- a/server/src/ProjectContext.cpp +++ b/server/src/ProjectContext.cpp @@ -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; diff --git a/server/src/ProjectContext.h b/server/src/ProjectContext.h index f3d6233b4..2f3cc7d85 100644 --- a/server/src/ProjectContext.h +++ b/server/src/ProjectContext.h @@ -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); @@ -30,6 +31,7 @@ class ProjectContext { const fs::path testDirPath; const fs::path buildDirRelativePath; const fs::path clientProjectPath; + const fs::path itfPath; }; } diff --git a/server/src/Server.cpp b/server/src/Server.cpp index 39d3c03a4..51b6867d7 100644 --- a/server/src/Server.cpp +++ b/server/src/Server.cpp @@ -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 @@ -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 initJson = std::nullopt; + if (itfJson.contains("init")) { + initJson = itfJson.at("init"); + } + + std::optional 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) { @@ -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()) { diff --git a/server/src/Tests.h b/server/src/Tests.h index 3c828aea0..d555e35d2 100644 --- a/server/src/Tests.h +++ b/server/src/Tests.h @@ -404,14 +404,15 @@ namespace tests { std::shared_ptr view; std::vector lazyParams; std::vector lazyValues; + TestCaseParamValue() = default; TestCaseParamValue(std::string _name, const std::optional &_alignment, std::shared_ptr _view) - : name(std::move(_name)), - alignment(_alignment), - view(std::move(_view)) {} + : name(std::move(_name)), + alignment(_alignment), + view(std::move(_view)) {} }; struct FileInfo { @@ -504,6 +505,9 @@ namespace tests { SuiteNameToCodeTextMap codeText; std::string paramsString; + std::string initFunction = ""; + std::string teardownFunction = ""; + types::Type returnType; bool hasIncompleteReturnType = false; diff --git a/server/src/building/BuildDatabase.cpp b/server/src/building/BuildDatabase.cpp index 9b1fb8673..4d3e37b1b 100644 --- a/server/src/building/BuildDatabase.cpp +++ b/server/src/building/BuildDatabase.cpp @@ -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() diff --git a/server/src/building/CompileCommand.cpp b/server/src/building/CompileCommand.cpp index 56a182c93..92a8a3a02 100644 --- a/server/src/building/CompileCommand.cpp +++ b/server/src/building/CompileCommand.cpp @@ -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})); } } diff --git a/server/src/building/LinkCommand.cpp b/server/src/building/LinkCommand.cpp index ca084d861..d2d1093b6 100644 --- a/server/src/building/LinkCommand.cpp +++ b/server/src/building/LinkCommand.cpp @@ -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); diff --git a/server/src/building/ProjectBuildDatabse.cpp b/server/src/building/ProjectBuildDatabse.cpp index 2f38d6044..47dc3e4ed 100644 --- a/server/src/building/ProjectBuildDatabse.cpp +++ b/server/src/building/ProjectBuildDatabse.cpp @@ -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; } @@ -82,7 +82,7 @@ void ProjectBuildDatabase::initObjects(const nlohmann::json &compileCommandsJson fs::path directory = compileCommand.at("directory").get(); fs::path jsonFile = compileCommand.at("file").get(); - fs::path sourceFile = Paths::getCCJsonFileFullPath(jsonFile, directory); + fs::path sourceFile = Paths::getFileFullPath(jsonFile, directory); std::vector jsonArguments; if (compileCommand.contains("command")) { @@ -218,7 +218,7 @@ void ProjectBuildDatabase::initInfo(const nlohmann::json &linkCommandsJson, bool } for (nlohmann::json const &jsonFile: linkCommand.at("files")) { auto filename = jsonFile.get(); - fs::path currentFile = Paths::getCCJsonFileFullPath(filename, command.getDirectory()); + fs::path currentFile = Paths::getFileFullPath(filename, command.getDirectory()); if (ignoredOutput.count(currentFile)) { continue; } diff --git a/server/src/commands/Commands.cpp b/server/src/commands/Commands.cpp index f42f8a700..fc89f2b8a 100644 --- a/server/src/commands/Commands.cpp +++ b/server/src/commands/Commands.cpp @@ -78,11 +78,11 @@ unsigned int Commands::ServerCommandOptions::getKleeProcessNumber() { } const std::map Commands::MainCommands::verbosityMap = { - { "trace", loguru::NamedVerbosity::Verbosity_MAX }, - { "debug", loguru::NamedVerbosity::Verbosity_1 }, - { "info", loguru::NamedVerbosity::Verbosity_INFO }, - { "warning", loguru::NamedVerbosity::Verbosity_WARNING }, - { "error", loguru::NamedVerbosity::Verbosity_ERROR } + {"trace", loguru::NamedVerbosity::Verbosity_MAX}, + {"debug", loguru::NamedVerbosity::Verbosity_1}, + {"info", loguru::NamedVerbosity::Verbosity_INFO}, + {"warning", loguru::NamedVerbosity::Verbosity_WARNING}, + {"error", loguru::NamedVerbosity::Verbosity_ERROR} }; @@ -108,9 +108,9 @@ Commands::GenerateCommands::GenerateCommands(CLI::App *command) { classCommand = generateCommand->add_subcommand("class", "Generate tests for C++ class."); lineCommand = generateCommand->add_subcommand("line", "Generate tests for line in file."); assertionCommand = - generateCommand->add_subcommand("assertion", "Generate tests that fails assertion."); + generateCommand->add_subcommand("assertion", "Generate tests that fails assertion."); predicateCommand = - generateCommand->add_subcommand("predicate", "Generate tests with given result."); + generateCommand->add_subcommand("predicate", "Generate tests with given result."); } CLI::App *Commands::GenerateCommands::getProjectCommand() { @@ -206,62 +206,62 @@ Commands::GenerateCommandsOptions::GenerateCommandsOptions(GenerateCommands &gen generateCommands.getPredicateCommand()->add_option(srcPathsFlag, srcPaths, srcPathsDescription); // file path generateCommands.getSnippetCommand() - ->add_option(filePathFlag, filePath, filePathDescription) - ->required(); + ->add_option(filePathFlag, filePath, filePathDescription) + ->required(); generateCommands.getFileCommand() - ->add_option(filePathFlag, filePath, filePathDescription) - ->required(); + ->add_option(filePathFlag, filePath, filePathDescription) + ->required(); generateCommands.getLineCommand() - ->add_option(filePathFlag, filePath, filePathDescription) - ->required(); + ->add_option(filePathFlag, filePath, filePathDescription) + ->required(); generateCommands.getFunctionCommand() - ->add_option(filePathFlag, filePath, filePathDescription) - ->required(); + ->add_option(filePathFlag, filePath, filePathDescription) + ->required(); generateCommands.getClassCommand() - ->add_option(filePathFlag, filePath, filePathDescription) - ->required(); + ->add_option(filePathFlag, filePath, filePathDescription) + ->required(); generateCommands.getAssertionCommand() - ->add_option(filePathFlag, filePath, filePathDescription) - ->required(); + ->add_option(filePathFlag, filePath, filePathDescription) + ->required(); generateCommands.getPredicateCommand() - ->add_option(filePathFlag, filePath, filePathDescription) - ->required(); + ->add_option(filePathFlag, filePath, filePathDescription) + ->required(); // folder path generateCommands.getFolderCommand() - ->add_option(folderPathFlag, folderPath, folderPathDescription) - ->required(); + ->add_option(folderPathFlag, folderPath, folderPathDescription) + ->required(); // line number generateCommands.getLineCommand() - ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) - ->required(); + ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) + ->required(); generateCommands.getFunctionCommand() - ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) - ->required(); + ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) + ->required(); generateCommands.getClassCommand() - ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) - ->required(); + ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) + ->required(); generateCommands.getAssertionCommand() - ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) - ->required(); + ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) + ->required(); generateCommands.getPredicateCommand() - ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) - ->required(); + ->add_option(lineNumberFlag, lineNumber, lineNumberDescription) + ->required(); // predicate info generateCommands.getPredicateCommand() - ->add_option("--validation-type", type, "Type of predicate values.") - ->required() - ->type_name(" ENUM:value in {" + - StringUtils::joinWith(CollectionUtils::getKeys(validationTypeMap), "|") + "}") - ->transform(CLI::CheckedTransformer(validationTypeMap, CLI::ignore_case)); + ->add_option("--validation-type", type, "Type of predicate values.") + ->required() + ->type_name(" ENUM:value in {" + + StringUtils::joinWith(CollectionUtils::getKeys(validationTypeMap), "|") + "}") + ->transform(CLI::CheckedTransformer(validationTypeMap, CLI::ignore_case)); generateCommands.getPredicateCommand() - ->add_option("--predicate", predicate, "Predicate string representation.") - ->required(); + ->add_option("--predicate", predicate, "Predicate string representation.") + ->required(); generateCommands.getPredicateCommand() - ->add_option("--return-value", returnValue, "Expected return value.") - ->required(); + ->add_option("--return-value", returnValue, "Expected return value.") + ->required(); // target generateCommands.getProjectCommand()->add_option(targetFlag, target, targetDescription); @@ -307,34 +307,38 @@ std::optional Commands::GenerateBaseCommandsOptions::getTarget() co } const std::map - Commands::GenerateCommandsOptions::validationTypeMap = { - { "int8", testsgen::ValidationType::INT8_T }, - { "int16", testsgen::ValidationType::INT16_T }, - { "int32", testsgen::ValidationType::INT32_T }, - { "int64", testsgen::ValidationType::INT64_T }, - { "uint8", testsgen::ValidationType::UINT8_T }, - { "uint16", testsgen::ValidationType::UINT16_T }, - { "uint32", testsgen::ValidationType::UINT32_T }, - { "uint64", testsgen::ValidationType::UINT64_T }, - { "bool", testsgen::ValidationType::BOOL }, - { "char", testsgen::ValidationType::CHAR }, - { "float", testsgen::ValidationType::FLOAT }, - { "string", testsgen::ValidationType::STRING } - }; + Commands::GenerateCommandsOptions::validationTypeMap = { + {"int8", testsgen::ValidationType::INT8_T}, + {"int16", testsgen::ValidationType::INT16_T}, + {"int32", testsgen::ValidationType::INT32_T}, + {"int64", testsgen::ValidationType::INT64_T}, + {"uint8", testsgen::ValidationType::UINT8_T}, + {"uint16", testsgen::ValidationType::UINT16_T}, + {"uint32", testsgen::ValidationType::UINT32_T}, + {"uint64", testsgen::ValidationType::UINT64_T}, + {"bool", testsgen::ValidationType::BOOL}, + {"char", testsgen::ValidationType::CHAR}, + {"float", testsgen::ValidationType::FLOAT}, + {"string", testsgen::ValidationType::STRING} +}; Commands::ProjectContextOptionGroup::ProjectContextOptionGroup(CLI::App *command) { projectContextOptions = command->add_option_group("Project context"); projectContextOptions - ->add_option("-p,--project-path", projectPath, "Path to testing project root.") - ->required(); + ->add_option("-p,--project-path", projectPath, "Path to testing project root.") + ->required(); + + projectContextOptions->add_option( + "-t,--tests-dir", testDir, "Relative path to directory in which tests will be generated.", + true); projectContextOptions->add_option( - "-t,--tests-dir", testDir, "Relative path to directory in which tests will be generated.", - true); + "-b,--build-dir", buildDir, + "Relative path to build directory with compile_commands.json and/or coverage.json.", true); projectContextOptions->add_option( - "-b,--build-dir", buildDir, - "Relative path to build directory with compile_commands.json and/or coverage.json.", true); + "-i,--init-teardown-path", itfPath, + "Relative paths to json, that contains list of initial and teardown functions", true); } CLI::Option_group *Commands::ProjectContextOptionGroup::getProjectContextOptions() const { @@ -360,11 +364,15 @@ std::string Commands::ProjectContextOptionGroup::getBuildDirectory() const { return buildDir; } +std::string Commands::ProjectContextOptionGroup::getItfPath() const { + return itfPath; +} + Commands::SettingsContextOptionGroup::SettingsContextOptionGroup(CLI::App *command) { settingsContextOptions = command->add_option_group("Settings context"); settingsContextOptions->add_flag( - "-g,--generate-for-static", generateForStaticFunctions, - "True, if you want UTBot to generate tests for static functions."); + "-g,--generate-for-static", generateForStaticFunctions, + "True, if you want UTBot to generate tests for static functions."); settingsContextOptions->add_flag("-v,--verbose", verbose, "Set if is required."); settingsContextOptions->add_option("--function-timeout", timeoutPerFunction, @@ -459,11 +467,11 @@ Commands::RunTestsCommandOptions::RunTestsCommandOptions(Commands::RunTestsComma commands.getRunTestCommand()->add_option("--test-suite", testSuite, "Test suite")->required(); commands.getRunTestCommand()->add_option("--test-name", testName, "Test name")->required(); commands.getRunTestCommand() - ->add_option("--file-path", filePath, "Path to test file") - ->required(); + ->add_option("--file-path", filePath, "Path to test file") + ->required(); commands.getRunFileCommand() - ->add_option("--file-path", filePath, "Path to test file") - ->required(); + ->add_option("--file-path", filePath, "Path to test file") + ->required(); commands.getRunTestCommand()->add_flag("--no-coverage", noCoverage, "Flag that controls coverage generation."); commands.getRunFileCommand()->add_flag("--no-coverage", noCoverage, diff --git a/server/src/commands/Commands.h b/server/src/commands/Commands.h index b52fae53c..d05f5f78d 100644 --- a/server/src/commands/Commands.h +++ b/server/src/commands/Commands.h @@ -218,11 +218,14 @@ namespace Commands { [[nodiscard]] std::string getBuildDirectory() const; + [[nodiscard]] std::string getItfPath() const; + private: CLI::Option_group *projectContextOptions; fs::path projectPath; std::string testDir = "tests"; std::string buildDir = "build"; + std::string itfPath = ""; }; struct SettingsContextOptionGroup { diff --git a/server/src/printers/KleePrinter.cpp b/server/src/printers/KleePrinter.cpp index 89bdf0169..70c3b32e0 100644 --- a/server/src/printers/KleePrinter.cpp +++ b/server/src/printers/KleePrinter.cpp @@ -49,9 +49,10 @@ void KleePrinter::writePosixWrapper(const Tests &tests, ss << printer::NL; } + void KleePrinter::genOpenFiles(const tests::Tests::MethodDescription &testMethod) { char fileName = 'A'; - for (const auto ¶m : testMethod.params) { + for (const auto ¶m: testMethod.params) { if (param.type.isFilePointer()) { std::string strFileName(1, fileName++); if (fileName > 'A' + types::Type::symFilesCount) { @@ -62,7 +63,7 @@ void KleePrinter::genOpenFiles(const tests::Tests::MethodDescription &testMethod strDeclareVar(param.type.typeName(), param.name, constrFunctionCall("fopen", - { StringUtils::wrapQuotations(strFileName), "\"r\"" }, + {StringUtils::wrapQuotations(strFileName), "\"r\""}, "", std::nullopt, false)); } } @@ -82,6 +83,7 @@ void KleePrinter::writeTestedFunction(const Tests &tests, declTestEntryPoint(tests, testMethod, isWrapped); genOpenFiles(testMethod); genGlobalParamsDeclarations(testMethod); + genInitCall(testMethod); genParamsDeclarations(testMethod, filterAllWithoutFile); genPostGlobalSymbolicVariables(testMethod); genPostParamsSymbolicVariables(testMethod, filterAllWithoutFile); @@ -92,6 +94,7 @@ void KleePrinter::writeTestedFunction(const Tests &tests, } genGlobalsKleeAssumes(testMethod); genPostParamsKleeAssumes(testMethod, filterAllWithoutFile); + genTearDownCall(testMethod); strReturn("0"); closeBrackets(1); ss << printer::NL; diff --git a/server/src/printers/KleePrinter.h b/server/src/printers/KleePrinter.h index 1ce867f2f..ebb7f7596 100644 --- a/server/src/printers/KleePrinter.h +++ b/server/src/printers/KleePrinter.h @@ -45,7 +45,9 @@ namespace printer { bool needAssertion, const utbot::ProjectContext &projectContext); - [[nodiscard]] std::vector getIncludePaths(const Tests &tests, const PathSubstitution &substitution) const; + [[nodiscard]] std::vector + getIncludePaths(const Tests &tests, const PathSubstitution &substitution) const; + private: types::TypesHandler const *typesHandler; BaseTestGen const *testGen; @@ -72,7 +74,8 @@ namespace printer { bool genPointerParamDeclaration(const Tests::MethodParam ¶m); - void genReturnDeclaration(const Tests::MethodDescription &testMethod, const std::optional &predicateInfo); + void + genReturnDeclaration(const Tests::MethodDescription &testMethod, const std::optional &predicateInfo); void genParamsKleeAssumes(const Tests::MethodDescription &testMethod, const std::optional &predicateInfo, @@ -88,7 +91,7 @@ namespace printer { /* * Functions for constraints generation. */ - void genConstraints(const Tests::MethodParam ¶m, const std::vector& names = {}); + void genConstraints(const Tests::MethodParam ¶m, const std::vector &names = {}); void genTwoDimPointers(const Tests::MethodParam ¶m, bool needDeclare); @@ -110,7 +113,8 @@ namespace printer { const std::string &testedMethod, bool onlyForOneEntity); - [[maybe_unused]] void addHeaderIncludeIfNecessary(std::unordered_set &headers, const types::Type &type); + [[maybe_unused]] void + addHeaderIncludeIfNecessary(std::unordered_set &headers, const types::Type &type); Stream strKleeMakeSymbolic(SRef varName, bool needAmpersand); @@ -121,8 +125,8 @@ namespace printer { void genPostGlobalSymbolicVariables(const Tests::MethodDescription &testMethod); void genPostParamsSymbolicVariables( - const Tests::MethodDescription &testMethod, - std::function filter); + const Tests::MethodDescription &testMethod, + std::function filter); void makeBracketsForStrPredicate(const std::optional &info); diff --git a/server/src/printers/Printer.cpp b/server/src/printers/Printer.cpp index 1e9e238fa..e254e0599 100644 --- a/server/src/printers/Printer.cpp +++ b/server/src/printers/Printer.cpp @@ -13,7 +13,7 @@ namespace printer { using StringUtils::stringFormat; - Printer::Printer(utbot::Language srcLanguage) : srcLanguage(srcLanguage){ + Printer::Printer(utbot::Language srcLanguage) : srcLanguage(srcLanguage) { } bool Printer::needDecorate() const { @@ -128,7 +128,7 @@ namespace printer { bool complete, ExternType externType) { auto baseType = type.baseType(); - std::string arrayName{ name.data(), name.length() }; + std::string arrayName{name.data(), name.length()}; if (needDecorate()) { baseType = NameDecorator::decorate(baseType); @@ -157,7 +157,7 @@ namespace printer { if (isLiteral) { ss << "[]"; } else { - for (auto size : sizes) { + for (auto size: sizes) { ss << "[" << size << "]"; } } @@ -186,16 +186,16 @@ namespace printer { } Printer::Stream &Printer::strFunctionDecl( - const std::string &returnType, - const std::string &functionName, - const std::vector ¶mTypes, - const std::vector ¶mValues, - const std::string &end, - const std::vector &modifiers, - const tests::Tests::MethodDescription::FPointerMap &fullDeclSubstitutions, - bool isVariadic) { + const std::string &returnType, + const std::string &functionName, + const std::vector ¶mTypes, + const std::vector ¶mValues, + const std::string &end, + const std::vector &modifiers, + const tests::Tests::MethodDescription::FPointerMap &fullDeclSubstitutions, + bool isVariadic) { ss << LINE_INDENT(); - for (const auto &modifier : modifiers) { + for (const auto &modifier: modifiers) { ss << modifier << " "; } ss << returnType << " " << functionName << "("; @@ -203,7 +203,8 @@ namespace printer { for (auto i = 0; i < n; i++) { bool named = false; if (CollectionUtils::containsKey(fullDeclSubstitutions, paramValues[i])) { - ss << getTypedefFunctionPointer(functionName, paramValues[i], paramTypes[i].isArrayOfPointersToFunction()); + ss << getTypedefFunctionPointer(functionName, paramValues[i], + paramTypes[i].isArrayOfPointersToFunction()); } else { if (paramTypes[i].isPointerToArray()) { auto decomposedType = StringUtils::split(paramTypes[i].usedType(), '*'); @@ -281,7 +282,7 @@ namespace printer { bool needTabs) { strTabIf(needTabs); std::vector parameters; - for (const auto ¶m : method.params) { + for (const auto ¶m: method.params) { parameters.push_back(param.getFunctionParamDecl()); } auto classObjName = method.getClassName(); @@ -309,7 +310,7 @@ namespace printer { std::string Printer::constrMultiIndex(const std::string &arrayName, const std::vector &indexes) { std::string element = arrayName; - for (const auto &index : indexes) { + for (const auto &index: indexes) { element = constrIndex(element, index); } return element; @@ -317,7 +318,7 @@ namespace printer { std::string Printer::constrMultiIndex(const std::string &arrayName, const std::vector &indexes) { std::vector strIndexes; - for (size_t index : indexes) { + for (size_t index: indexes) { strIndexes.push_back(std::to_string(index)); } return constrMultiIndex(arrayName, strIndexes); @@ -387,9 +388,10 @@ namespace printer { return ss; } - std::stringstream& Printer::checkOverflowStubArray(const std::string &cntCall) { + std::stringstream &Printer::checkOverflowStubArray(const std::string &cntCall) { ss << LINE_INDENT() << "if (" << cntCall << " == " << - types::TypesHandler::getElementsNumberInPointerOneDim(types::PointerUsage::PARAMETER) << ") {" << printer::NL; + types::TypesHandler::getElementsNumberInPointerOneDim(types::PointerUsage::PARAMETER) << ") {" + << printer::NL; tabsDepth++; ss << LINE_INDENT() << cntCall << "--;" << printer::NL; ss << RB(); @@ -446,7 +448,7 @@ namespace printer { printer::KleeConstraintsPrinter preferWriter(temp.get(), srcLanguage); preferWriter.setTabsDepth(tabsDepth); preferWriter.genConstraints( - {types::Type::createArray(method.returnType), stubSymbolicVarName, std::nullopt}); + {types::Type::createArray(method.returnType), stubSymbolicVarName, std::nullopt}); ss << preferWriter.ss.str(); ss << RB(); tabsDepth--; @@ -463,14 +465,14 @@ namespace printer { auto pointer = (needAmpersand ? "&" : "") + varName; auto size = "sizeof(" + varName + ")"; auto name = "\"" + pseudoName + "\""; - strFunctionCall("klee_make_symbolic", { pointer, size, name }); + strFunctionCall("klee_make_symbolic", {pointer, size, name}); return ss; } std::stringstream &Printer::strDeclareArrayOfFunctionPointerVar( - const std::string &arrayType, const std::string &arrayName, const std::string &stubFunctionName) { + const std::string &arrayType, const std::string &arrayName, const std::string &stubFunctionName) { size_t size = - types::TypesHandler::getElementsNumberInPointerOneDim(types::PointerUsage::PARAMETER); + types::TypesHandler::getElementsNumberInPointerOneDim(types::PointerUsage::PARAMETER); strDeclareVar(arrayType, arrayName + "[" + std::to_string(size) + "]"); strForBound("i", size) << " " << BNL; tabsDepth++; @@ -483,13 +485,14 @@ namespace printer { std::stringstream &Printer::strTypedefFunctionPointer(const types::FunctionInfo &method, const std::string &name) { auto paramTypes = - CollectionUtils::transform(method.params, [](const auto ¶m) { return param.type; }); + CollectionUtils::transform(method.params, [](const auto ¶m) { return param.type; }); ss << LINE_INDENT() << "typedef "; strFunctionDecl(method.returnType.usedType(), StringUtils::stringFormat("(*%s)", name), paramTypes, std::vector(paramTypes.size(), ""), "") << SCNL; if (method.isArray) { ss << LINE_INDENT() << "typedef "; - strFunctionDecl(method.returnType.usedType(), StringUtils::stringFormat("(**%s)", name + "_arr"), paramTypes, + strFunctionDecl(method.returnType.usedType(), StringUtils::stringFormat("(**%s)", name + "_arr"), + paramTypes, std::vector(paramTypes.size(), ""), "") << SCNL; } return ss; @@ -509,19 +512,19 @@ namespace printer { size_t pointerSize = types::TypesHandler::getElementsNumberInPointerMultiDim(types::PointerUsage::PARAMETER); auto typeObject = types::TypesHandler::isVoid(param.type.baseTypeObj()) - ? types::Type::minimalScalarPointerType(2) - : param.type; + ? types::Type::minimalScalarPointerType(2) + : param.type; auto baseType = typeObject.baseType(); auto type = stringFormat("%s%s **", getConstQualifier(typeObject), baseType); std::string value = - stringFormat("(%s) calloc(%zu, sizeof(%s *))", type, pointerSize + 1, baseType); + stringFormat("(%s) calloc(%zu, sizeof(%s *))", type, pointerSize + 1, baseType); if (needDeclare) { strDeclareVar(type, param.name, value); } else { strAssignVar(param.name, value); } - auto iterators = printForLoopsAndReturnLoopIterators({ pointerSize }); + auto iterators = printForLoopsAndReturnLoopIterators({pointerSize}); auto indexing = constrMultiIndex(iterators); strAssignVar(param.name + indexing, param.underscoredName() + indexing); closeBrackets(1); @@ -533,9 +536,9 @@ namespace printer { Printer::strMemcpyImpl(std::string_view dest, std::string_view src, bool needDereference) { using namespace std::string_literals; std::string destArg = stringFormat("(void *) %s%.*s", (needDereference ? "&"s : ""s), - dest.length(), dest.data()); + dest.length(), dest.data()); std::string count = stringFormat("%s(%.*s)", SIZEOF, src.length(), src.data()); - strFunctionCall(MEMCPY, { destArg, std::string(src), count }); + strFunctionCall(MEMCPY, {destArg, std::string(src), count}); return ss; } @@ -616,7 +619,7 @@ namespace printer { std::unordered_set &checkedOnPrivate) { if (!checkedOnPrivate.count(type.getId()) && typesHandler->isStructLike(type)) { checkedOnPrivate.insert(type.getId()); - for (const auto& field : typesHandler->getStructInfo(type).fields) { + for (const auto &field: typesHandler->getStructInfo(type).fields) { if (field.accessSpecifier != types::AccessSpecifier::AS_pubic && !field.type.isArray()) { ss << StringUtils::stringFormat("ACCESS_PRIVATE_FIELD(%s, %s, %s)", type.typeName(), @@ -640,7 +643,7 @@ namespace printer { const types::Field &field, const std::string &stubName) { size_t size = - types::TypesHandler::getElementsNumberInPointerOneDim(types::PointerUsage::PARAMETER); + types::TypesHandler::getElementsNumberInPointerOneDim(types::PointerUsage::PARAMETER); strForBound("i", size) << " " << BNL; tabsDepth++; std::string name = structName + "." + field.name + "[i]"; @@ -656,7 +659,7 @@ namespace printer { } void Printer::writeStubsForParameters(const Tests &tests) { - for (const auto &[methodName, methodDescription] : tests.methods) { + for (const auto &[methodName, methodDescription]: tests.methods) { if (methodDescription.stubsText.empty()) { continue; } @@ -668,7 +671,7 @@ namespace printer { return srcLanguage; } - std::string Printer::getConstQualifier(const types::Type& type) { + std::string Printer::getConstQualifier(const types::Type &type) { std::string constQualifier; if (auto simpleType = dynamic_cast(type.kinds().back().get())) { if (simpleType->isConstQualified()) { @@ -683,7 +686,7 @@ namespace printer { } Printer::Stream Printer::strDeclareSetOfVars(const std::set &vars) { - for (const auto &var : vars) { + for (const auto &var: vars) { if (var.type.isArray()) { strDeclareArrayVar(var.type, var.varName, types::PointerUsage::KNOWN_SIZE); } else { @@ -692,4 +695,16 @@ namespace printer { } return ss; } + + void Printer::genInitCall(const tests::Tests::MethodDescription &testMethod) { + if (!testMethod.initFunction.empty()) { + strFunctionCall(testMethod.initFunction, {}); + } + } + + void Printer::genTearDownCall(const tests::Tests::MethodDescription &testMethod) { + if (!testMethod.teardownFunction.empty()) { + strFunctionCall(testMethod.teardownFunction, {}); + } + } } diff --git a/server/src/printers/Printer.h b/server/src/printers/Printer.h index 792a2efc7..73795d860 100644 --- a/server/src/printers/Printer.h +++ b/server/src/printers/Printer.h @@ -53,8 +53,8 @@ namespace printer { inline std::string LINE_INDENT() const { std::string tabs = StringUtils::repeat(TAB, tabsDepth); return commentDepth <= 0 - ? tabs - : tabs + "// "; + ? tabs + : tabs + "// "; } // all functions which return std::stringstream start with `str` prefix. @@ -63,7 +63,8 @@ namespace printer { Stream strDefine(std::string_view from, std::string_view to); Stream strInclude(SRef header, bool isAngled = false); - Stream strInclude(const Include& include); + + Stream strInclude(const Include &include); Stream strIncludeSystem(SRef header); @@ -87,7 +88,7 @@ namespace printer { C }; - Stream strDeclareArrayVar(const types::Type& type, + Stream strDeclareArrayVar(const types::Type &type, std::string_view name, types::PointerUsage usage, std::optional value = std::nullopt, @@ -99,19 +100,19 @@ namespace printer { Stream strAssignVar(std::string_view name, std::string_view value); - std::stringstream& checkOverflowStubArray(const std::string &cntCall); + std::stringstream &checkOverflowStubArray(const std::string &cntCall); Stream strTabIf(bool needTabs); Stream strFunctionDecl( - SRef returnType, - SRef functionName, - std::vector const& paramTypes = {}, - VSRef paramValues = {}, - SRef end = SCNL, - VSRef modifiers = {}, - const tests::Tests::MethodDescription::FPointerMap &fullDeclSubstitutions = {}, - bool isVariadic = false); + SRef returnType, + SRef functionName, + std::vector const ¶mTypes = {}, + VSRef paramValues = {}, + SRef end = SCNL, + VSRef modifiers = {}, + const tests::Tests::MethodDescription::FPointerMap &fullDeclSubstitutions = {}, + bool isVariadic = false); Stream strFunctionDecl(const Tests::MethodDescription &method, SRef end = SCNL, @@ -162,7 +163,7 @@ namespace printer { std::optional castType = std::nullopt); template - static std::string concat(Args&&... args) { + static std::string concat(Args &&... args) { std::stringstream cc_ss; (cc_ss << ... << args); return cc_ss.str(); @@ -205,17 +206,17 @@ namespace printer { const std::string &end = "", bool needTabs = true); - void writeStubsForFunctionParams(const types::TypesHandler* typesHandler, - const Tests::MethodDescription& testMethod, + void writeStubsForFunctionParams(const types::TypesHandler *typesHandler, + const Tests::MethodDescription &testMethod, bool forKlee); - void writeExternForSymbolicStubs(const Tests::MethodDescription& testMethod); + void writeExternForSymbolicStubs(const Tests::MethodDescription &testMethod); void writeStubsForStructureFields(const Tests &tests); void writeStubsForParameters(const Tests &tests); - void writeStubForParam(const types::TypesHandler* typesHandler, + void writeStubForParam(const types::TypesHandler *typesHandler, const std::shared_ptr &fInfo, const std::string &methodName, const std::string &stubName, bool needToTypedef, bool makeStatic); @@ -233,7 +234,11 @@ namespace printer { const types::Field &fieldName, const std::string &stubName); - static std::string getConstQualifier(const types::Type& type); + static std::string getConstQualifier(const types::Type &type); + + void genInitCall(const tests::Tests::MethodDescription &testMethod); + + void genTearDownCall(const tests::Tests::MethodDescription &testMethod); private: Stream strMemcpyImpl(std::string_view dest, std::string_view src, bool needDereference); diff --git a/server/src/printers/TestsPrinter.cpp b/server/src/printers/TestsPrinter.cpp index 9f36f01e3..7248ee515 100644 --- a/server/src/printers/TestsPrinter.cpp +++ b/server/src/printers/TestsPrinter.cpp @@ -139,15 +139,16 @@ void TestsPrinter::printFinalCodeAndAlterJson(Tests &tests) { } } -std::uint32_t TestsPrinter::printSuiteAndReturnMethodsCount(const std::string &suiteName, const Tests::MethodsMap &methods) { - if (std::all_of(methods.begin(), methods.end(), [&suiteName](const auto& method) { +std::uint32_t +TestsPrinter::printSuiteAndReturnMethodsCount(const std::string &suiteName, const Tests::MethodsMap &methods) { + if (std::all_of(methods.begin(), methods.end(), [&suiteName](const auto &method) { return method.second.codeText.at(suiteName).empty(); })) { return 0; } ss << "#pragma region " << suiteName << printer::NL; std::uint32_t count = 0; - for (const auto &[methodName, methodDescription] : methods) { + for (const auto &[methodName, methodDescription]: methods) { if (methodDescription.codeText.at(suiteName).empty()) { continue; } @@ -159,12 +160,12 @@ std::uint32_t TestsPrinter::printSuiteAndReturnMethodsCount(const std::string &s } void TestsPrinter::genCode(Tests::MethodDescription &methodDescription, - const std::optional& predicateInfo, + const std::optional &predicateInfo, bool verbose, ErrorMode errorMode) { resetStream(); - if(needDecorate()) { + if (needDecorate()) { methodDescription.name = KleeUtils::getRenamedOperator(methodDescription.name); } @@ -196,10 +197,10 @@ static std::string getTestName(const Tests::MethodDescription &methodDescription std::string renamedMethodDescription = KleeUtils::getRenamedOperator(methodDescription.name); StringUtils::replaceColon(renamedMethodDescription); std::string testBaseName = methodDescription.isClassMethod() - ? StringUtils::stringFormat("%s_%s", - methodDescription.classObj->type.typeName(), - renamedMethodDescription) - : renamedMethodDescription; + ? StringUtils::stringFormat("%s_%s", + methodDescription.classObj->type.typeName(), + renamedMethodDescription) + : renamedMethodDescription; return printer::Printer::concat(testBaseName, Paths::TEST_SUFFIX, testNum); } @@ -210,11 +211,11 @@ void TestsPrinter::genCodeBySuiteName(const std::string &targetSuiteName, bool verbose, int &testNum, ErrorMode errorMode) { - const auto& testCases = methodDescription.suiteTestCases[targetSuiteName]; + const auto &testCases = methodDescription.suiteTestCases[targetSuiteName]; if (testCases.empty()) { return; } - for (int testCaseIndex : testCases) { + for (int testCaseIndex: testCases) { ++testNum; Tests::MethodTestCase &testCase = methodDescription.testCases[testCaseIndex]; testCase.testName = getTestName(methodDescription, testNum); @@ -225,6 +226,8 @@ void TestsPrinter::genCodeBySuiteName(const std::string &targetSuiteName, } else { genParametrizedTestCase(methodDescription, testCase, predicateInfo, errorMode); } + genTearDownCall(methodDescription); + ss << RB() << printer::NL; } methodDescription.codeText[targetSuiteName] = ss.str(); @@ -263,7 +266,6 @@ void TestsPrinter::genVerboseTestCase(const Tests::MethodDescription &methodDesc ss << printer::NL; TestsPrinter::verboseAsserts(methodDescription, testCase, predicateInfo); } - ss << RB() << printer::NL; } void TestsPrinter::initializeFiles(const Tests::MethodDescription &methodDescription, @@ -377,6 +379,7 @@ void TestsPrinter::genParametrizedTestCase(const Tests::MethodDescription &metho initializeFiles(methodDescription, testCase); openFiles(methodDescription, testCase); parametrizedInitializeGlobalVariables(methodDescription, testCase); + genInitCall(methodDescription); parametrizedInitializeSymbolicStubs(methodDescription, testCase); printStubVariablesForParam(methodDescription, testCase); printClassObject(methodDescription, testCase); @@ -384,7 +387,6 @@ void TestsPrinter::genParametrizedTestCase(const Tests::MethodDescription &metho printLazyVariables(methodDescription, testCase, false); printLazyReferences(methodDescription, testCase, false); parametrizedAsserts(methodDescription, testCase, predicateInfo, errorMode); - ss << RB() << printer::NL; } void TestsPrinter::genHeaders(Tests &tests, const fs::path& generatedHeaderPath) { @@ -457,6 +459,8 @@ void TestsPrinter::verboseParameters(const Tests::MethodDescription &methodDescr ss << printer::NL; } + genInitCall(methodDescription); + std::vector> types = {testCase.stubValuesTypes, testCase.stubParamTypes}; std::vector> values = {testCase.stubValues, testCase.stubParamValues}; diff --git a/server/src/testgens/BaseTestGen.h b/server/src/testgens/BaseTestGen.h index 852ac23dc..a3686c9d8 100644 --- a/server/src/testgens/BaseTestGen.h +++ b/server/src/testgens/BaseTestGen.h @@ -35,9 +35,9 @@ class BaseTestGen { virtual std::string toString() = 0; - bool needToBeMocked() const; + [[nodiscard]] bool needToBeMocked() const; - bool isBatched() const; + [[nodiscard]] bool isBatched() const; void setTargetPath(fs::path _targetPath); diff --git a/server/src/types/TypesResolver.cpp b/server/src/types/TypesResolver.cpp index 3f2ff4f9b..068e1ed89 100644 --- a/server/src/types/TypesResolver.cpp +++ b/server/src/types/TypesResolver.cpp @@ -105,7 +105,7 @@ void TypesResolver::resolveStructEx(const clang::RecordDecl *D, const std::strin fs::path filename = sourceManager.getFilename(sourceManager.getSpellingLoc(D->getLocation())).str(); fs::path sourceFilePath = ClangUtils::getSourceFilePath(sourceManager); - structInfo.filePath = Paths::getCCJsonFileFullPath(filename, parent->buildRootPath); + structInfo.filePath = Paths::getFileFullPath(filename, parent->buildRootPath); structInfo.name = getFullname(D, canonicalType, id, sourceFilePath); structInfo.hasAnonymousStructOrUnion = false; if (Paths::getSourceLanguage(sourceFilePath) == utbot::Language::CXX) { @@ -239,7 +239,7 @@ void TypesResolver::resolveEnum(const clang::EnumDecl *EN, const std::string &na types::EnumInfo enumInfo; fs::path sourceFilePath = ClangUtils::getSourceFilePath(sourceManager); enumInfo.name = getFullname(EN, canonicalType, id, sourceFilePath); - enumInfo.filePath = Paths::getCCJsonFileFullPath( + enumInfo.filePath = Paths::getFileFullPath( sourceManager.getFilename(EN->getLocation()).str(), parent->buildRootPath.string()); clang::QualType promotionType = EN->getPromotionType(); enumInfo.size = context.getTypeSize(promotionType); diff --git a/server/src/utils/CLIUtils.cpp b/server/src/utils/CLIUtils.cpp index 2d7e8d0cd..e851d35fc 100644 --- a/server/src/utils/CLIUtils.cpp +++ b/server/src/utils/CLIUtils.cpp @@ -47,10 +47,11 @@ std::unique_ptr createProjectContextByOptions(const ProjectContextOptionGroup &projectContextOptions) { fs::path projectPath = projectContextOptions.getProjectPath(); fs::path testDir = - Paths::normalizedTrimmed(projectPath / projectContextOptions.getTestDirectory()); + Paths::normalizedTrimmed(projectPath / projectContextOptions.getTestDirectory()); auto projectContext = - GrpcUtils::createProjectContext(projectContextOptions.getProjectName(), projectPath, - testDir, projectContextOptions.getBuildDirectory()); + GrpcUtils::createProjectContext(projectContextOptions.getProjectName(), projectPath, + testDir, projectContextOptions.getBuildDirectory(), + projectContextOptions.getItfPath()); return projectContext; } diff --git a/server/src/utils/DynamicLibraryUtils.cpp b/server/src/utils/DynamicLibraryUtils.cpp index 6f6dd3065..1f94d6e2b 100644 --- a/server/src/utils/DynamicLibraryUtils.cpp +++ b/server/src/utils/DynamicLibraryUtils.cpp @@ -14,7 +14,7 @@ namespace DynamicLibraryUtils { const fs::path &directory) { if (StringUtils::startsWith(argument, libraryDirOption)) { fs::path relativePath = argument.substr(libraryDirOption.length()); - fs::path absolutePath = Paths::getCCJsonFileFullPath(relativePath, directory); + fs::path absolutePath = Paths::getFileFullPath(relativePath, directory); return absolutePath; } return std::nullopt; diff --git a/server/src/utils/GrpcUtils.cpp b/server/src/utils/GrpcUtils.cpp index c862856eb..955299100 100644 --- a/server/src/utils/GrpcUtils.cpp +++ b/server/src/utils/GrpcUtils.cpp @@ -20,12 +20,14 @@ namespace GrpcUtils { createProjectContext(const std::string &projectName, const fs::path &projectPath, const fs::path &testDirPath, - const fs::path &buildDirRelativePath) { + const fs::path &buildDirRelativePath, + const fs::path &itfPath) { auto result = std::make_unique(); result->set_projectname(projectName); result->set_projectpath(projectPath); result->set_testdirpath(testDirPath); result->set_builddirrelativepath(buildDirRelativePath); + result->set_itfpath(itfPath); return result; } @@ -60,7 +62,7 @@ namespace GrpcUtils { auto result = std::make_unique(); result->set_allocated_projectcontext(projectContext.release()); result->set_allocated_settingscontext(settingsContext.release()); - for (const auto &path : sourcePaths) { + for (const auto &path: sourcePaths) { result->add_sourcepaths(path); } if (target.has_value()) { @@ -191,7 +193,7 @@ namespace GrpcUtils { projectTarget.set_name(output.filename()); projectTarget.set_path(output); fs::path description = - fs::relative(output, projectContext.projectPath / projectContext.buildDirRelativePath); + fs::relative(output, projectContext.projectPath / projectContext.buildDirRelativePath); projectTarget.set_description(description); } diff --git a/server/src/utils/GrpcUtils.h b/server/src/utils/GrpcUtils.h index 0f22a62f4..cdd55505d 100644 --- a/server/src/utils/GrpcUtils.h +++ b/server/src/utils/GrpcUtils.h @@ -19,7 +19,8 @@ namespace GrpcUtils { createProjectContext(const std::string &projectName, const fs::path &projectPath, const fs::path &testDirPath, - const fs::path &buildDirRelativePath); + const fs::path &buildDirRelativePath, + const fs::path &itfPath); std::unique_ptr createSettingsContext(bool generateForStaticFunctions, diff --git a/server/test/framework/Library_Test.cpp b/server/test/framework/Library_Test.cpp index 21d63481e..b54eb7cbf 100644 --- a/server/test/framework/Library_Test.cpp +++ b/server/test/framework/Library_Test.cpp @@ -20,7 +20,7 @@ namespace { std::pair createTestForFunction(const fs::path &pathToFile, int lineNum, int kleeTimeout = 60) { auto lineRequest = testUtils::createLineRequest(projectName, suitePath, buildDirRelativePath, - srcPaths, pathToFile, lineNum, + srcPaths, pathToFile, lineNum, "", pathToFile, true, false, kleeTimeout); auto request = GrpcUtils::createFunctionRequest(std::move(lineRequest)); diff --git a/server/test/framework/Regression_Tests.cpp b/server/test/framework/Regression_Tests.cpp index 0a13f8bbf..3e9bde527 100644 --- a/server/test/framework/Regression_Tests.cpp +++ b/server/test/framework/Regression_Tests.cpp @@ -28,7 +28,7 @@ namespace { std::pair createTestForFunction(const fs::path &pathToFile, int lineNum, bool verbose = true) { auto lineRequest = testUtils::createLineRequest(projectName, suitePath, buildDirRelativePath, - srcPaths, pathToFile, lineNum, + srcPaths, pathToFile, lineNum, "", pathToFile, false, verbose, 0); auto request = GrpcUtils::createFunctionRequest(std::move(lineRequest)); auto testGen = FunctionTestGen(*request, writer.get(), TESTMODE); @@ -40,7 +40,7 @@ namespace { std::pair createTestForFolder(const fs::path &pathToFolder, bool useStubs = true, bool verbose = true) { auto folderRequest = testUtils::createProjectRequest(projectName, suitePath, buildDirRelativePath, - srcPaths, GrpcUtils::UTBOT_AUTO_TARGET_PATH, useStubs, + srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, useStubs, verbose, 0); auto request = GrpcUtils::createFolderRequest(std::move(folderRequest), pathToFolder); auto testGen = FolderTestGen(*request, writer.get(), TESTMODE); @@ -89,7 +89,7 @@ namespace { TEST_F(Regression_Test, Incomplete_Array_Type) { fs::path folderPath = suitePath / "SAT-760"; auto projectRequest = testUtils::createProjectRequest( - projectName, suitePath, buildDirRelativePath, { suitePath, folderPath }, "SAT-760"); + projectName, suitePath, buildDirRelativePath, { suitePath, folderPath }, "", "SAT-760"); auto request = GrpcUtils::createFolderRequest(std::move(projectRequest), folderPath); auto testGen = FolderTestGen(*request, writer.get(), TESTMODE); diff --git a/server/test/framework/Server_Tests.cpp b/server/test/framework/Server_Tests.cpp index 7f2652d29..2b757ebe8 100644 --- a/server/test/framework/Server_Tests.cpp +++ b/server/test/framework/Server_Tests.cpp @@ -60,7 +60,7 @@ namespace { fs::path testsDirPath = getTestFilePath(testsRelativeDir); auto projectContext = GrpcUtils::createProjectContext( - projectName, suitePath, testsDirPath, buildDirRelativePath); + projectName, suitePath, testsDirPath, buildDirRelativePath, ""); auto settingsContext = GrpcUtils::createSettingsContext(true, false, 30, 0, false, false, ErrorMode::PASSING, false, false); @@ -701,7 +701,7 @@ namespace { TEST_F(Server_Test, Char_Literals_Test) { std::string suite = "char"; setSuite(suite); - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); @@ -724,7 +724,7 @@ namespace { fs::path b_c = getTestFilePath("b.c"); fs::path main_c = getTestFilePath("main.c"); { - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "ex"); + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", "ex"); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); Status status = Server::TestsGenServiceImpl::ProcessBaseTestRequest(testGen, writer.get()); @@ -742,7 +742,7 @@ namespace { } })); } { - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "one"); + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", "one"); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); Status status = Server::TestsGenServiceImpl::ProcessBaseTestRequest(testGen, writer.get()); @@ -757,7 +757,7 @@ namespace { } { auto request = - createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "two"); + createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", "two"); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); Status status = Server::TestsGenServiceImpl::ProcessBaseTestRequest(testGen, writer.get()); @@ -777,7 +777,7 @@ namespace { TEST_F(Server_Test, Datacom_Test) { std::string suite = "datacom"; setSuite(suite); - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); @@ -821,7 +821,7 @@ namespace { TEST_F(Server_Test, Different_Variables_False) { auto projectRequest = - createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, true, 60, ErrorMode::PASSING, false); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), different_variables_c); auto testGen = FileTestGen(*request, writer.get(), TESTMODE); @@ -832,7 +832,7 @@ namespace { TEST_F(Server_Test, Different_Variables_True) { auto projectRequest = - createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, true, 60, ErrorMode::PASSING, true); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), different_variables_c); auto testGen = FileTestGen(*request, writer.get(), TESTMODE); @@ -994,7 +994,7 @@ namespace { std::string suite = "small-project"; setSuite(suite); srcPaths = {suitePath, suitePath / "lib", suitePath / "src"}; - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); @@ -1015,7 +1015,7 @@ namespace { std::string suite = "small-project"; setSuite(suite); srcPaths = {}; - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); @@ -1039,7 +1039,7 @@ namespace { std::string suite = "small-project"; setSuite(suite); srcPaths = { suitePath / "lib"}; - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); @@ -1072,7 +1072,7 @@ namespace { } TEST_P(Parameterized_Server_Test, Folder_Test) { - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH); auto request = GrpcUtils::createFolderRequest(std::move(projectRequest), suitePath / "inner"); auto testGen = FolderTestGen(*request, writer.get(), TESTMODE); @@ -1085,7 +1085,7 @@ namespace { TEST_P(Parameterized_Server_Test, Line_Test1) { auto request = createLineRequest(projectName, suitePath, buildDirRelativePath, srcPaths, - basic_functions_c, 17, GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); + basic_functions_c, 17, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); auto testGen = LineTestGen(*request, writer.get(), TESTMODE); Status status = Server::TestsGenServiceImpl::ProcessBaseTestRequest(testGen, writer.get()); ASSERT_TRUE(status.ok()) << status.error_message(); @@ -1101,7 +1101,7 @@ namespace { TEST_P(Parameterized_Server_Test, Line_Test2) { auto request = createLineRequest(projectName, suitePath, buildDirRelativePath, srcPaths, - basic_functions_c, 17, GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); + basic_functions_c, 17, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); auto testGen = LineTestGen(*request, writer.get(), TESTMODE); Status status = Server::TestsGenServiceImpl::ProcessBaseTestRequest(testGen, writer.get()); ASSERT_TRUE(status.ok()) << status.error_message(); @@ -1160,7 +1160,7 @@ namespace { TEST_P(Parameterized_Server_Test, Function_Test) { auto lineRequest = createLineRequest(projectName, suitePath, buildDirRelativePath, srcPaths, - basic_functions_c, 6, GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); + basic_functions_c, 6, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); auto request = GrpcUtils::createFunctionRequest(std::move(lineRequest)); auto testGen = FunctionTestGen(*request, writer.get(), TESTMODE); @@ -1187,7 +1187,7 @@ namespace { TEST_P(Parameterized_Server_Test, Predicate_Test_Integer) { auto lineRequest = createLineRequest(projectName, suitePath, buildDirRelativePath, srcPaths, - basic_functions_c, 17, GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); + basic_functions_c, 17, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); auto predicateInfo = std::make_unique(); predicateInfo->set_predicate("=="); predicateInfo->set_returnvalue("36"); @@ -1209,7 +1209,7 @@ namespace { TEST_P(Parameterized_Server_Test, Predicate_Test_Str) { auto lineRequest = createLineRequest(projectName, suitePath, buildDirRelativePath, srcPaths, - basic_functions_c, 32, GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); + basic_functions_c, 32, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); auto predicateInfo = std::make_unique(); predicateInfo->set_predicate("=="); predicateInfo->set_returnvalue("abacaba"); @@ -1232,7 +1232,7 @@ namespace { TEST_P(Parameterized_Server_Test, Symbolic_Stdin_Test) { auto request = std::make_unique(); auto lineRequest = createLineRequest(projectName, suitePath, buildDirRelativePath, srcPaths, - symbolic_stdin_c, 8, GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); + symbolic_stdin_c, 8, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); request->set_allocated_linerequest(lineRequest.release()); auto testGen = FunctionTestGen(*request, writer.get(), TESTMODE); @@ -1253,7 +1253,7 @@ namespace { TEST_P(Parameterized_Server_Test, Symbolic_Stdin_Long_Read) { auto request = std::make_unique(); auto lineRequest = createLineRequest(projectName, suitePath, buildDirRelativePath, srcPaths, - symbolic_stdin_c, 19, GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); + symbolic_stdin_c, 19, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 0); request->set_allocated_linerequest(lineRequest.release()); auto testGen = FunctionTestGen(*request, writer.get(), TESTMODE); @@ -1289,7 +1289,7 @@ namespace { testDirPath = getTestFilePath(pregeneratedTestsRelativeDir); projectContext = std::make_unique( - projectName, suitePath, testDirPath, buildDirRelativePath, clientProjectPath); + projectName, suitePath, testDirPath, buildDirRelativePath, clientProjectPath, ""); basic_functions_c = getTestFilePath("basic_functions.c"); simple_loop_uncovered_c = getTestFilePath("simple_loop_uncovered.c"); @@ -1531,7 +1531,7 @@ namespace { std::string suite = "object-file"; setSuite(suite); static const std::string source2_c = getTestFilePath("source2.c"); - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 30, ErrorMode::FAILING); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), source2_c); auto testGen = FileTestGen(*request, writer.get(), TESTMODE); @@ -1568,13 +1568,13 @@ namespace { std::string suite = "precompiled"; setSuite(suite); static const std::string source_c = getTestFilePath("source.c"); - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 30, ErrorMode::FAILING, false, false); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), source_c); EXPECT_THROW(FileTestGen(*request, writer.get(), TESTMODE), CompilationDatabaseException); - projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 30, ErrorMode::FAILING, false, true); request = GrpcUtils::createFileRequest(std::move(projectRequest), source_c); @@ -1590,7 +1590,7 @@ namespace { std::string suite = "linkage-ld"; setSuite(suite); static const std::string issue_c = getTestFilePath("issue-638.c"); - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 30, ErrorMode::FAILING); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), issue_c); auto testGen = FileTestGen(*request, writer.get(), TESTMODE); @@ -1632,7 +1632,7 @@ namespace { testUtils::BuildCommandsTool::BEAR_BUILD_COMMANDS_TOOL, true); static const std::string methods_with_asserts_cpp = getTestFilePath("methods_with_asserts.cpp"); - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 30, ErrorMode::FAILING); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), methods_with_asserts_cpp); @@ -1644,7 +1644,7 @@ namespace { testUtils::checkMinNumberOfTests(testGen.tests, 11); auto projectContext = std::make_unique(projectName, suitePath, suitePath / "tests", - buildDirRelativePath, clientProjectPath); + buildDirRelativePath, clientProjectPath, ""); auto testFilter = GrpcUtils::createTestFilterForFile( Paths::sourcePathToTestPath(*projectContext, methods_with_asserts_cpp)); auto runRequest = createCoverageAndResultsRequest( @@ -1680,7 +1680,7 @@ namespace { testUtils::BuildCommandsTool::BEAR_BUILD_COMMANDS_TOOL, true); static const std::string methods_with_asserts_cpp = getTestFilePath("methods_with_asserts.cpp"); - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 30, ErrorMode::PASSING); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), methods_with_asserts_cpp); @@ -1692,7 +1692,7 @@ namespace { testUtils::checkMinNumberOfTests(testGen.tests, 11); auto projectContext = std::make_unique(projectName, suitePath, suitePath / "tests", - buildDirRelativePath, clientProjectPath); + buildDirRelativePath, clientProjectPath, ""); auto testFilter = GrpcUtils::createTestFilterForFile( Paths::sourcePathToTestPath(*projectContext, methods_with_asserts_cpp)); auto runRequest = createCoverageAndResultsRequest( @@ -1726,7 +1726,7 @@ namespace { testUtils::BuildCommandsTool::BEAR_BUILD_COMMANDS_TOOL, true); static const std::string methods_with_exceptions_cpp = getTestFilePath("methods_with_exceptions.cpp"); - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 30, ErrorMode::FAILING); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), methods_with_exceptions_cpp); @@ -1738,7 +1738,7 @@ namespace { testUtils::checkMinNumberOfTests(testGen.tests, 8); auto projectContext = std::make_unique(projectName, suitePath, suitePath / "tests", - buildDirRelativePath, clientProjectPath); + buildDirRelativePath, clientProjectPath, ""); auto testFilter = GrpcUtils::createTestFilterForFile( Paths::sourcePathToTestPath(*projectContext, methods_with_exceptions_cpp)); auto runRequest = createCoverageAndResultsRequest( @@ -1772,7 +1772,7 @@ namespace { testUtils::BuildCommandsTool::BEAR_BUILD_COMMANDS_TOOL, true); static const std::string methods_with_exceptions_cpp = getTestFilePath("methods_with_exceptions.cpp"); - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, false, false, 30, ErrorMode::PASSING); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), methods_with_exceptions_cpp); @@ -1784,7 +1784,7 @@ namespace { testUtils::checkMinNumberOfTests(testGen.tests, 8); auto projectContext = std::make_unique(projectName, suitePath, suitePath / "tests", - buildDirRelativePath, clientProjectPath); + buildDirRelativePath, clientProjectPath, ""); auto testFilter = GrpcUtils::createTestFilterForFile( Paths::sourcePathToTestPath(*projectContext, methods_with_exceptions_cpp)); auto runRequest = createCoverageAndResultsRequest( @@ -1890,7 +1890,7 @@ namespace { TEST_P(Parameterized_Server_Test, Clang_Resources_Directory_Test) { std::string suite = "stddef"; setSuite(suite); - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); @@ -1903,7 +1903,7 @@ namespace { TEST_P(Parameterized_Server_Test, Installed_Dependency_Test) { std::string suite = "installed"; setSuite(suite); - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); @@ -1920,7 +1920,7 @@ namespace { std::string suite = "small-project"; setSuite(suite); srcPaths = {}; - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); @@ -1941,7 +1941,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path linked_list_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), linked_list_c); auto testFilter = GrpcUtils::createTestFilterForFile(linked_list_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( @@ -1979,7 +1979,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path tree_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), tree_c); auto testFilter = GrpcUtils::createTestFilterForFile(tree_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( @@ -2019,7 +2019,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path complex_structs_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), complex_structs_c); auto testFilter = GrpcUtils::createTestFilterForFile(complex_structs_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( @@ -2072,7 +2072,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path input_output_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), input_output_c); auto testFilter = GrpcUtils::createTestFilterForFile(input_output_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( @@ -2110,7 +2110,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path file_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), file_c); auto testFilter = GrpcUtils::createTestFilterForFile(file_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( @@ -2148,7 +2148,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path hard_linked_list_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), hard_linked_list_c); auto testFilter = GrpcUtils::createTestFilterForFile(hard_linked_list_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( @@ -2186,7 +2186,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path multi_dim_pointers_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), multi_dim_pointers_c); auto testFilter = GrpcUtils::createTestFilterForFile(multi_dim_pointers_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( @@ -2224,7 +2224,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path struct_with_union_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), struct_with_union_c); auto testFilter = GrpcUtils::createTestFilterForFile(struct_with_union_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( @@ -2262,7 +2262,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path structs_with_pointers_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), structs_with_pointers_c); auto testFilter = GrpcUtils::createTestFilterForFile(structs_with_pointers_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( @@ -2300,7 +2300,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path thread_local_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), thread_local_c); auto testFilter = GrpcUtils::createTestFilterForFile(thread_local_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( diff --git a/server/test/framework/Stub_Tests.cpp b/server/test/framework/Stub_Tests.cpp index d815025da..1849ec70b 100644 --- a/server/test/framework/Stub_Tests.cpp +++ b/server/test/framework/Stub_Tests.cpp @@ -37,7 +37,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); utbot::ProjectContext projectContext{projectName, suitePath, testsDirPath, - buildDirRelativePath, clientProjectPath}; + buildDirRelativePath, clientProjectPath, ""}; fs::path sum_test_cpp = Paths::sourcePathToTestPath(projectContext, calc_sum_c); fs::path foreign_bar_test_cpp = @@ -117,7 +117,7 @@ namespace { TEST_F(Stub_Test, Project_Stubs_Test) { auto stubsWriter = std::make_unique(nullptr, false); - auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, + auto request = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", GrpcUtils::UTBOT_AUTO_TARGET_PATH, true); auto testGen = std::make_unique(*request, writer.get(), TESTMODE); std::vector stubSources = {calc_sum_c, calc_mult_c, literals_foo_c}; @@ -163,7 +163,7 @@ namespace { TEST_F(Stub_Test, Multimodule_Lib_Heuristic_Test) { auto request = testUtils::createProjectRequest(projectName, suitePath, buildDirRelativePath, - {foreign, calc, suitePath, literals}, + {foreign, calc, suitePath, literals}, "", foreign_bar_c, true); auto testGen = ProjectTestGen(*request, writer.get(), TESTMODE); Status status = Server::TestsGenServiceImpl::ProcessBaseTestRequest(testGen, writer.get()); @@ -342,7 +342,7 @@ namespace { fs::path testsDirPath = getTestFilePath("tests"); fs::path function_pointers_test_cpp = Paths::sourcePathToTestPath( - utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath), + utbot::ProjectContext(projectName, suitePath, testsDirPath, buildDirRelativePath, clientProjectPath, ""), function_pointers_c); auto testFilter = GrpcUtils::createTestFilterForFile(function_pointers_test_cpp); auto runRequest = testUtils::createCoverageAndResultsRequest( diff --git a/server/test/framework/Syntax_Tests.cpp b/server/test/framework/Syntax_Tests.cpp index bb70bdd99..420ce473f 100644 --- a/server/test/framework/Syntax_Tests.cpp +++ b/server/test/framework/Syntax_Tests.cpp @@ -64,6 +64,7 @@ namespace { fs::path rvalue_reference_cpp = getTestFilePath("function_with_rvalue_params.cpp"); fs::path hard_linked_list_c = getTestFilePath("hard_linked_list.c"); fs::path unsupported_class_cpp = getTestFilePath("unsupported_class.cpp"); + fs::path inits_c = getTestFilePath("inits.c"); void SetUp() override { clearEnv(CompilationUtils::CompilerName::CLANG); @@ -91,9 +92,9 @@ namespace { } std::pair createTestForFunction(const fs::path &pathToFile, - int lineNum, int kleeTimeout = 60) { + int lineNum, int kleeTimeout = 60, fs::path ithPath = "") { auto lineRequest = createLineRequest(projectName, suitePath, buildDirRelativePath, - srcPaths, pathToFile, lineNum, pathToFile, + srcPaths, pathToFile, lineNum, ithPath, pathToFile, false, false, kleeTimeout); auto request = GrpcUtils::createFunctionRequest(std::move(lineRequest)); auto testGen = FunctionTestGen(*request, writer.get(), TESTMODE); @@ -3667,25 +3668,39 @@ namespace { ASSERT_TRUE(status.ok()) << status.error_message(); checkTestCasePredicates( - testGen.tests.at(hard_linked_list_c).methods.begin().value().testCases, - std::vector( - { [](const tests::Tests::MethodTestCase &testCase) { - return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == -1; - }, - [](const tests::Tests::MethodTestCase &testCase) { - return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 1; - }, - [](const tests::Tests::MethodTestCase &testCase) { - return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == -2; - }, - [](const tests::Tests::MethodTestCase &testCase) { - return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 2; - }, - [](const tests::Tests::MethodTestCase &testCase) { - return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == -3; - }, - [](const tests::Tests::MethodTestCase &testCase) { - return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 3; - } })); + testGen.tests.at(hard_linked_list_c).methods.begin().value().testCases, + std::vector( + {[](const tests::Tests::MethodTestCase &testCase) { + return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == -1; + }, + [](const tests::Tests::MethodTestCase &testCase) { + return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 1; + }, + [](const tests::Tests::MethodTestCase &testCase) { + return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == -2; + }, + [](const tests::Tests::MethodTestCase &testCase) { + return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 2; + }, + [](const tests::Tests::MethodTestCase &testCase) { + return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == -3; + }, + [](const tests::Tests::MethodTestCase &testCase) { + return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 3; + }})); + } + + TEST_F(Syntax_Test, init_function) { + auto [testGen, status] = createTestForFunction(inits_c, 8, 60, "itf.json"); + + ASSERT_TRUE(status.ok()) << status.error_message(); + + testUtils::checkNumberOfTestsInFile(testGen, inits_c, 1); + checkTestCasePredicates( + testGen.tests.at(inits_c).methods.begin().value().testCases, + std::vector( + {[](const tests::Tests::MethodTestCase &testCase) { + return stoi(testCase.returnValue.view->getEntryValue(nullptr)) == 42; + }})); } } diff --git a/server/test/framework/Targets_Test.cpp b/server/test/framework/Targets_Test.cpp index 5fc2e13d3..879cc4805 100644 --- a/server/test/framework/Targets_Test.cpp +++ b/server/test/framework/Targets_Test.cpp @@ -22,7 +22,7 @@ using namespace testUtils; TEST_F(TargetsTest, Valid_Target_Test_ls) { auto projectRequest = - createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "ls"); + createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", "ls"); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), parse_c); auto testGen = FileTestGen(*request, writer.get(), TESTMODE); @@ -41,7 +41,7 @@ TEST_F(TargetsTest, Valid_Target_Test_ls) { TEST_F(TargetsTest, Valid_Target_Test_cat) { auto projectRequest = - createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "cat"); + createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", "cat"); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), parse_c); auto testGen = FileTestGen(*request, writer.get(), TESTMODE); @@ -59,7 +59,7 @@ TEST_F(TargetsTest, Valid_Target_Test_cat) { } TEST_F(TargetsTest, Valid_Target_Test_dummy) { - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "dummy"); + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, "", "dummy"); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), parse_c); auto testGen = FileTestGen(*request, writer.get(), TESTMODE); @@ -71,7 +71,7 @@ TEST_F(TargetsTest, Valid_Target_Test_dummy) { } TEST_F(TargetsTest, Valid_Target_Test_parse) { - auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths); + auto projectRequest = createProjectRequest(projectName, suitePath, buildDirRelativePath, srcPaths, ""); auto request = GrpcUtils::createFileRequest(std::move(projectRequest), parse_c); auto testGen = FileTestGen(*request, writer.get(), TESTMODE); @@ -89,7 +89,7 @@ TEST_F(TargetsTest, Valid_Target_Test_parse) { TEST_F(TargetsTest, Valid_Target_Test_get_10) { std::unique_ptr projectRequest = createProjectRequest( - projectName, suitePath, buildDirRelativePath, srcPaths, "get_10", false, false, 15); + projectName, suitePath, buildDirRelativePath, srcPaths, "", "get_10", false, false, 15); auto testGen = ProjectTestGen(*projectRequest.get(), writer.get(), TESTMODE, true); @@ -129,7 +129,7 @@ TEST_F(TargetsTest, Valid_Target_Test_get_10) { TEST_F(TargetsTest, Valid_Target_Test_get_20) { std::unique_ptr projectRequest = createProjectRequest( - projectName, suitePath, buildDirRelativePath, srcPaths, "get_20", false, false, 15); + projectName, suitePath, buildDirRelativePath, srcPaths, "", "get_20", false, false, 15); auto testGen = ProjectTestGen(*projectRequest.get(), writer.get(), TESTMODE, true); @@ -169,7 +169,7 @@ TEST_F(TargetsTest, Valid_Target_Test_get_20) { TEST_F(TargetsTest, Valid_Target_Test_get_10_2) { std::unique_ptr projectRequest = createProjectRequest( - projectName, suitePath, buildDirRelativePath, srcPaths, "get_10_2", false, false, 15); + projectName, suitePath, buildDirRelativePath, srcPaths, "", "get_10_2", false, false, 15); auto testGen = ProjectTestGen(*projectRequest.get(), writer.get(), TESTMODE, true); @@ -209,7 +209,7 @@ TEST_F(TargetsTest, Valid_Target_Test_get_10_2) { TEST_F(TargetsTest, Valid_Target_Test_libshared) { std::unique_ptr projectRequest = createProjectRequest( - projectName, suitePath, buildDirRelativePath, srcPaths, "libshared_get.so", false, false, 15); + projectName, suitePath, buildDirRelativePath, srcPaths, "", "libshared_get.so", false, false, 15); auto testGen = ProjectTestGen(*projectRequest.get(), writer.get(), TESTMODE, true); @@ -249,7 +249,7 @@ TEST_F(TargetsTest, Valid_Target_Test_libshared) { TEST_F(TargetsTest, Valid_Target_Test_get_libstatic) { std::unique_ptr projectRequest = createProjectRequest( - projectName, suitePath, buildDirRelativePath, srcPaths, "libstatic_get.a", false, false, 15); + projectName, suitePath, buildDirRelativePath, srcPaths, "", "libstatic_get.a", false, false, 15); auto testGen = ProjectTestGen(*projectRequest.get(), writer.get(), TESTMODE, true); diff --git a/server/test/framework/TestUtils.cpp b/server/test/framework/TestUtils.cpp index 439a82c69..b76c6200b 100644 --- a/server/test/framework/TestUtils.cpp +++ b/server/test/framework/TestUtils.cpp @@ -224,6 +224,7 @@ namespace testUtils { const fs::path &projectPath, const std::string &buildDirRelativePath, const std::vector &srcPaths, + const fs::path &itfPath, const std::string &targetOrSourcePath, bool useStubs, bool verbose, @@ -232,7 +233,7 @@ namespace testUtils { bool differentVariables, bool skipPrecompiled) { auto projectContext = GrpcUtils::createProjectContext( - projectName, projectPath, projectPath / "tests", buildDirRelativePath); + projectName, projectPath, projectPath / "tests", buildDirRelativePath, itfPath); auto settingsContext = GrpcUtils::createSettingsContext(true, verbose, kleeTimeout, 0, false, useStubs, errorMode, differentVariables, skipPrecompiled); @@ -253,7 +254,7 @@ namespace testUtils { int kleeTimeout, ErrorMode errorMode) { auto projectRequest = createProjectRequest(projectName, projectPath, buildDirRelativePath, - srcPaths, targetOrSourcePath, useStubs, verbose, kleeTimeout, errorMode); + srcPaths, "", targetOrSourcePath, useStubs, verbose, kleeTimeout, errorMode); return GrpcUtils::createFileRequest(std::move(projectRequest), filePath); } @@ -263,13 +264,14 @@ namespace testUtils { const std::vector &srcPaths, const fs::path &filePath, int line, + const fs::path &itfPath, const std::string &targetOrSourcePath, bool useStubs, bool verbose, int kleeTimeout, ErrorMode errorMode) { auto projectRequest = createProjectRequest(projectName, projectPath, buildDirRelativePath, - srcPaths, targetOrSourcePath, useStubs, verbose, kleeTimeout, errorMode); + srcPaths, itfPath, targetOrSourcePath, useStubs, verbose, kleeTimeout, errorMode); auto lineInfo = GrpcUtils::createSourceInfo(filePath, line); return GrpcUtils::createLineRequest(std::move(projectRequest), std::move(lineInfo)); } @@ -286,7 +288,7 @@ namespace testUtils { int kleeTimeout, ErrorMode errorMode) { auto lineRequest = createLineRequest(projectName, projectPath, buildDirRelativePath, - srcPaths, filePath, line, targetOrSourcePath, useStubs, verbose, kleeTimeout, errorMode); + srcPaths, filePath, line, "", targetOrSourcePath, useStubs, verbose, kleeTimeout, errorMode); return GrpcUtils::createClassRequest(std::move(lineRequest)); } @@ -295,7 +297,7 @@ namespace testUtils { const fs::path &filePath, ErrorMode errorMode) { auto projectContext = - GrpcUtils::createProjectContext(projectName, projectPath, projectPath / "tests", ""); + GrpcUtils::createProjectContext(projectName, projectPath, projectPath / "tests", "", ""); // we actually don't pass all parameters except test directory and project name on client auto settingsContext = GrpcUtils::createSettingsContext(true, true, 10, 0, true, false, errorMode, false, false); @@ -311,7 +313,7 @@ namespace testUtils { std::unique_ptr testFilter) { auto request = std::make_unique(); auto projectContext = GrpcUtils::createProjectContext(projectName, projectPath, testDirPath, - buildDirRelativePath); + buildDirRelativePath, ""); request->set_allocated_projectcontext(projectContext.release()); request->set_allocated_testfilter(testFilter.release()); request->set_coverage(true); diff --git a/server/test/framework/TestUtils.h b/server/test/framework/TestUtils.h index bbbf925c1..4c373c40d 100644 --- a/server/test/framework/TestUtils.h +++ b/server/test/framework/TestUtils.h @@ -73,6 +73,7 @@ namespace testUtils { const fs::path &projectPath, const std::string &buildDirRelativePath, const std::vector &srcPaths, + const fs::path &itfPath = "", const std::string &targetOrSourcePath = GrpcUtils::UTBOT_AUTO_TARGET_PATH, bool useStubs = false, bool verbose = true, @@ -98,6 +99,7 @@ namespace testUtils { const std::vector &srcPaths, const fs::path &filePath, int line, + const fs::path &itfPath = "", const std::string &targetOrSourcePath = GrpcUtils::UTBOT_AUTO_TARGET_PATH, bool useStubs = false, bool verbose = true, diff --git a/server/test/suites/syntax/CMakeLists.txt b/server/test/suites/syntax/CMakeLists.txt index 7631c4aaa..f469b8b9b 100644 --- a/server/test/suites/syntax/CMakeLists.txt +++ b/server/test/suites/syntax/CMakeLists.txt @@ -44,4 +44,6 @@ add_executable(syntax1 bitfields.c function_with_rvalue_params.cpp hard_linked_list.c - unsupported_class.cpp) + unsupported_class.cpp + inits.c +) diff --git a/server/test/suites/syntax/inits.c b/server/test/suites/syntax/inits.c new file mode 100644 index 000000000..f0c396819 --- /dev/null +++ b/server/test/suites/syntax/inits.c @@ -0,0 +1,12 @@ +int a; + +void _init_vals() { + a = 42; +} + +int init_global() { + if(a == 42) { + return 42; + } + return 0; +} diff --git a/server/test/suites/syntax/inits.h b/server/test/suites/syntax/inits.h new file mode 100644 index 000000000..fa9731800 --- /dev/null +++ b/server/test/suites/syntax/inits.h @@ -0,0 +1 @@ +bool init_global(); diff --git a/server/test/suites/syntax/itf.json b/server/test/suites/syntax/itf.json new file mode 100644 index 000000000..0717492a2 --- /dev/null +++ b/server/test/suites/syntax/itf.json @@ -0,0 +1,10 @@ +{ + "default init": "", + "default teardown": "", + "init": { + "init_global": "_init_vals" + }, + "teardown": { + "init_global": "" + } +} diff --git a/vscode-plugin/package.json b/vscode-plugin/package.json index 32121399e..1d9b5e46d 100644 --- a/vscode-plugin/package.json +++ b/vscode-plugin/package.json @@ -498,6 +498,11 @@ "default": "", "markdownDescription": "%unittestbot.paths.sourceDirectories.description%" }, + "unittestbot.paths.initialTeardownFunctions": { + "type": "string", + "default": "", + "markdownDescription": "%unittestbot.paths.initialTeardownFunctions.description%" + }, "unittestbot.testsGeneration.verboseFormatting": { "type": "boolean", "default": false, @@ -583,15 +588,15 @@ "@vscode/test-electron": "2.1.2", "eslint": "6.8.0", "glob": "7.2.0", - "mocha": "9.2.0" + "mocha": "^9.2.2" }, "dependencies": { "@types/google-protobuf": "3.15.5", "@types/node": "15.6.0", "@types/randomstring": "1.1.8", "@types/ssh2": "1.11.6", - "@types/vscode": "1.64.0", "@types/ssh2-streams": "0.1.9", + "@types/vscode": "1.64.0", "emittery": "0.10.1", "filepath": "1.1.0", "google-protobuf": "3.12.4", @@ -599,10 +604,10 @@ "grpc_tools_node_protoc_ts": "5.3.2", "grpc-tools": "1.11.2", "log4js": "6.5.2", + "node-ssh": "^13.0.0", "randomstring": "1.2.2", - "ssh2-streams": "0.4.10", "source-map-support": "0.5.21", - "typescript": "3.9.4", - "node-ssh": "^13.0.0" + "ssh2-streams": "0.4.10", + "typescript": "3.9.4" } } diff --git a/vscode-plugin/package.nls.json b/vscode-plugin/package.nls.json index f873fa05c..02feb680e 100644 --- a/vscode-plugin/package.nls.json +++ b/vscode-plugin/package.nls.json @@ -6,6 +6,7 @@ "unittestbot.paths.cmakeOptions.description": "Options passed to CMake command. [Learn more](https://github.com/UnitTestBot/UTBotCpp/wiki/vscode-extension-settings#cmake-options)", "unittestbot.paths.testsDirectory.description": "Relative path to directory in which tests will be generated. [Learn more](https://github.com/UnitTestBot/UTBotCpp/wiki/vscode-extension-settings#tests-directory)", "unittestbot.paths.sourceDirectories.description": "Relative paths to directories, that are marked as source directories. Please, prefer using UTBot Explorer View instead of raw settings. [Learn more](https://github.com/UnitTestBot/UTBotCpp/wiki/vscode-extension-settings#source-directories)", + "unittestbot.paths.initialTeardownFunctions.description": "Relative paths to json, that contains list of initial and teardown functions", "unittestbot.testsGeneration.verboseFormatting.description": "If set to true, tests will be formatted in more detailed form. [Learn more](https://github.com/UnitTestBot/UTBotCpp/wiki/vscode-extension-settings#verbose-formatting)", "unittestbot.testsGeneration.generateForStaticFunctions.description": "True, if you want UTBot to generate tests for static functions. [Learn more](https://github.com/UnitTestBot/UTBotCpp/wiki/vscode-extension-settings#generate-for-static-functions)", "unittestbot.testsGeneration.errorMode.description": "Choose the option: \"Failing\" means that error tests have runtime error, \"Passing\" means that no tests have runtime error.", diff --git a/vscode-plugin/src/client/client.ts b/vscode-plugin/src/client/client.ts index 492731705..2ea68200f 100644 --- a/vscode-plugin/src/client/client.ts +++ b/vscode-plugin/src/client/client.ts @@ -385,6 +385,7 @@ export class Client { projectName: string, projectPath: string, buildDirRelativePath: string, + itfPath: string, cmakeOptions: Array, configMode: ConfigMode, progressKey: utbotUI.ProgressKey, @@ -396,6 +397,7 @@ export class Client { projectContext.setProjectpath(projectPath); projectContext.setBuilddirrelativepath(buildDirRelativePath); projectContext.setClientprojectpath(vsUtils.getProjectDirByOpenedFile().fsPath); + projectContext.setItfpath(itfPath); const projectConfigRequest = new ProjectConfigRequest(); projectConfigRequest.setProjectcontext(projectContext); projectConfigRequest.setConfigmode(configMode); @@ -429,6 +431,7 @@ export class Client { projectContext.setTestdirpath(Prefs.getTestsDirPath()); projectContext.setBuilddirrelativepath(buildDir[1]); projectContext.setClientprojectpath(vsUtils.getProjectDirByOpenedFile().fsPath); + projectContext.setItfpath(Prefs.getITFPath()); rpcRequest.setProjectcontext(projectContext); rpcRequest.setSettingscontext(Prefs.getSettingsContext()); diff --git a/vscode-plugin/src/config/prefs.ts b/vscode-plugin/src/config/prefs.ts index d0d344132..47f009003 100644 --- a/vscode-plugin/src/config/prefs.ts +++ b/vscode-plugin/src/config/prefs.ts @@ -29,6 +29,7 @@ export class Prefs { public static CMAKE_OPTIONS_PREF = 'unittestbot.paths.cmakeOptions'; public static TESTS_DIR_PREF = 'unittestbot.paths.testsDirectory'; public static SOURCE_DIRS_PREF = 'unittestbot.paths.sourceDirectories'; + public static ITF_PATH_PREF = 'unittestbot.paths.initialTeardownFunctions'; public static VERBOSE_MODE_PREF = "unittestbot.testsGeneration.verboseFormatting"; @@ -260,6 +261,13 @@ export class Prefs { return this.getLocalSourcePaths(); } + public static getITFPath(): string { + const itfPath: string = this.getAssetBase(Prefs.ITF_PATH_PREF, ""); + if (itfPath.length === 0) { + return ""; + } + return pathUtils.normalizeRawPosixPath(itfPath); + } public static async setAsset(pref: string, newValue: T, raiseError: boolean = true): Promise { try { diff --git a/vscode-plugin/src/config/projectConfig.ts b/vscode-plugin/src/config/projectConfig.ts index cd565e64a..feddc9a5a 100644 --- a/vscode-plugin/src/config/projectConfig.ts +++ b/vscode-plugin/src/config/projectConfig.ts @@ -8,7 +8,7 @@ import {ExtensionLogger} from '../logger'; import {ConfigMode, ProjectConfigResponse, ProjectConfigStatus} from '../proto-ts/testgen_pb'; import {ProjectConfigEventsEmitter} from './projectConfigEventsEmitter'; -const { logger } = ExtensionLogger; +const {logger} = ExtensionLogger; export class ProjectConfig { private static readonly guideUri = "https://github.com/UnitTestBot/UTBotCpp/wiki"; @@ -16,11 +16,13 @@ export class ProjectConfig { private readonly projectName: string; private readonly projectPath: string; private readonly buildDirRelativePath: string; + private readonly itfPath: string; private readonly cmakeOptions: Array; constructor(private readonly client: Client) { this.projectName = Prefs.getProjectName(); [this.projectPath, this.buildDirRelativePath] = Prefs.getBuildDirPath(); + this.itfPath = Prefs.getITFPath(); this.cmakeOptions = Prefs.getCmakeOptions(); } @@ -64,12 +66,12 @@ export class ProjectConfig { case ProjectConfigStatus.BUILD_DIR_CREATION_FAILED: { return this.createBuildDirFailed(response.getMessage()); } - case ProjectConfigStatus.BUILD_DIR_SAME_AS_PROJECT: { + case ProjectConfigStatus.BUILD_DIR_SAME_AS_PROJECT: { const message = response.getMessage(); logger.warn(message); messages.showWarningMessage(`${message}. Please, follow the [guilde](${ProjectConfig.guideUri}) to configure project.`); - return false; + return false; } default: { this.handleUnexpectedResponse(); @@ -90,7 +92,7 @@ export class ProjectConfig { return utbotUI.progresses().withProgress(async (progressKey, token) => { utbotUI.progresses().report(progressKey, "Check project configuration..."); const responseHandler = new DummyResponseHandler(); - return this.client.checkProjectConfigurationRequest(this.projectName, this.projectPath, this.buildDirRelativePath, this.cmakeOptions, configMode, progressKey, token, responseHandler); + return this.client.checkProjectConfigurationRequest(this.projectName, this.projectPath, this.buildDirRelativePath, this.itfPath, this.cmakeOptions, configMode, progressKey, token, responseHandler); }); } diff --git a/vscode-plugin/src/requests/protos.ts b/vscode-plugin/src/requests/protos.ts index da21da884..497713461 100644 --- a/vscode-plugin/src/requests/protos.ts +++ b/vscode-plugin/src/requests/protos.ts @@ -40,6 +40,7 @@ export class Protos { projectContext.setTestdirpath(Prefs.getTestsDirPath()); projectContext.setBuilddirrelativepath(buildDirRelativePath); projectContext.setClientprojectpath(vsUtils.getProjectDirByOpenedFile().fsPath); + projectContext.setItfpath(Prefs.getITFPath()); projectInfo.setProjectcontext(projectContext); projectInfo.setSettingscontext(Prefs.getSettingsContext()); projectInfo.setSourcepathsList(srcPathsList);