Skip to content

Commit

Permalink
Add test
Browse files Browse the repository at this point in the history
  • Loading branch information
ladisgin committed Mar 25, 2024
1 parent 8961f05 commit 4b4c8e7
Show file tree
Hide file tree
Showing 22 changed files with 235 additions and 151 deletions.
10 changes: 10 additions & 0 deletions integration-tests/c-example/itf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"default init": "",
"default teardown": "",
"init": {
"init_global": "_init_vals"
},
"teardown": {
"init_global": ""
}
}
12 changes: 12 additions & 0 deletions integration-tests/c-example/lib/inits.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
int a;

void _init_vals() {
a = 42;
}

int init_global() {
if(a == 42) {
return 42;
}
return 0;
}
1 change: 1 addition & 0 deletions integration-tests/c-example/lib/inits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bool init_global();
144 changes: 76 additions & 68 deletions server/src/commands/Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ unsigned int Commands::ServerCommandOptions::getKleeProcessNumber() {
}

const std::map<std::string, loguru::NamedVerbosity> 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}
};


Expand All @@ -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() {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -307,34 +307,38 @@ std::optional<std::string> Commands::GenerateBaseCommandsOptions::getTarget() co
}

const std::map<std::string, testsgen::ValidationType>
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 {
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions server/src/commands/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion server/src/printers/KleePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ void KleePrinter::writeTestedFunction(const Tests &tests,

writeStubsForFunctionParams(typesHandler, testMethod, true);
declTestEntryPoint(tests, testMethod, isWrapped);
genInitCall(testMethod);
genOpenFiles(testMethod);
genGlobalParamsDeclarations(testMethod);
genInitCall(testMethod);
genParamsDeclarations(testMethod, filterAllWithoutFile);
genPostGlobalSymbolicVariables(testMethod);
genPostParamsSymbolicVariables(testMethod, filterAllWithoutFile);
Expand Down
4 changes: 3 additions & 1 deletion server/src/printers/TestsPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ void TestsPrinter::genCodeBySuiteName(const std::string &targetSuiteName,
testCase.testName = getTestName(methodDescription, testNum);
testHeader(testCase);
redirectStdin(methodDescription, testCase, verbose);
genInitCall(methodDescription);
if (verbose) {
genVerboseTestCase(methodDescription, testCase, predicateInfo, errorMode);
} else {
Expand Down Expand Up @@ -380,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);
Expand Down Expand Up @@ -459,6 +459,8 @@ void TestsPrinter::verboseParameters(const Tests::MethodDescription &methodDescr
ss << printer::NL;
}

genInitCall(methodDescription);

std::vector<std::vector<tests::Tests::MethodParam>> types = {testCase.stubValuesTypes, testCase.stubParamTypes};
std::vector<std::vector<tests::Tests::TestCaseParamValue>> values = {testCase.stubValues, testCase.stubParamValues};

Expand Down
7 changes: 4 additions & 3 deletions server/src/utils/CLIUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ std::unique_ptr<testsgen::ProjectContext>
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;
}

Expand Down
8 changes: 5 additions & 3 deletions server/src/utils/GrpcUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<testsgen::ProjectContext>();
result->set_projectname(projectName);
result->set_projectpath(projectPath);
result->set_testdirpath(testDirPath);
result->set_builddirrelativepath(buildDirRelativePath);
result->set_itfpath(itfPath);
return result;
}

Expand Down Expand Up @@ -60,7 +62,7 @@ namespace GrpcUtils {
auto result = std::make_unique<testsgen::ProjectRequest>();
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()) {
Expand Down Expand Up @@ -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);
}

Expand Down
3 changes: 2 additions & 1 deletion server/src/utils/GrpcUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<testsgen::SettingsContext>
createSettingsContext(bool generateForStaticFunctions,
Expand Down
2 changes: 1 addition & 1 deletion server/test/framework/Library_Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace {
std::pair<FunctionTestGen, Status>
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));
Expand Down
6 changes: 3 additions & 3 deletions server/test/framework/Regression_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace {
std::pair<FunctionTestGen, Status>
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);
Expand All @@ -40,7 +40,7 @@ namespace {
std::pair<FolderTestGen, Status>
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);
Expand Down Expand Up @@ -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);

Expand Down
Loading

0 comments on commit 4b4c8e7

Please sign in to comment.