diff options
-rw-r--r-- | src/buildtool/execution_api/local/TARGETS | 7 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/config.hpp | 65 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/local_action.cpp | 3 | ||||
-rw-r--r-- | src/buildtool/main/main.cpp | 44 | ||||
-rw-r--r-- | src/other_tools/just_mr/TARGETS | 1 | ||||
-rw-r--r-- | src/other_tools/just_mr/fetch.cpp | 9 | ||||
-rw-r--r-- | src/other_tools/just_mr/setup.cpp | 9 | ||||
-rw-r--r-- | src/other_tools/just_mr/setup_utils.cpp | 16 | ||||
-rw-r--r-- | src/other_tools/just_mr/setup_utils.hpp | 5 | ||||
-rw-r--r-- | test/buildtool/build_engine/target_map/target_map.test.cpp | 24 | ||||
-rw-r--r-- | test/buildtool/execution_api/common/api_test.hpp | 13 | ||||
-rw-r--r-- | test/buildtool/execution_api/local/local_api.test.cpp | 32 | ||||
-rw-r--r-- | test/buildtool/execution_api/local/local_execution.test.cpp | 48 | ||||
-rw-r--r-- | test/buildtool/execution_engine/executor/executor_api_local.test.cpp | 19 | ||||
-rw-r--r-- | test/buildtool/graph_traverser/graph_traverser.test.hpp | 49 |
15 files changed, 204 insertions, 140 deletions
diff --git a/src/buildtool/execution_api/local/TARGETS b/src/buildtool/execution_api/local/TARGETS index 2c848bf7..53b7f717 100644 --- a/src/buildtool/execution_api/local/TARGETS +++ b/src/buildtool/execution_api/local/TARGETS @@ -5,14 +5,9 @@ , "deps": [ ["@", "fmt", "", "fmt"] , ["@", "json", "", "json"] - , ["@", "gsl", "", "gsl"] - , ["src/buildtool/common", "common"] - , ["src/buildtool/file_system", "file_system_manager"] - , ["src/buildtool/file_system", "object_type"] , ["src/buildtool/logging", "log_level"] , ["src/buildtool/logging", "logging"] - , ["src/buildtool/execution_api/remote", "config"] - , ["src/buildtool/compatibility", "compatibility"] + , ["src/utils/cpp", "expected"] ] , "stage": ["src", "buildtool", "execution_api", "local"] } diff --git a/src/buildtool/execution_api/local/config.hpp b/src/buildtool/execution_api/local/config.hpp index 92d6606a..f2c8bf57 100644 --- a/src/buildtool/execution_api/local/config.hpp +++ b/src/buildtool/execution_api/local/config.hpp @@ -15,49 +15,56 @@ #ifndef INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_CONFIG_HPP #define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_CONFIG_HPP -#include <filesystem> -#include <functional> +#include <exception> +#include <optional> #include <string> +#include <utility> // std::move #include <vector> -#include "gsl/gsl" +#include "fmt/core.h" #include "nlohmann/json.hpp" -#include "src/buildtool/common/artifact_digest.hpp" -#include "src/buildtool/file_system/file_system_manager.hpp" -#include "src/buildtool/file_system/object_type.hpp" #include "src/buildtool/logging/log_level.hpp" #include "src/buildtool/logging/logger.hpp" +#include "src/utils/cpp/expected.hpp" -/// \brief Store global build system configuration. -class LocalExecutionConfig { +/// \brief Store local execution configuration. +struct LocalExecutionConfig final { + class Builder; + + // Launcher to be prepended to action's command before executed. + // Default: ["env", "--"] + std::vector<std::string> const launcher = {"env", "--"}; +}; + +class LocalExecutionConfig::Builder final { public: - [[nodiscard]] static auto SetLauncher( - std::vector<std::string> const& launcher) noexcept -> bool { - try { - Instance().launcher_ = launcher; - } catch (std::exception const& e) { - Logger::Log(LogLevel::Error, - "when setting the local launcher\n{}", - e.what()); - return false; - } - return true; + auto SetLauncher(std::vector<std::string> launcher) noexcept -> Builder& { + launcher_ = std::move(launcher); + return *this; } - [[nodiscard]] static auto GetLauncher() noexcept - -> std::vector<std::string> { - return Instance().launcher_; - } + /// \brief Finalize building and create LocalExecutionConfig. + /// \return LocalExecutionConfig on success, an error string on failure. + [[nodiscard]] auto Build() const noexcept + -> expected<LocalExecutionConfig, std::string> { + // To not duplicate default arguments in builder, create a default + // config and copy arguments from there. + LocalExecutionConfig const default_config; + auto launcher = default_config.launcher; + if (launcher_.has_value()) { + try { + launcher = *launcher_; + } catch (std::exception const& ex) { + return unexpected{ + fmt::format("Failed to set launcher:\n{}", ex.what())}; + } + } - [[nodiscard]] static auto Instance() noexcept -> LocalExecutionConfig& { - static LocalExecutionConfig config; - return config; + return LocalExecutionConfig{.launcher = std::move(launcher)}; } private: - // Launcher to be prepended to action's command before executed. - // Default: ["env", "--"] - std::vector<std::string> launcher_ = {"env", "--"}; + std::optional<std::vector<std::string>> launcher_; }; #endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_CONFIG_HPP diff --git a/src/buildtool/execution_api/local/local_action.cpp b/src/buildtool/execution_api/local/local_action.cpp index 73d78e36..b44fbd5c 100644 --- a/src/buildtool/execution_api/local/local_action.cpp +++ b/src/buildtool/execution_api/local/local_action.cpp @@ -165,7 +165,8 @@ auto LocalAction::Run(bazel_re::Digest const& action_id) const noexcept return std::nullopt; } - auto cmdline = exec_config_.GetLauncher(); + // prepare actual command by including the launcher + auto cmdline = exec_config_.launcher; std::copy(cmdline_.begin(), cmdline_.end(), std::back_inserter(cmdline)); SystemCommand system{"LocalExecution"}; diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp index c42b83a3..36f03345 100644 --- a/src/buildtool/main/main.cpp +++ b/src/buildtool/main/main.cpp @@ -118,16 +118,25 @@ void SetupLogging(LogArguments const& clargs) { } #ifndef BOOTSTRAP_BUILD_TOOL -void SetupExecutionConfig(EndpointArguments const& eargs, - BuildArguments const& bargs, - RebuildArguments const& rargs) { - using LocalConfig = LocalExecutionConfig; - using RemoteConfig = RemoteExecutionConfig; - if (bargs.local_launcher and - not LocalConfig::SetLauncher(*bargs.local_launcher)) { - Logger::Log(LogLevel::Error, "Failed to configure local execution."); - std::exit(kExitFailure); +[[nodiscard]] auto CreateLocalExecutionConfig( + BuildArguments const& bargs) noexcept + -> std::optional<LocalExecutionConfig> { + LocalExecutionConfig::Builder builder; + if (bargs.local_launcher.has_value()) { + builder.SetLauncher(*bargs.local_launcher); + } + + auto config = builder.Build(); + if (config) { + return *std::move(config); } + Logger::Log(LogLevel::Error, config.error()); + return std::nullopt; +} + +void SetupRemoteExecutionConfig(EndpointArguments const& eargs, + RebuildArguments const& rargs) { + using RemoteConfig = RemoteExecutionConfig; for (auto const& property : eargs.platform_properties) { if (not RemoteConfig::AddPlatformProperty(property)) { Logger::Log(LogLevel::Error, @@ -781,8 +790,13 @@ auto main(int argc, char* argv[]) -> int { SetupHashFunction(); SetupFileChunker(); - SetupExecutionConfig( - arguments.endpoint, arguments.build, arguments.rebuild); + + auto local_exec_config = CreateLocalExecutionConfig(arguments.build); + if (not local_exec_config) { + return kExitFailure; + } + + SetupRemoteExecutionConfig(arguments.endpoint, arguments.rebuild); auto serve_config = CreateServeConfig( arguments.serve, arguments.common, arguments.build, arguments.tc); @@ -822,7 +836,7 @@ auto main(int argc, char* argv[]) -> int { SetupExecutionServiceConfig(arguments.service); ApiBundle const exec_apis{&*storage_config, &storage, - &LocalExecutionConfig::Instance(), + &*local_exec_config, /*repo_config=*/nullptr, &*auth_config, RemoteExecutionConfig::RemoteAddress()}; @@ -851,7 +865,7 @@ auto main(int argc, char* argv[]) -> int { ApiBundle const serve_apis{ &*storage_config, &storage, - &LocalExecutionConfig::Instance(), + &*local_exec_config, /*repo_config=*/nullptr, &*auth_config, RemoteExecutionConfig::RemoteAddress()}; @@ -861,7 +875,7 @@ auto main(int argc, char* argv[]) -> int { return serve_server->Run(*serve_config, *storage_config, storage, - LocalExecutionConfig::Instance(), + *local_exec_config, serve, serve_apis, with_execute) @@ -922,7 +936,7 @@ auto main(int argc, char* argv[]) -> int { } ApiBundle const main_apis{&*storage_config, &storage, - &LocalExecutionConfig::Instance(), + &*local_exec_config, &repo_config, &*auth_config, RemoteExecutionConfig::RemoteAddress()}; diff --git a/src/other_tools/just_mr/TARGETS b/src/other_tools/just_mr/TARGETS index 560a08f6..3b4a3df6 100644 --- a/src/other_tools/just_mr/TARGETS +++ b/src/other_tools/just_mr/TARGETS @@ -87,6 +87,7 @@ [ ["src/buildtool/auth", "auth"] , ["src/buildtool/build_engine/expression", "expression_ptr_interface"] , ["src/buildtool/build_engine/expression", "expression"] + , ["src/buildtool/execution_api/local", "config"] , ["src/buildtool/serve_api/remote", "config"] , "cli" ] diff --git a/src/other_tools/just_mr/fetch.cpp b/src/other_tools/just_mr/fetch.cpp index 6b247e7c..44b9bdb1 100644 --- a/src/other_tools/just_mr/fetch.cpp +++ b/src/other_tools/just_mr/fetch.cpp @@ -407,9 +407,16 @@ auto MultiRepoFetch(std::shared_ptr<Configuration> const& config, return kExitConfigError; } + // setup local execution + auto local_exec_config = + JustMR::Utils::CreateLocalExecutionConfig(common_args); + if (not local_exec_config) { + return kExitConfigError; + } + ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &*local_exec_config, /*repo_config=*/nullptr, &*auth_config, RemoteExecutionConfig::RemoteAddress()}; diff --git a/src/other_tools/just_mr/setup.cpp b/src/other_tools/just_mr/setup.cpp index 10c15312..6cf5eaa6 100644 --- a/src/other_tools/just_mr/setup.cpp +++ b/src/other_tools/just_mr/setup.cpp @@ -126,9 +126,16 @@ auto MultiRepoSetup(std::shared_ptr<Configuration> const& config, return std::nullopt; } + // setup local execution + auto local_exec_config = + JustMR::Utils::CreateLocalExecutionConfig(common_args); + if (not local_exec_config) { + return std::nullopt; + } + ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &*local_exec_config, /*repo_config=*/nullptr, &*auth_config, RemoteExecutionConfig::RemoteAddress()}; diff --git a/src/other_tools/just_mr/setup_utils.cpp b/src/other_tools/just_mr/setup_utils.cpp index 2c219d95..ae6f5a28 100644 --- a/src/other_tools/just_mr/setup_utils.cpp +++ b/src/other_tools/just_mr/setup_utils.cpp @@ -217,6 +217,22 @@ auto CreateAuthConfig(MultiRepoRemoteAuthArguments const& authargs) noexcept return Auth{}; } +auto CreateLocalExecutionConfig(MultiRepoCommonArguments const& cargs) noexcept + -> std::optional<LocalExecutionConfig> { + + LocalExecutionConfig::Builder builder; + if (cargs.local_launcher.has_value()) { + builder.SetLauncher(*cargs.local_launcher); + } + + auto config = builder.Build(); + if (config) { + return *std::move(config); + } + Logger::Log(LogLevel::Error, config.error()); + return std::nullopt; +} + void SetupRemoteConfig( std::optional<std::string> const& remote_exec_addr, std::optional<std::string> const& remote_serve_addr) noexcept { diff --git a/src/other_tools/just_mr/setup_utils.hpp b/src/other_tools/just_mr/setup_utils.hpp index 3043855c..f96ca81e 100644 --- a/src/other_tools/just_mr/setup_utils.hpp +++ b/src/other_tools/just_mr/setup_utils.hpp @@ -24,6 +24,7 @@ #include "src/buildtool/auth/authentication.hpp" #include "src/buildtool/build_engine/expression/configuration.hpp" #include "src/buildtool/build_engine/expression/expression_ptr.hpp" +#include "src/buildtool/execution_api/local/config.hpp" #include "src/buildtool/serve_api/remote/config.hpp" #include "src/other_tools/just_mr/cli.hpp" @@ -65,6 +66,10 @@ void DefaultReachableRepositories( MultiRepoRemoteAuthArguments const& authargs) noexcept -> std::optional<Auth>; +[[nodiscard]] auto CreateLocalExecutionConfig( + MultiRepoCommonArguments const& cargs) noexcept + -> std::optional<LocalExecutionConfig>; + void SetupRemoteConfig( std::optional<std::string> const& remote_exec_addr, std::optional<std::string> const& remote_serve_addr) noexcept; diff --git a/test/buildtool/build_engine/target_map/target_map.test.cpp b/test/buildtool/build_engine/target_map/target_map.test.cpp index c3a875a7..18236837 100644 --- a/test/buildtool/build_engine/target_map/target_map.test.cpp +++ b/test/buildtool/build_engine/target_map/target_map.test.cpp @@ -106,10 +106,11 @@ TEST_CASE("simple targets", "[target_map]") { auto serve_config = TestServeConfig::ReadFromEnvironment(); REQUIRE(serve_config); + LocalExecutionConfig local_exec_config{}; Auth auth{}; ApiBundle const apis{&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; @@ -556,10 +557,11 @@ TEST_CASE("configuration deduplication", "[target_map]") { auto serve_config = TestServeConfig::ReadFromEnvironment(); REQUIRE(serve_config); + LocalExecutionConfig local_exec_config{}; Auth auth{}; ApiBundle const apis{&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; @@ -651,10 +653,11 @@ TEST_CASE("generator functions in string arguments", "[target_map]") { auto serve_config = TestServeConfig::ReadFromEnvironment(); REQUIRE(serve_config); + LocalExecutionConfig local_exec_config{}; Auth auth{}; ApiBundle const apis{&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; @@ -758,10 +761,11 @@ TEST_CASE("built-in rules", "[target_map]") { auto serve_config = TestServeConfig::ReadFromEnvironment(); REQUIRE(serve_config); + LocalExecutionConfig local_exec_config{}; Auth auth{}; ApiBundle const apis{&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; @@ -975,10 +979,11 @@ TEST_CASE("target reference", "[target_map]") { auto serve_config = TestServeConfig::ReadFromEnvironment(); REQUIRE(serve_config); + LocalExecutionConfig local_exec_config{}; Auth auth{}; ApiBundle const apis{&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; @@ -1125,10 +1130,11 @@ TEST_CASE("trees", "[target_map]") { auto serve_config = TestServeConfig::ReadFromEnvironment(); REQUIRE(serve_config); + LocalExecutionConfig local_exec_config{}; Auth auth{}; ApiBundle const apis{&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; @@ -1239,10 +1245,11 @@ TEST_CASE("RESULT error reporting", "[target_map]") { auto serve_config = TestServeConfig::ReadFromEnvironment(); REQUIRE(serve_config); + LocalExecutionConfig local_exec_config{}; Auth auth{}; ApiBundle const apis{&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; @@ -1412,10 +1419,11 @@ TEST_CASE("wrong arguments", "[target_map]") { auto serve_config = TestServeConfig::ReadFromEnvironment(); REQUIRE(serve_config); + LocalExecutionConfig local_exec_config{}; Auth auth{}; ApiBundle const apis{&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; diff --git a/test/buildtool/execution_api/common/api_test.hpp b/test/buildtool/execution_api/common/api_test.hpp index d43c850d..f9a814f7 100644 --- a/test/buildtool/execution_api/common/api_test.hpp +++ b/test/buildtool/execution_api/common/api_test.hpp @@ -32,7 +32,8 @@ using ApiFactory = std::function<IExecutionApi::Ptr()>; using ExecProps = std::map<std::string, std::string>; -inline void SetLauncher() { +[[nodiscard]] static inline auto SetLauncher() noexcept + -> LocalExecutionConfig { std::vector<std::string> launcher{"env"}; auto* env_path = std::getenv("PATH"); if (env_path != nullptr) { @@ -41,10 +42,12 @@ inline void SetLauncher() { else { launcher.emplace_back("PATH=/bin:/usr/bin"); } - if (not LocalExecutionConfig::SetLauncher(launcher)) { - Logger::Log(LogLevel::Error, "Failure setting the local launcher."); - std::exit(EXIT_FAILURE); + LocalExecutionConfig::Builder builder; + if (auto config = builder.SetLauncher(std::move(launcher)).Build()) { + return *std::move(config); } + Logger::Log(LogLevel::Error, "Failure setting the local launcher."); + std::exit(EXIT_FAILURE); } [[nodiscard]] static inline auto GetTestDir(std::string const& test_name) @@ -68,8 +71,6 @@ inline void SetLauncher() { auto action = api->CreateAction( *api->UploadTree({}), {"echo", "-n", test_content}, {}, {}, {}, props); - SetLauncher(); - SECTION("Cache execution result in action cache") { action->SetCacheFlag(IExecutionAction::CacheFlag::CacheOutput); diff --git a/test/buildtool/execution_api/local/local_api.test.cpp b/test/buildtool/execution_api/local/local_api.test.cpp index 164226b9..6a6b899a 100644 --- a/test/buildtool/execution_api/local/local_api.test.cpp +++ b/test/buildtool/execution_api/local/local_api.test.cpp @@ -51,8 +51,8 @@ class FactoryApi final { TEST_CASE("LocalAPI: No input, no output", "[execution_api]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); - FactoryApi api_factory( - &storage_config.Get(), &storage, &LocalExecutionConfig::Instance()); + auto const local_exec_config = SetLauncher(); + FactoryApi api_factory(&storage_config.Get(), &storage, &local_exec_config); TestNoInputNoOutput(api_factory, {}, /*is_hermetic=*/true); } @@ -60,8 +60,8 @@ TEST_CASE("LocalAPI: No input, no output", "[execution_api]") { TEST_CASE("LocalAPI: No input, create output", "[execution_api]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); - FactoryApi api_factory( - &storage_config.Get(), &storage, &LocalExecutionConfig::Instance()); + auto const local_exec_config = SetLauncher(); + FactoryApi api_factory(&storage_config.Get(), &storage, &local_exec_config); TestNoInputCreateOutput(api_factory, {}, /*is_hermetic=*/true); } @@ -69,8 +69,8 @@ TEST_CASE("LocalAPI: No input, create output", "[execution_api]") { TEST_CASE("LocalAPI: One input copied to output", "[execution_api]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); - FactoryApi api_factory( - &storage_config.Get(), &storage, &LocalExecutionConfig::Instance()); + auto const local_exec_config = SetLauncher(); + FactoryApi api_factory(&storage_config.Get(), &storage, &local_exec_config); TestOneInputCopiedToOutput(api_factory, {}, /*is_hermetic=*/true); } @@ -78,8 +78,8 @@ TEST_CASE("LocalAPI: One input copied to output", "[execution_api]") { TEST_CASE("LocalAPI: Non-zero exit code, create output", "[execution_api]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); - FactoryApi api_factory( - &storage_config.Get(), &storage, &LocalExecutionConfig::Instance()); + auto const local_exec_config = SetLauncher(); + FactoryApi api_factory(&storage_config.Get(), &storage, &local_exec_config); TestNonZeroExitCodeCreateOutput(api_factory, {}); } @@ -87,8 +87,8 @@ TEST_CASE("LocalAPI: Non-zero exit code, create output", "[execution_api]") { TEST_CASE("LocalAPI: Retrieve two identical trees to path", "[execution_api]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); - FactoryApi api_factory( - &storage_config.Get(), &storage, &LocalExecutionConfig::Instance()); + auto const local_exec_config = SetLauncher(); + FactoryApi api_factory(&storage_config.Get(), &storage, &local_exec_config); TestRetrieveTwoIdenticalTreesToPath( api_factory, {}, "two_trees", /*is_hermetic=*/true); @@ -98,8 +98,8 @@ TEST_CASE("LocalAPI: Retrieve file and symlink with same content to path", "[execution_api]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); - FactoryApi api_factory( - &storage_config.Get(), &storage, &LocalExecutionConfig::Instance()); + auto const local_exec_config = SetLauncher(); + FactoryApi api_factory(&storage_config.Get(), &storage, &local_exec_config); TestRetrieveFileAndSymlinkWithSameContentToPath( api_factory, {}, "file_and_symlink", /*is_hermetic=*/true); @@ -108,8 +108,8 @@ TEST_CASE("LocalAPI: Retrieve file and symlink with same content to path", TEST_CASE("LocalAPI: Retrieve mixed blobs and trees", "[execution_api]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); - FactoryApi api_factory( - &storage_config.Get(), &storage, &LocalExecutionConfig::Instance()); + auto const local_exec_config = SetLauncher(); + FactoryApi api_factory(&storage_config.Get(), &storage, &local_exec_config); TestRetrieveMixedBlobsAndTrees( api_factory, {}, "blobs_and_trees", /*is_hermetic=*/true); @@ -118,8 +118,8 @@ TEST_CASE("LocalAPI: Retrieve mixed blobs and trees", "[execution_api]") { TEST_CASE("LocalAPI: Create directory prior to execution", "[execution_api]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); - FactoryApi api_factory( - &storage_config.Get(), &storage, &LocalExecutionConfig::Instance()); + auto const local_exec_config = SetLauncher(); + FactoryApi api_factory(&storage_config.Get(), &storage, &local_exec_config); TestCreateDirPriorToExecution(api_factory, {}, /*is_hermetic=*/true); } diff --git a/test/buildtool/execution_api/local/local_execution.test.cpp b/test/buildtool/execution_api/local/local_execution.test.cpp index e8489b33..72db2800 100644 --- a/test/buildtool/execution_api/local/local_execution.test.cpp +++ b/test/buildtool/execution_api/local/local_execution.test.cpp @@ -41,7 +41,8 @@ namespace { "test/buildtool/execution_api/local"; } -inline void SetLauncher() { +[[nodiscard]] inline auto CreateLocalExecConfig() noexcept + -> LocalExecutionConfig { std::vector<std::string> launcher{"env"}; auto* env_path = std::getenv("PATH"); if (env_path != nullptr) { @@ -50,10 +51,12 @@ inline void SetLauncher() { else { launcher.emplace_back("PATH=/bin:/usr/bin"); } - if (not LocalExecutionConfig::SetLauncher(launcher)) { - Logger::Log(LogLevel::Error, "Failure setting the local launcher."); - std::exit(EXIT_FAILURE); + LocalExecutionConfig::Builder builder; + if (auto config = builder.SetLauncher(std::move(launcher)).Build()) { + return *std::move(config); } + Logger::Log(LogLevel::Error, "Failure setting the local launcher."); + std::exit(EXIT_FAILURE); } } // namespace @@ -63,10 +66,9 @@ TEST_CASE("LocalExecution: No input, no output", "[execution_api]") { auto const storage = Storage::Create(&storage_config.Get()); RepositoryConfig repo_config{}; - auto api = LocalApi(&storage_config.Get(), - &storage, - &LocalExecutionConfig::Instance(), - &repo_config); + auto const local_exec_config = CreateLocalExecConfig(); + auto api = LocalApi( + &storage_config.Get(), &storage, &local_exec_config, &repo_config); std::string test_content("test"); std::vector<std::string> const cmdline = {"echo", "-n", test_content}; @@ -74,8 +76,6 @@ TEST_CASE("LocalExecution: No input, no output", "[execution_api]") { api.CreateAction(*api.UploadTree({}), cmdline, {}, {}, {}, {}); REQUIRE(action); - SetLauncher(); - SECTION("Cache execution result in action cache") { // run execution action->SetCacheFlag(IExecutionAction::CacheFlag::CacheOutput); @@ -114,10 +114,9 @@ TEST_CASE("LocalExecution: No input, no output, env variables used", auto const storage = Storage::Create(&storage_config.Get()); RepositoryConfig repo_config{}; - auto api = LocalApi(&storage_config.Get(), - &storage, - &LocalExecutionConfig::Instance(), - &repo_config); + auto const local_exec_config = CreateLocalExecConfig(); + auto api = LocalApi( + &storage_config.Get(), &storage, &local_exec_config, &repo_config); std::string test_content("test from env var"); std::vector<std::string> const cmdline = { @@ -168,10 +167,9 @@ TEST_CASE("LocalExecution: No input, create output", "[execution_api]") { auto const storage = Storage::Create(&storage_config.Get()); RepositoryConfig repo_config{}; - auto api = LocalApi(&storage_config.Get(), - &storage, - &LocalExecutionConfig::Instance(), - &repo_config); + auto const local_exec_config = CreateLocalExecConfig(); + auto api = LocalApi( + &storage_config.Get(), &storage, &local_exec_config, &repo_config); std::string test_content("test"); auto test_digest = ArtifactDigest::Create<ObjectType::File>(test_content); @@ -228,10 +226,9 @@ TEST_CASE("LocalExecution: One input copied to output", "[execution_api]") { auto const storage = Storage::Create(&storage_config.Get()); RepositoryConfig repo_config{}; - auto api = LocalApi(&storage_config.Get(), - &storage, - &LocalExecutionConfig::Instance(), - &repo_config); + auto const local_exec_config = CreateLocalExecConfig(); + auto api = LocalApi( + &storage_config.Get(), &storage, &local_exec_config, &repo_config); std::string test_content("test"); auto test_digest = ArtifactDigest::Create<ObjectType::File>(test_content); @@ -301,10 +298,9 @@ TEST_CASE("LocalExecution: Cache failed action's result", "[execution_api]") { auto const storage = Storage::Create(&storage_config.Get()); RepositoryConfig repo_config{}; - auto api = LocalApi(&storage_config.Get(), - &storage, - &LocalExecutionConfig::Instance(), - &repo_config); + auto const local_exec_config = CreateLocalExecConfig(); + auto api = LocalApi( + &storage_config.Get(), &storage, &local_exec_config, &repo_config); auto flag = GetTestDir() / "flag"; std::vector<std::string> const cmdline = { diff --git a/test/buildtool/execution_engine/executor/executor_api_local.test.cpp b/test/buildtool/execution_engine/executor/executor_api_local.test.cpp index d8e9fd96..4fee58da 100644 --- a/test/buildtool/execution_engine/executor/executor_api_local.test.cpp +++ b/test/buildtool/execution_engine/executor/executor_api_local.test.cpp @@ -32,12 +32,11 @@ TEST_CASE("Executor<LocalApi>: Upload blob", "[executor]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); + LocalExecutionConfig local_exec_config{}; RepositoryConfig repo_config{}; TestBlobUpload(&repo_config, [&] { - return std::make_unique<LocalApi>(&storage_config.Get(), - &storage, - &LocalExecutionConfig::Instance(), - &repo_config); + return std::make_unique<LocalApi>( + &storage_config.Get(), &storage, &local_exec_config, &repo_config); }); } @@ -45,6 +44,7 @@ TEST_CASE("Executor<LocalApi>: Compile hello world", "[executor]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); + LocalExecutionConfig local_exec_config{}; RepositoryConfig repo_config{}; Statistics stats{}; Progress progress{}; @@ -57,7 +57,7 @@ TEST_CASE("Executor<LocalApi>: Compile hello world", "[executor]") { [&] { return std::make_unique<LocalApi>(&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, &repo_config); }, &*auth_config); @@ -67,6 +67,7 @@ TEST_CASE("Executor<LocalApi>: Compile greeter", "[executor]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); + LocalExecutionConfig local_exec_config{}; RepositoryConfig repo_config{}; Statistics stats{}; Progress progress{}; @@ -79,7 +80,7 @@ TEST_CASE("Executor<LocalApi>: Compile greeter", "[executor]") { [&] { return std::make_unique<LocalApi>(&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, &repo_config); }, &*auth_config); @@ -89,6 +90,7 @@ TEST_CASE("Executor<LocalApi>: Upload and download trees", "[executor]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); + LocalExecutionConfig local_exec_config{}; RepositoryConfig repo_config{}; Statistics stats{}; Progress progress{}; @@ -101,7 +103,7 @@ TEST_CASE("Executor<LocalApi>: Upload and download trees", "[executor]") { [&] { return std::make_unique<LocalApi>(&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, &repo_config); }, &*auth_config); @@ -111,6 +113,7 @@ TEST_CASE("Executor<LocalApi>: Retrieve output directories", "[executor]") { auto const storage_config = TestStorageConfig::Create(); auto const storage = Storage::Create(&storage_config.Get()); + LocalExecutionConfig local_exec_config{}; RepositoryConfig repo_config{}; Statistics stats{}; Progress progress{}; @@ -123,7 +126,7 @@ TEST_CASE("Executor<LocalApi>: Retrieve output directories", "[executor]") { [&] { return std::make_unique<LocalApi>(&storage_config.Get(), &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, &repo_config); }, &*auth_config); diff --git a/test/buildtool/graph_traverser/graph_traverser.test.hpp b/test/buildtool/graph_traverser/graph_traverser.test.hpp index ae07d347..4d47ef39 100644 --- a/test/buildtool/graph_traverser/graph_traverser.test.hpp +++ b/test/buildtool/graph_traverser/graph_traverser.test.hpp @@ -137,7 +137,8 @@ class TestProject { } }; -inline void SetLauncher() { +[[nodiscard]] inline auto CreateLocalExecConfig() noexcept + -> LocalExecutionConfig { std::vector<std::string> launcher{"env"}; auto* env_path = std::getenv("PATH"); if (env_path != nullptr) { @@ -146,10 +147,12 @@ inline void SetLauncher() { else { launcher.emplace_back("PATH=/bin:/usr/bin"); } - if (not LocalExecutionConfig::SetLauncher(launcher)) { - Logger::Log(LogLevel::Error, "Failure setting the local launcher."); - std::exit(EXIT_FAILURE); + LocalExecutionConfig::Builder builder; + if (auto config = builder.SetLauncher(std::move(launcher)).Build()) { + return *std::move(config); } + Logger::Log(LogLevel::Error, "Failure setting the local launcher."); + std::exit(EXIT_FAILURE); } } // namespace @@ -161,13 +164,13 @@ inline void SetLauncher() { bool is_hermetic = true) { TestProject p("hello_world_copy_message"); - SetLauncher(); + auto const local_exec_config = CreateLocalExecConfig(); auto const clargs = p.CmdLineArgs(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -199,7 +202,7 @@ inline void SetLauncher() { auto const clargs_exec = p.CmdLineArgs("_entry_points_get_executable"); ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -237,13 +240,13 @@ inline void SetLauncher() { bool is_hermetic = true) { TestProject p("copy_local_file"); - SetLauncher(); + auto const local_exec_config = CreateLocalExecConfig(); auto const clargs = p.CmdLineArgs(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -275,13 +278,13 @@ inline void SetLauncher() { bool is_hermetic = true) { TestProject p("sequence_printer_build_library_only"); - SetLauncher(); + auto const local_exec_config = CreateLocalExecConfig(); auto const clargs = p.CmdLineArgs(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -333,14 +336,14 @@ inline void SetLauncher() { bool is_hermetic = true) { TestProject full_hello_world("hello_world_copy_message"); - SetLauncher(); + auto const local_exec_config = CreateLocalExecConfig(); auto const clargs_update_cpp = full_hello_world.CmdLineArgs("_entry_points_upload_source"); Statistics stats{}; Progress progress{}; ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, full_hello_world.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -398,12 +401,12 @@ static void TestBlobsUploadedAndUsed(StorageConfig const& storage_config, TestProject p("use_uploaded_blobs"); auto const clargs = p.CmdLineArgs(); - SetLauncher(); + auto const local_exec_config = CreateLocalExecConfig(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -444,12 +447,12 @@ static void TestEnvironmentVariablesSetAndUsed( TestProject p("use_env_variables"); auto const clargs = p.CmdLineArgs(); - SetLauncher(); + auto const local_exec_config = CreateLocalExecConfig(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -489,12 +492,12 @@ static void TestTreesUsed(StorageConfig const& storage_config, TestProject p("use_trees"); auto const clargs = p.CmdLineArgs(); - SetLauncher(); + auto const local_exec_config = CreateLocalExecConfig(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -534,12 +537,12 @@ static void TestNestedTreesUsed(StorageConfig const& storage_config, TestProject p("use_nested_trees"); auto const clargs = p.CmdLineArgs(); - SetLauncher(); + auto const local_exec_config = CreateLocalExecConfig(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -578,17 +581,17 @@ static void TestFlakyHelloWorldDetected(StorageConfig const& storage_config, bool /*is_hermetic*/ = true) { TestProject p("flaky_hello_world"); + auto const local_exec_config = CreateLocalExecConfig(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&storage_config, &storage, - &LocalExecutionConfig::Instance(), + &local_exec_config, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; { - SetLauncher(); auto clargs = p.CmdLineArgs("_entry_points_ctimes"); GraphTraverser const gt{clargs.gtargs, p.GetRepoConfig(), |