diff --git a/test/integration/CMakeLists.txt b/test/integration/CMakeLists.txt index a5a6bfc1..cedb57f6 100644 --- a/test/integration/CMakeLists.txt +++ b/test/integration/CMakeLists.txt @@ -3,6 +3,7 @@ set(INTEGRATION_TEST_CONFIGS anonymous.toml container_enums.toml cycles.toml + ignored.toml inheritance_access.toml inheritance_multiple.toml inheritance_polymorphic.toml @@ -95,7 +96,9 @@ target_include_directories(integration_test_runner PRIVATE ${CMAKE_CURRENT_SOURC target_link_libraries(integration_test_runner PRIVATE ${GMOCK_MAIN_LIBS} Boost::headers - ${Boost_LIBRARIES}) + ${Boost_LIBRARIES} + tomlplusplus::tomlplusplus +) target_compile_definitions(integration_test_runner PRIVATE TARGET_EXE_PATH="${CMAKE_CURRENT_BINARY_DIR}/integration_test_target" OID_EXE_PATH="$" diff --git a/test/integration/gen_tests.py b/test/integration/gen_tests.py index f23d8fa2..0591fba9 100644 --- a/test/integration/gen_tests.py +++ b/test/integration/gen_tests.py @@ -240,9 +240,7 @@ def add_oid_integration_test(f, config, case_name, case): f"\n" f"TEST_F(OidIntegration, {case_str}) {{\n" f"{generate_skip(case, 'oid')}" - f' std::string configOptions = R"--(\n' - f"{config_extra}\n" - f' )--";\n' + f' std::string configOptions = R"--({config_extra})--";\n' f" ba::io_context ctx;\n" f" auto [target, oid] = runOidOnProcess(\n" f" {{\n" @@ -307,15 +305,18 @@ def add_oil_integration_test(f, config, case_name, case): if case.get("oil_disable", False): return + config_extra = case.get("config", "") + f.write( f"\n" f"TEST_F(OilIntegration, {case_str}) {{\n" f"{generate_skip(case, 'oil')}" + f' std::string configOptions = R"--({config_extra})--";\n' f" ba::io_context ctx;\n" f" auto target = runOilTarget({{\n" f" .ctx = ctx,\n" f' .targetArgs = "oil {case_str} 1",\n' - f" }});\n\n" + f" }}, std::move(configOptions));\n\n" f" ASSERT_EQ(exit_code(target), {exit_code});\n" f"\n" f" bpt::ptree result_json;\n" diff --git a/test/integration/runner_common.cpp b/test/integration/runner_common.cpp index 5ea2cb8a..807bf248 100644 --- a/test/integration/runner_common.cpp +++ b/test/integration/runner_common.cpp @@ -1,5 +1,8 @@ #include "runner_common.h" +#include + +#include #include #include #include @@ -119,6 +122,48 @@ int IntegrationBase::exit_code(Proc &proc) { return proc.proc.exit_code(); } +fs::path IntegrationBase::createCustomConfig(const std::string &extraConfig) { + // If no extra config provided, return the config path unaltered. + if (extraConfig.empty()) { + return configFile; + } + + auto customConfigFile = workingDir / "oid.config.toml"; + auto config = toml::parse_file(configFile); + + // As relative paths are allowed, we must canonicalise the paths before + // moving the file to the temporary directory. + fs::path configDirectory = fs::path(configFile).remove_filename(); + + if (toml::table *types = config["types"].as_table()) { + if (toml::array *arr = (*types)["containers"].as_array()) { + arr->for_each([&](auto &&el) { + if constexpr (toml::is_string) { + el = configDirectory / el.get(); + } + }); + } + } + if (toml::table *headers = config["headers"].as_table()) { + for (auto &path : {"user_paths", "system_paths"}) { + if (toml::array *arr = (*headers)[path].as_array()) { + arr->for_each([&](auto &&el) { + if constexpr (toml::is_string) { + el = configDirectory / el.get(); + } + }); + } + } + } + + std::ofstream customConfig(customConfigFile, std::ios_base::app); + customConfig << config; + customConfig << "\n\n# Test custom config\n\n"; + customConfig << extraConfig; + + return customConfigFile; +} + std::string OidIntegration::TmpDirStr() { return std::string("/tmp/oid-integration-XXXXXX"); } @@ -149,18 +194,7 @@ OidProc OidIntegration::runOidOnProcess(OidOpts opts, std::ofstream touch(segconfigPath); } - // Only create a new custom config if we've been provided an extra_config - boost::trim(extra_config); - - fs::path customConfigFile = configFile; - if (!extra_config.empty()) { - customConfigFile = workingDir / "oid.config.toml"; - fs::copy_file(configFile, customConfigFile); - - std::ofstream customConfig(customConfigFile, std::ios_base::app); - customConfig << "\n\n# Test custom config\n\n"; - customConfig << extra_config; - } + fs::path thisConfig = createCustomConfig(extra_config); // Keep PID as the last argument to make it easier for users to directly copy // and modify the command from the verbose mode output. @@ -169,7 +203,7 @@ OidProc OidIntegration::runOidOnProcess(OidOpts opts, "--debug-level=3"s, "--timeout=20"s, "--dump-json"s, - "--config-file"s, customConfigFile.string(), + "--config-file"s, thisConfig.string(), "--script-source"s, opts.scriptSource, "--pid"s, std::to_string(targetProcess.id()), }; @@ -302,7 +336,7 @@ std::string OilIntegration::TmpDirStr() { return std::string("/tmp/oil-integration-XXXXXX"); } -Proc OilIntegration::runOilTarget(OidOpts opts) { +Proc OilIntegration::runOilTarget(OidOpts opts, std::string extra_config) { std::string targetExe = std::string(TARGET_EXE_PATH) + " " + opts.targetArgs; if (verbose) { @@ -341,6 +375,8 @@ Proc OilIntegration::runOilTarget(OidOpts opts) { // clang-format on } + fs::path thisConfig = createCustomConfig(extra_config); + /* Spawn target with tracing on and IOs redirected in custom pipes to be read * later */ // clang-format off @@ -349,7 +385,7 @@ Proc OilIntegration::runOilTarget(OidOpts opts) { bp::std_in < bp::null, bp::std_out > std_out_pipe, bp::std_err > std_err_pipe, - bp::env["CONFIG_FILE_PATH"] = configFile, + bp::env["CONFIG_FILE_PATH"] = thisConfig.string(), opts.ctx); // clang-format on diff --git a/test/integration/runner_common.h b/test/integration/runner_common.h index fc23aaa4..45002d5c 100644 --- a/test/integration/runner_common.h +++ b/test/integration/runner_common.h @@ -38,6 +38,7 @@ class IntegrationBase : public ::testing::Test { void TearDown() override; void SetUp() override; int exit_code(Proc &proc); + std::filesystem::path createCustomConfig(const std::string &extra); std::filesystem::path workingDir; @@ -68,5 +69,5 @@ class OilIntegration : public IntegrationBase { protected: std::string TmpDirStr() override; - Proc runOilTarget(OidOpts opts); + Proc runOilTarget(OidOpts opts, std::string extra_config); };