diff options
18 files changed, 259 insertions, 189 deletions
diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp index 80b7ea14..d0c36d93 100644 --- a/src/buildtool/main/main.cpp +++ b/src/buildtool/main/main.cpp @@ -784,6 +784,8 @@ auto main(int argc, char* argv[]) -> int { return kExitFailure; } + auto const storage = Storage::Create(&StorageConfig::Instance()); + if (arguments.cmd == SubCommand::kGc) { if (GarbageCollector::TriggerGarbageCollection( StorageConfig::Instance(), arguments.gc.no_rotate)) { @@ -795,13 +797,12 @@ auto main(int argc, char* argv[]) -> int { if (arguments.cmd == SubCommand::kExecute) { SetupExecutionServiceConfig(arguments.service); ApiBundle const exec_apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &*auth_config, RemoteExecutionConfig::RemoteAddress()}; - if (not ServerImpl::Instance().Run(StorageConfig::Instance(), - Storage::Instance(), - exec_apis)) { + if (not ServerImpl::Instance().Run( + StorageConfig::Instance(), storage, exec_apis)) { return kExitFailure; } return kExitSuccess; @@ -816,16 +817,16 @@ auto main(int argc, char* argv[]) -> int { if (serve_server) { ApiBundle const serve_apis{ &StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &*auth_config, RemoteExecutionConfig::RemoteAddress()}; - auto serve = ServeApi::Create( - *serve_config, &Storage::Instance(), &serve_apis); + auto serve = + ServeApi::Create(*serve_config, &storage, &serve_apis); bool with_execute = not RemoteExecutionConfig::RemoteAddress(); return serve_server->Run(*serve_config, StorageConfig::Instance(), - Storage::Instance(), + storage, serve, serve_apis, with_execute) @@ -876,7 +877,7 @@ auto main(int argc, char* argv[]) -> int { std::exit(kExitFailure); } ApiBundle const main_apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, &repo_config, &*auth_config, RemoteExecutionConfig::RemoteAddress()}; @@ -905,8 +906,7 @@ auto main(int argc, char* argv[]) -> int { : kExitFailure; } if (arguments.cmd == SubCommand::kAddToCas) { - return AddArtifactsToCas( - arguments.to_add, Storage::Instance(), main_apis) + return AddArtifactsToCas(arguments.to_add, storage, main_apis) ? kExitSuccess : kExitFailure; } @@ -917,7 +917,7 @@ auto main(int argc, char* argv[]) -> int { #ifndef BOOTSTRAP_BUILD_TOOL std::optional<ServeApi> serve = - ServeApi::Create(*serve_config, &Storage::Instance(), &main_apis); + ServeApi::Create(*serve_config, &storage, &main_apis); #else std::optional<ServeApi> serve; #endif // BOOTSTRAP_BUILD_TOOL @@ -993,7 +993,7 @@ auto main(int argc, char* argv[]) -> int { // create progress tracker for export targets Progress exports_progress{}; AnalyseContext analyse_ctx{.repo_config = &repo_config, - .storage = &Storage::Instance(), + .storage = &storage, .statistics = &stats, .progress = &exports_progress, .serve = serve ? &*serve : nullptr}; @@ -1095,7 +1095,7 @@ auto main(int argc, char* argv[]) -> int { jobs, main_apis, arguments.tc.target_cache_write_strategy, - Storage::Instance().TargetCache(), + storage.TargetCache(), nullptr, arguments.serve.remote_serve_address ? LogLevel::Performance diff --git a/src/buildtool/storage/garbage_collector.cpp b/src/buildtool/storage/garbage_collector.cpp index 45237413..3b3e5d28 100644 --- a/src/buildtool/storage/garbage_collector.cpp +++ b/src/buildtool/storage/garbage_collector.cpp @@ -223,8 +223,7 @@ auto GarbageCollector::Compactify(StorageConfig const& storage_config, // Compactification must be done for both native and compatible storages. auto compactify = [&storage_config, threshold](bool compatible) -> bool { Compatibility::SetCompatible(compatible); - auto gen_config = storage_config.CreateGenerationConfig(0); - auto const storage = ::Generation(gen_config); + auto const storage = ::Generation::Create(&storage_config); return Compactifier::RemoveInvalid(storage.CAS()) and Compactifier::RemoveSpliced(storage.CAS()) and diff --git a/src/buildtool/storage/storage.hpp b/src/buildtool/storage/storage.hpp index 070c8fa6..d4b070e3 100644 --- a/src/buildtool/storage/storage.hpp +++ b/src/buildtool/storage/storage.hpp @@ -16,10 +16,7 @@ #define INCLUDED_SRC_BUILDTOOL_STORAGE_STORAGE_HPP #include <cstddef> -#include <filesystem> #include <memory> -#include <optional> -#include <vector> #include "gsl/gsl" #include "src/buildtool/common/artifact.hpp" @@ -36,7 +33,7 @@ /// the affected storage instance (CAS, action cache, target cache). /// \tparam kDoGlobalUplink Enable global uplinking. template <bool kDoGlobalUplink> -class LocalStorage { +class LocalStorage final { public: static constexpr std::size_t kYoungest = 0U; @@ -45,11 +42,16 @@ class LocalStorage { using AC_t = LocalAC<kDoGlobalUplink>; using TC_t = ::TargetCache<kDoGlobalUplink>; - explicit LocalStorage(GenerationConfig const& config) - : uplinker_{std::make_shared<Uplinker_t>(config.storage_config)}, - cas_{std::make_shared<CAS_t>(config, &*uplinker_)}, - ac_{std::make_shared<AC_t>(&*cas_, config, &*uplinker_)}, - tc_{std::make_shared<TC_t>(&*cas_, config, &*uplinker_)} {} + [[nodiscard]] static auto Create( + gsl::not_null<StorageConfig const*> const& storage_config, + std::size_t generation = kYoungest) -> LocalStorage<kDoGlobalUplink> { + if constexpr (kDoGlobalUplink) { + // It is not allowed to enable uplinking for old generations. + EnsuresAudit(generation == kYoungest); + } + auto gen_config = storage_config->CreateGenerationConfig(generation); + return LocalStorage<kDoGlobalUplink>{gen_config}; + } /// \brief Get the CAS instance. [[nodiscard]] auto CAS() const noexcept -> CAS_t const& { return *cas_; } @@ -65,10 +67,16 @@ class LocalStorage { } private: - std::shared_ptr<Uplinker_t const> uplinker_; - std::shared_ptr<CAS_t const> cas_; - std::shared_ptr<AC_t const> ac_; - std::shared_ptr<TC_t const> tc_; + std::unique_ptr<Uplinker_t const> uplinker_; + std::unique_ptr<CAS_t const> cas_; + std::unique_ptr<AC_t const> ac_; + std::unique_ptr<TC_t const> tc_; + + explicit LocalStorage(GenerationConfig const& config) + : uplinker_{std::make_unique<Uplinker_t>(config.storage_config)}, + cas_{std::make_unique<CAS_t>(config, &*uplinker_)}, + ac_{std::make_unique<AC_t>(&*cas_, config, &*uplinker_)}, + tc_{std::make_unique<TC_t>(&*cas_, config, &*uplinker_)} {} }; #ifdef BOOTSTRAP_BUILD_TOOL @@ -81,35 +89,6 @@ constexpr auto kDefaultDoGlobalUplink = true; /// \brief Generation type, local storage without global uplinking. using Generation = LocalStorage</*kDoGlobalUplink=*/false>; -/// \brief Global storage singleton class, valid throughout the entire tool. -/// Configured via \ref StorageConfig. -class Storage : public LocalStorage<kDefaultDoGlobalUplink> { - public: - /// \brief Get the global storage instance. - /// Build root is read from \ref - /// StorageConfig::Instance().BuildRoot(). - /// \returns The global storage singleton instance. - [[nodiscard]] static auto Instance() noexcept -> Storage const& { - return GetStorage(); - } - - /// \brief Reinitialize storage instance and generations. - /// Use if global \ref StorageConfig was changed. Not thread-safe! - static void Reinitialize() noexcept { GetStorage() = CreateStorage(); } - - private: - using LocalStorage<kDefaultDoGlobalUplink>::LocalStorage; - - [[nodiscard]] static auto CreateStorage() noexcept -> Storage { - auto gen_config = StorageConfig::Instance().CreateGenerationConfig( - Storage::kYoungest); - return Storage{gen_config}; - } - - [[nodiscard]] static auto GetStorage() noexcept -> Storage& { - static auto instance = CreateStorage(); - return instance; - } -}; +using Storage = LocalStorage<kDefaultDoGlobalUplink>; #endif // INCLUDED_SRC_BUILDTOOL_STORAGE_STORAGE_HPP diff --git a/src/buildtool/storage/uplinker.cpp b/src/buildtool/storage/uplinker.cpp index 42213b33..de6cfb99 100644 --- a/src/buildtool/storage/uplinker.cpp +++ b/src/buildtool/storage/uplinker.cpp @@ -34,8 +34,8 @@ namespace { std::vector<Generation> generations; generations.reserve(storage_config->NumGenerations()); for (std::size_t i = 0; i < storage_config->NumGenerations(); ++i) { - auto const gen_config = storage_config->CreateGenerationConfig(i); - generations.emplace_back(gen_config); + generations.emplace_back(Generation::Create(storage_config, + /*generation=*/i)); } return generations; } diff --git a/src/other_tools/just_mr/main.cpp b/src/other_tools/just_mr/main.cpp index 815d6453..98e1de2c 100644 --- a/src/other_tools/just_mr/main.cpp +++ b/src/other_tools/just_mr/main.cpp @@ -296,6 +296,8 @@ auto main(int argc, char* argv[]) -> int { return kExitGenericFailure; } + auto const storage = Storage::Create(&StorageConfig::Instance()); + // check for conflicts in main repo name if ((not arguments.setup.sub_all) and arguments.common.main and arguments.setup.sub_main and @@ -346,7 +348,7 @@ auto main(int argc, char* argv[]) -> int { arguments.retry, arguments.launch_fwd, StorageConfig::Instance(), - Storage::Instance(), + storage, forward_build_root, my_name); } @@ -376,7 +378,7 @@ auto main(int argc, char* argv[]) -> int { arguments.just_cmd, arguments.auth, StorageConfig::Instance(), - Storage::Instance(), + storage, /*interactive=*/(arguments.cmd == SubCommand::kSetupEnv), my_name); // dump resulting config to stdout @@ -424,7 +426,7 @@ auto main(int argc, char* argv[]) -> int { arguments.fetch, arguments.auth, StorageConfig::Instance(), - Storage::Instance(), + storage, my_name); } 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 bb15a544..76447242 100644 --- a/test/buildtool/build_engine/target_map/target_map.test.cpp +++ b/test/buildtool/build_engine/target_map/target_map.test.cpp @@ -101,15 +101,16 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "simple targets", "[target_map]") { auto serve_config = TestServeConfig::ReadServeConfigFromEnvironment(); REQUIRE(serve_config); + auto const storage = Storage::Create(&StorageConfig::Instance()); Auth auth{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; - auto serve = ServeApi::Create(*serve_config, &Storage::Instance(), &apis); + auto serve = ServeApi::Create(*serve_config, &storage, &apis); AnalyseContext ctx{.repo_config = &repo_config, - .storage = &Storage::Instance(), + .storage = &storage, .statistics = &stats, .progress = &exports_progress, .serve = serve ? &*serve : nullptr}; @@ -549,15 +550,17 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, auto serve_config = TestServeConfig::ReadServeConfigFromEnvironment(); REQUIRE(serve_config); + auto const storage = Storage::Create(&StorageConfig::Instance()); + Auth auth{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; - auto serve = ServeApi::Create(*serve_config, &Storage::Instance(), &apis); + auto serve = ServeApi::Create(*serve_config, &storage, &apis); AnalyseContext ctx{.repo_config = &repo_config, - .storage = &Storage::Instance(), + .storage = &storage, .statistics = &stats, .progress = &exports_progress, .serve = serve ? &*serve : nullptr}; @@ -642,15 +645,16 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, auto serve_config = TestServeConfig::ReadServeConfigFromEnvironment(); REQUIRE(serve_config); + auto const storage = Storage::Create(&StorageConfig::Instance()); Auth auth{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; - auto serve = ServeApi::Create(*serve_config, &Storage::Instance(), &apis); + auto serve = ServeApi::Create(*serve_config, &storage, &apis); AnalyseContext ctx{.repo_config = &repo_config, - .storage = &Storage::Instance(), + .storage = &storage, .statistics = &stats, .progress = &exports_progress, .serve = serve ? &*serve : nullptr}; @@ -745,15 +749,16 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "built-in rules", "[target_map]") { auto serve_config = TestServeConfig::ReadServeConfigFromEnvironment(); REQUIRE(serve_config); + auto const storage = Storage::Create(&StorageConfig::Instance()); Auth auth{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; - auto serve = ServeApi::Create(*serve_config, &Storage::Instance(), &apis); + auto serve = ServeApi::Create(*serve_config, &storage, &apis); AnalyseContext ctx{.repo_config = &repo_config, - .storage = &Storage::Instance(), + .storage = &storage, .statistics = &stats, .progress = &exports_progress, .serve = serve ? &*serve : nullptr}; @@ -958,15 +963,16 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "target reference", "[target_map]") { auto serve_config = TestServeConfig::ReadServeConfigFromEnvironment(); REQUIRE(serve_config); + auto const storage = Storage::Create(&StorageConfig::Instance()); Auth auth{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; - auto serve = ServeApi::Create(*serve_config, &Storage::Instance(), &apis); + auto serve = ServeApi::Create(*serve_config, &storage, &apis); AnalyseContext ctx{.repo_config = &repo_config, - .storage = &Storage::Instance(), + .storage = &storage, .statistics = &stats, .progress = &exports_progress, .serve = serve ? &*serve : nullptr}; @@ -1104,15 +1110,16 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "trees", "[target_map]") { auto serve_config = TestServeConfig::ReadServeConfigFromEnvironment(); REQUIRE(serve_config); + auto const storage = Storage::Create(&StorageConfig::Instance()); Auth auth{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; - auto serve = ServeApi::Create(*serve_config, &Storage::Instance(), &apis); + auto serve = ServeApi::Create(*serve_config, &storage, &apis); AnalyseContext ctx{.repo_config = &repo_config, - .storage = &Storage::Instance(), + .storage = &storage, .statistics = &stats, .progress = &exports_progress, .serve = serve ? &*serve : nullptr}; @@ -1216,15 +1223,16 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, auto serve_config = TestServeConfig::ReadServeConfigFromEnvironment(); REQUIRE(serve_config); + auto const storage = Storage::Create(&StorageConfig::Instance()); Auth auth{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; - auto serve = ServeApi::Create(*serve_config, &Storage::Instance(), &apis); + auto serve = ServeApi::Create(*serve_config, &storage, &apis); AnalyseContext ctx{.repo_config = &repo_config, - .storage = &Storage::Instance(), + .storage = &storage, .statistics = &stats, .progress = &exports_progress, .serve = serve ? &*serve : nullptr}; @@ -1385,15 +1393,16 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "wrong arguments", "[target_map]") { auto serve_config = TestServeConfig::ReadServeConfigFromEnvironment(); REQUIRE(serve_config); + auto const storage = Storage::Create(&StorageConfig::Instance()); Auth auth{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, /*repo_config=*/nullptr, &auth, RemoteExecutionConfig::RemoteAddress()}; - auto serve = ServeApi::Create(*serve_config, &Storage::Instance(), &apis); + auto serve = ServeApi::Create(*serve_config, &storage, &apis); AnalyseContext ctx{.repo_config = &repo_config, - .storage = &Storage::Instance(), + .storage = &storage, .statistics = &stats, .progress = &exports_progress, .serve = serve ? &*serve : nullptr}; diff --git a/test/buildtool/common/repository_config.test.cpp b/test/buildtool/common/repository_config.test.cpp index 56100643..131cf01f 100644 --- a/test/buildtool/common/repository_config.test.cpp +++ b/test/buildtool/common/repository_config.test.cpp @@ -85,8 +85,9 @@ template <class T> } // Read graph from CAS -[[nodiscard]] auto ReadGraph(std::string const& hash) -> nlohmann::json { - auto const& cas = Storage::Instance().CAS(); +[[nodiscard]] auto ReadGraph(Storage const& storage, std::string const& hash) + -> nlohmann::json { + auto const& cas = storage.CAS(); auto blob = cas.BlobPath( ArtifactDigest{hash, /*does not matter*/ 0, /*is_tree=*/false}, /*is_executable=*/false); @@ -118,37 +119,40 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "Test missing repository", "[repository_config]") { RepositoryConfig config{}; + auto const storage = Storage::Create(&StorageConfig::Instance()); CHECK(config.Info("missing") == nullptr); - CHECK_FALSE(config.RepositoryKey(Storage::Instance(), "missing")); + CHECK_FALSE(config.RepositoryKey(storage, "missing")); } TEST_CASE_METHOD(HermeticLocalTestFixture, "Compute key of fixed repository", "[repository_config]") { RepositoryConfig config{}; + auto const storage = Storage::Create(&StorageConfig::Instance()); SECTION("for single fixed repository") { config.SetInfo("foo", CreateFixedRepoInfo()); - auto key = config.RepositoryKey(Storage::Instance(), "foo"); + auto key = config.RepositoryKey(storage, "foo"); REQUIRE(key); // verify created graph from CAS - CHECK(ReadGraph(*key) == BuildGraph({config.Info("foo")}, {{}})); + CHECK(ReadGraph(storage, *key) == + BuildGraph({config.Info("foo")}, {{}})); } SECTION("for fixed repositories with same missing dependency") { config.SetInfo("foo", CreateFixedRepoInfo({{"dep", "baz"}})); config.SetInfo("bar", CreateFixedRepoInfo({{"dep", "baz"}})); - CHECK_FALSE(config.RepositoryKey(Storage::Instance(), "foo")); - CHECK_FALSE(config.RepositoryKey(Storage::Instance(), "bar")); + CHECK_FALSE(config.RepositoryKey(storage, "foo")); + CHECK_FALSE(config.RepositoryKey(storage, "bar")); } SECTION("for fixed repositories with different missing dependency") { config.SetInfo("foo", CreateFixedRepoInfo({{"dep", "baz0"}})); config.SetInfo("bar", CreateFixedRepoInfo({{"dep", "baz1"}})); - CHECK_FALSE(config.RepositoryKey(Storage::Instance(), "foo")); - CHECK_FALSE(config.RepositoryKey(Storage::Instance(), "bar")); + CHECK_FALSE(config.RepositoryKey(storage, "foo")); + CHECK_FALSE(config.RepositoryKey(storage, "bar")); } } @@ -156,17 +160,18 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "Compute key of file repository", "[repository_config]") { RepositoryConfig config{}; + auto const storage = Storage::Create(&StorageConfig::Instance()); SECTION("for single file repository") { config.SetInfo("foo", CreateFileRepoInfo()); - CHECK_FALSE(config.RepositoryKey(Storage::Instance(), "foo")); + CHECK_FALSE(config.RepositoryKey(storage, "foo")); } SECTION("for graph with leaf dependency as file") { config.SetInfo("foo", CreateFixedRepoInfo({{"bar", "bar"}})); config.SetInfo("bar", CreateFixedRepoInfo({{"baz", "baz"}})); config.SetInfo("baz", CreateFileRepoInfo()); - CHECK_FALSE(config.RepositoryKey(Storage::Instance(), "foo")); + CHECK_FALSE(config.RepositoryKey(storage, "foo")); } } @@ -174,6 +179,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "Compare key of two repos with same content", "[repository_config]") { RepositoryConfig config{}; + auto const storage = Storage::Create(&StorageConfig::Instance()); // create two different repo infos with same content (baz should be same) config.SetInfo("foo", CreateFixedRepoInfo({{"dep", "baz0"}})); @@ -186,14 +192,14 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, config.SetInfo("baz1", Copy(baz)); // check if computed key is same - auto foo_key = config.RepositoryKey(Storage::Instance(), "foo"); - auto bar_key = config.RepositoryKey(Storage::Instance(), "bar"); + auto foo_key = config.RepositoryKey(storage, "foo"); + auto bar_key = config.RepositoryKey(storage, "bar"); REQUIRE(foo_key); REQUIRE(bar_key); CHECK(*foo_key == *bar_key); // verify created graph from CAS - CHECK(ReadGraph(*foo_key) == + CHECK(ReadGraph(storage, *foo_key) == BuildGraph({config.Info("foo"), config.Info("baz0")}, {{{"dep", "1"}}, {}})); } @@ -205,14 +211,14 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, config.SetInfo("baz1", Copy(baz)); // check if computed key is same - auto foo_key = config.RepositoryKey(Storage::Instance(), "foo"); - auto bar_key = config.RepositoryKey(Storage::Instance(), "bar"); + auto foo_key = config.RepositoryKey(storage, "foo"); + auto bar_key = config.RepositoryKey(storage, "bar"); REQUIRE(foo_key); REQUIRE(bar_key); CHECK(*foo_key == *bar_key); // verify created graph from CAS - CHECK(ReadGraph(*foo_key) == + CHECK(ReadGraph(storage, *foo_key) == BuildGraph({config.Info("foo"), config.Info("baz0")}, {{{"dep", "1"}}, {{"foo", "0"}, {"bar", "0"}}})); } @@ -223,14 +229,14 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, config.SetInfo("baz1", CreateFixedRepoInfo({{"dep", "bar"}})); // check if computed key is same - auto foo_key = config.RepositoryKey(Storage::Instance(), "foo"); - auto bar_key = config.RepositoryKey(Storage::Instance(), "bar"); + auto foo_key = config.RepositoryKey(storage, "foo"); + auto bar_key = config.RepositoryKey(storage, "bar"); REQUIRE(foo_key); REQUIRE(bar_key); CHECK(*foo_key == *bar_key); // verify created graph from CAS - CHECK(ReadGraph(*foo_key) == + CHECK(ReadGraph(storage, *foo_key) == BuildGraph({config.Info("foo")}, {{{"dep", "0"}}})); } @@ -239,10 +245,10 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, config.SetInfo("baz1", CreateFixedRepoInfo({{"dep", "baz1"}})); // check if computed key is same - auto foo_key = config.RepositoryKey(Storage::Instance(), "foo"); - auto bar_key = config.RepositoryKey(Storage::Instance(), "bar"); - auto baz0_key = config.RepositoryKey(Storage::Instance(), "baz0"); - auto baz1_key = config.RepositoryKey(Storage::Instance(), "baz1"); + auto foo_key = config.RepositoryKey(storage, "foo"); + auto bar_key = config.RepositoryKey(storage, "bar"); + auto baz0_key = config.RepositoryKey(storage, "baz0"); + auto baz1_key = config.RepositoryKey(storage, "baz1"); CHECK(foo_key); CHECK(bar_key); CHECK(baz0_key); @@ -252,7 +258,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, CHECK(*baz0_key == *baz1_key); // verify created graph from CAS - CHECK(ReadGraph(*foo_key) == + CHECK(ReadGraph(storage, *foo_key) == BuildGraph({config.Info("foo")}, {{{"dep", "0"}}})); } } diff --git a/test/buildtool/execution_api/execution_service/cas_server.test.cpp b/test/buildtool/execution_api/execution_service/cas_server.test.cpp index 70a674ca..5b6e50b5 100644 --- a/test/buildtool/execution_api/execution_service/cas_server.test.cpp +++ b/test/buildtool/execution_api/execution_service/cas_server.test.cpp @@ -44,8 +44,9 @@ namespace { TEST_CASE_METHOD(HermeticLocalTestFixture, "CAS Service: upload incomplete tree", "[execution_service]") { - auto cas_server = - CASServiceImpl{&StorageConfig::Instance(), &Storage::Instance()}; + auto const storage = Storage::Create(&StorageConfig::Instance()); + + auto cas_server = CASServiceImpl{&StorageConfig::Instance(), &storage}; auto instance_name = std::string{"remote-execution"}; // Create an empty tree. diff --git a/test/buildtool/execution_api/local/local_api.test.cpp b/test/buildtool/execution_api/local/local_api.test.cpp index fa296c9b..de875a2c 100644 --- a/test/buildtool/execution_api/local/local_api.test.cpp +++ b/test/buildtool/execution_api/local/local_api.test.cpp @@ -23,10 +23,21 @@ #include "test/utils/hermeticity/local.hpp" namespace { +class FactoryApi final { + public: + explicit FactoryApi( + gsl::not_null<Storage const*> const& storage, + gsl::not_null<StorageConfig const*> const& storage_config) noexcept + : storage_{*storage}, storage_config_{*storage_config} {} -auto const kApiFactory = []() { - return IExecutionApi::Ptr{ - new LocalApi(&StorageConfig::Instance(), &Storage::Instance())}; + [[nodiscard]] auto operator()() const -> IExecutionApi::Ptr { + return IExecutionApi::Ptr{ + new LocalApi{&StorageConfig::Instance(), &storage_}}; + } + + private: + Storage const& storage_; + StorageConfig const& storage_config_; }; } // namespace @@ -34,51 +45,67 @@ auto const kApiFactory = []() { TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAPI: No input, no output", "[execution_api]") { - TestNoInputNoOutput(kApiFactory, {}, /*is_hermetic=*/true); + auto const storage = Storage::Create(&StorageConfig::Instance()); + FactoryApi api_factory(&storage, &StorageConfig::Instance()); + TestNoInputNoOutput(api_factory, {}, /*is_hermetic=*/true); } TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAPI: No input, create output", "[execution_api]") { - TestNoInputCreateOutput(kApiFactory, {}, /*is_hermetic=*/true); + auto const storage = Storage::Create(&StorageConfig::Instance()); + FactoryApi api_factory(&storage, &StorageConfig::Instance()); + TestNoInputCreateOutput(api_factory, {}, /*is_hermetic=*/true); } TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAPI: One input copied to output", "[execution_api]") { - TestOneInputCopiedToOutput(kApiFactory, {}, /*is_hermetic=*/true); + auto const storage = Storage::Create(&StorageConfig::Instance()); + FactoryApi api_factory(&storage, &StorageConfig::Instance()); + TestOneInputCopiedToOutput(api_factory, {}, /*is_hermetic=*/true); } TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAPI: Non-zero exit code, create output", "[execution_api]") { - TestNonZeroExitCodeCreateOutput(kApiFactory, {}); + auto const storage = Storage::Create(&StorageConfig::Instance()); + FactoryApi api_factory(&storage, &StorageConfig::Instance()); + TestNonZeroExitCodeCreateOutput(api_factory, {}); } TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAPI: Retrieve two identical trees to path", "[execution_api]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + FactoryApi api_factory(&storage, &StorageConfig::Instance()); TestRetrieveTwoIdenticalTreesToPath( - kApiFactory, {}, "two_trees", /*is_hermetic=*/true); + api_factory, {}, "two_trees", /*is_hermetic=*/true); } TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAPI: Retrieve file and symlink with same content to " "path", "[execution_api]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + FactoryApi api_factory(&storage, &StorageConfig::Instance()); TestRetrieveFileAndSymlinkWithSameContentToPath( - kApiFactory, {}, "file_and_symlink", /*is_hermetic=*/true); + api_factory, {}, "file_and_symlink", /*is_hermetic=*/true); } TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAPI: Retrieve mixed blobs and trees", "[execution_api]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + FactoryApi api_factory(&storage, &StorageConfig::Instance()); TestRetrieveMixedBlobsAndTrees( - kApiFactory, {}, "blobs_and_trees", /*is_hermetic=*/true); + api_factory, {}, "blobs_and_trees", /*is_hermetic=*/true); } TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAPI: Create directory prior to execution", "[execution_api]") { - TestCreateDirPriorToExecution(kApiFactory, {}, /*is_hermetic=*/true); + auto const storage = Storage::Create(&StorageConfig::Instance()); + FactoryApi api_factory(&storage, &StorageConfig::Instance()); + 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 6f9ccfb1..480b34df 100644 --- a/test/buildtool/execution_api/local/local_execution.test.cpp +++ b/test/buildtool/execution_api/local/local_execution.test.cpp @@ -61,9 +61,10 @@ inline void SetLauncher() { TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalExecution: No input, no output", "[execution_api]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + RepositoryConfig repo_config{}; - auto api = LocalApi( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + auto api = LocalApi(&StorageConfig::Instance(), &storage, &repo_config); std::string test_content("test"); std::vector<std::string> const cmdline = {"echo", "-n", test_content}; @@ -108,9 +109,9 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalExecution: No input, no output, env variables used", "[execution_api]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); RepositoryConfig repo_config{}; - auto api = LocalApi( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + auto api = LocalApi(&StorageConfig::Instance(), &storage, &repo_config); std::string test_content("test from env var"); std::vector<std::string> const cmdline = { @@ -159,9 +160,9 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalExecution: No input, create output", "[execution_api]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); RepositoryConfig repo_config{}; - auto api = LocalApi( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + auto api = LocalApi(&StorageConfig::Instance(), &storage, &repo_config); std::string test_content("test"); auto test_digest = ArtifactDigest::Create<ObjectType::File>(test_content); @@ -216,9 +217,9 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalExecution: One input copied to output", "[execution_api]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); RepositoryConfig repo_config{}; - auto api = LocalApi( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + auto api = LocalApi(&StorageConfig::Instance(), &storage, &repo_config); std::string test_content("test"); auto test_digest = ArtifactDigest::Create<ObjectType::File>(test_content); @@ -287,9 +288,9 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalExecution: Cache failed action's result", "[execution_api]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); RepositoryConfig repo_config{}; - auto api = LocalApi( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + auto api = LocalApi(&StorageConfig::Instance(), &storage, &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 ea6baa60..ae6c3d4e 100644 --- a/test/buildtool/execution_engine/executor/executor_api_local.test.cpp +++ b/test/buildtool/execution_engine/executor/executor_api_local.test.cpp @@ -30,16 +30,18 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "Executor<LocalApi>: Upload blob", "[executor]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); RepositoryConfig repo_config{}; TestBlobUpload(&repo_config, [&] { return std::make_unique<LocalApi>( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + &StorageConfig::Instance(), &storage, &repo_config); }); } TEST_CASE_METHOD(HermeticLocalTestFixture, "Executor<LocalApi>: Compile hello world", "[executor]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); RepositoryConfig repo_config{}; Statistics stats{}; Progress progress{}; @@ -51,7 +53,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, &progress, [&] { return std::make_unique<LocalApi>( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + &StorageConfig::Instance(), &storage, &repo_config); }, &*auth_config); } @@ -59,6 +61,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "Executor<LocalApi>: Compile greeter", "[executor]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); RepositoryConfig repo_config{}; Statistics stats{}; Progress progress{}; @@ -70,7 +73,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, &progress, [&] { return std::make_unique<LocalApi>( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + &StorageConfig::Instance(), &storage, &repo_config); }, &*auth_config); } @@ -78,6 +81,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "Executor<LocalApi>: Upload and download trees", "[executor]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); RepositoryConfig repo_config{}; Statistics stats{}; Progress progress{}; @@ -89,7 +93,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, &progress, [&] { return std::make_unique<LocalApi>( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + &StorageConfig::Instance(), &storage, &repo_config); }, &*auth_config); } @@ -97,6 +101,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "Executor<LocalApi>: Retrieve output directories", "[executor]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); RepositoryConfig repo_config{}; Statistics stats{}; Progress progress{}; @@ -108,7 +113,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, &progress, [&] { return std::make_unique<LocalApi>( - &StorageConfig::Instance(), &Storage::Instance(), &repo_config); + &StorageConfig::Instance(), &storage, &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 2999c0e0..e8fe20bd 100644 --- a/test/buildtool/graph_traverser/graph_traverser.test.hpp +++ b/test/buildtool/graph_traverser/graph_traverser.test.hpp @@ -158,12 +158,14 @@ inline void SetLauncher() { bool is_hermetic = true) { TestProject p("hello_world_copy_message"); + auto const storage = Storage::Create(&StorageConfig::Instance()); + SetLauncher(); auto const clargs = p.CmdLineArgs(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -194,7 +196,7 @@ inline void SetLauncher() { SECTION("Executable is retrieved as executable") { auto const clargs_exec = p.CmdLineArgs("_entry_points_get_executable"); ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -230,12 +232,14 @@ inline void SetLauncher() { bool is_hermetic = true) { TestProject p("copy_local_file"); + auto const storage = Storage::Create(&StorageConfig::Instance()); + SetLauncher(); auto const clargs = p.CmdLineArgs(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -265,12 +269,14 @@ inline void SetLauncher() { bool is_hermetic = true) { TestProject p("sequence_printer_build_library_only"); + auto const storage = Storage::Create(&StorageConfig::Instance()); + SetLauncher(); auto const clargs = p.CmdLineArgs(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -320,13 +326,15 @@ inline void SetLauncher() { bool is_hermetic = true) { TestProject full_hello_world("hello_world_copy_message"); + auto const storage = Storage::Create(&StorageConfig::Instance()); + SetLauncher(); auto const clargs_update_cpp = full_hello_world.CmdLineArgs("_entry_points_upload_source"); Statistics stats{}; Progress progress{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, full_hello_world.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -382,11 +390,13 @@ static void TestBlobsUploadedAndUsed(gsl::not_null<Auth const*> const& auth, TestProject p("use_uploaded_blobs"); auto const clargs = p.CmdLineArgs(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + SetLauncher(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -425,11 +435,13 @@ static void TestEnvironmentVariablesSetAndUsed( TestProject p("use_env_variables"); auto const clargs = p.CmdLineArgs(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + SetLauncher(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -467,11 +479,13 @@ static void TestTreesUsed(gsl::not_null<Auth const*> const& auth, TestProject p("use_trees"); auto const clargs = p.CmdLineArgs(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + SetLauncher(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -509,11 +523,13 @@ static void TestNestedTreesUsed(gsl::not_null<Auth const*> const& auth, TestProject p("use_nested_trees"); auto const clargs = p.CmdLineArgs(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + SetLauncher(); Statistics stats{}; Progress progress{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; @@ -550,10 +566,12 @@ static void TestFlakyHelloWorldDetected(gsl::not_null<Auth const*> const& auth, bool /*is_hermetic*/ = true) { TestProject p("flaky_hello_world"); + auto const storage = Storage::Create(&StorageConfig::Instance()); + Statistics stats{}; Progress progress{}; ApiBundle const apis{&StorageConfig::Instance(), - &Storage::Instance(), + &storage, p.GetRepoConfig(), auth, RemoteExecutionConfig::RemoteAddress()}; diff --git a/test/buildtool/storage/large_object_cas.test.cpp b/test/buildtool/storage/large_object_cas.test.cpp index f7713d45..fda1449a 100644 --- a/test/buildtool/storage/large_object_cas.test.cpp +++ b/test/buildtool/storage/large_object_cas.test.cpp @@ -100,7 +100,8 @@ class Tree final { TEST_CASE_METHOD(HermeticLocalTestFixture, "LargeObjectCAS: split a small tree", "[storage]") { - auto const& cas = Storage::Instance().CAS(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + auto const& cas = storage.CAS(); // Create a small tree: using LargeTestUtils::Tree; @@ -125,6 +126,8 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, template <ObjectType kType> static void TestLarge() noexcept { SECTION("Large") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + static constexpr bool kIsTree = IsTreeObject(kType); static constexpr bool kIsExec = IsExecutableObject(kType); @@ -132,7 +135,7 @@ static void TestLarge() noexcept { LargeTestUtils::Tree, LargeTestUtils::Blob<kIsExec>>; - auto const& cas = Storage::Instance().CAS(); + auto const& cas = storage.CAS(); // Create a large object: auto object = TestType::Create( @@ -188,9 +191,8 @@ static void TestLarge() noexcept { CHECK_FALSE(FileSystemManager::IsFile(path)); // Call split with disabled uplinking: - auto gen_config = - StorageConfig::Instance().CreateGenerationConfig(0); - ::Generation youngest_storage{gen_config}; + auto const youngest_storage = + ::Generation::Create(&StorageConfig::Instance()); auto pack_3 = kIsTree ? youngest_storage.CAS().SplitTree(digest) : youngest_storage.CAS().SplitBlob(digest); REQUIRE(pack_3); @@ -200,9 +202,8 @@ static void TestLarge() noexcept { for (std::size_t i = 0; i < StorageConfig::Instance().NumGenerations(); ++i) { - auto gen_config1 = - StorageConfig::Instance().CreateGenerationConfig(i); - ::Generation storage{gen_config1}; + auto const storage = ::Generation::Create( + &StorageConfig::Instance(), /*generation=*/i); auto generation_path = kIsTree ? storage.CAS().TreePath(digest) : storage.CAS().BlobPath(digest, kIsExec); @@ -219,6 +220,8 @@ static void TestLarge() noexcept { template <ObjectType kType> static void TestSmall() noexcept { SECTION("Small") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + static constexpr bool kIsTree = IsTreeObject(kType); static constexpr bool kIsExec = IsExecutableObject(kType); @@ -226,7 +229,7 @@ static void TestSmall() noexcept { LargeTestUtils::Tree, LargeTestUtils::Blob<kIsExec>>; - auto const& cas = Storage::Instance().CAS(); + auto const& cas = storage.CAS(); // Create a small object: auto object = TestType::Create( @@ -275,6 +278,8 @@ static void TestSmall() noexcept { template <ObjectType kType> static void TestEmpty() noexcept { SECTION("Empty") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + static constexpr bool kIsTree = IsTreeObject(kType); static constexpr bool kIsExec = IsExecutableObject(kType); @@ -282,7 +287,7 @@ static void TestEmpty() noexcept { LargeTestUtils::Tree, LargeTestUtils::Blob<kIsExec>>; - auto const& cas = Storage::Instance().CAS(); + auto const& cas = storage.CAS(); // Create an empty object: auto object = TestType::Create( @@ -324,6 +329,8 @@ static void TestEmpty() noexcept { template <ObjectType kType> static void TestExternal() noexcept { SECTION("External") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + static constexpr bool kIsTree = IsTreeObject(kType); static constexpr bool kIsExec = IsExecutableObject(kType); @@ -331,7 +338,7 @@ static void TestExternal() noexcept { LargeTestUtils::Tree, LargeTestUtils::Blob<kIsExec>>; - auto const& cas = Storage::Instance().CAS(); + auto const& cas = storage.CAS(); // Create a large object: auto object = TestType::Create( @@ -354,8 +361,7 @@ static void TestExternal() noexcept { REQUIRE(cas.BlobPath(part, is_executable)); } - auto gen_config = StorageConfig::Instance().CreateGenerationConfig(0); - ::Generation const youngest{gen_config}; + auto const youngest = ::Generation::Create(&StorageConfig::Instance()); SECTION("Proper request") { if constexpr (kIsTree) { @@ -424,6 +430,8 @@ static void TestExternal() noexcept { template <ObjectType kType> static void TestCompactification() { SECTION("Compactify") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + static constexpr bool kIsTree = IsTreeObject(kType); static constexpr bool kIsExec = IsExecutableObject(kType); @@ -431,7 +439,7 @@ static void TestCompactification() { LargeTestUtils::Tree, LargeTestUtils::Blob<kIsExec>>; - auto const& cas = Storage::Instance().CAS(); + auto const& cas = storage.CAS(); // Create a large object and split it: auto object = TestType::Create( @@ -470,8 +478,7 @@ static void TestCompactification() { : cas.BlobPath(digest, kIsExec); }; - auto gen_config = StorageConfig::Instance().CreateGenerationConfig(0); - ::Generation const latest{gen_config}; + auto const latest = ::Generation::Create(&StorageConfig::Instance()); REQUIRE(get_path(latest.CAS(), digest).has_value()); REQUIRE(get_path(latest.CAS(), digest_2).has_value()); @@ -536,7 +543,9 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LargeObjectCAS: uplink nested large objects", "[storage]") { - auto const& cas = Storage::Instance().CAS(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + + auto const& cas = storage.CAS(); // Randomize a large directory: auto tree_path = LargeTestUtils::Tree::Generate( @@ -601,8 +610,7 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, CHECK_FALSE(FileSystemManager::IsFile(*nested_tree_path)); CHECK_FALSE(FileSystemManager::IsFile(*nested_blob_path)); - auto gen_config = StorageConfig::Instance().CreateGenerationConfig(0); - ::Generation const latest{gen_config}; + auto const latest = ::Generation::Create(&StorageConfig::Instance()); // However, they might be reconstructed on request because there entries are // in the latest generation: @@ -615,8 +623,8 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, // Check there are no spliced results in old generations: for (std::size_t i = 1; i < StorageConfig::Instance().NumGenerations(); ++i) { - auto gen_config1 = StorageConfig::Instance().CreateGenerationConfig(i); - ::Generation storage{gen_config1}; + auto const storage = + ::Generation::Create(&StorageConfig::Instance(), /*generation=*/i); auto const& generation_cas = storage.CAS(); REQUIRE_FALSE(generation_cas.TreePath(*nested_tree_digest)); REQUIRE_FALSE(generation_cas.TreePath(*large_tree_digest)); diff --git a/test/buildtool/storage/local_ac.test.cpp b/test/buildtool/storage/local_ac.test.cpp index 4092ca1d..f2ca3a15 100644 --- a/test/buildtool/storage/local_ac.test.cpp +++ b/test/buildtool/storage/local_ac.test.cpp @@ -20,6 +20,7 @@ #include "src/buildtool/common/bazel_types.hpp" #include "src/buildtool/file_system/file_system_manager.hpp" #include "src/buildtool/file_system/object_type.hpp" +#include "src/buildtool/storage/config.hpp" #include "src/buildtool/storage/storage.hpp" #include "test/utils/hermeticity/local.hpp" @@ -32,8 +33,10 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAC: Single action, single result", "[storage]") { - auto const& ac = Storage::Instance().ActionCache(); - auto const& cas = Storage::Instance().CAS(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + + auto const& ac = storage.ActionCache(); + auto const& cas = storage.CAS(); auto action_id = ArtifactDigest::Create<ObjectType::File>("action"); CHECK(not ac.CachedResult(action_id)); @@ -45,8 +48,10 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAC: Two different actions, two different results", "[storage]") { - auto const& ac = Storage::Instance().ActionCache(); - auto const& cas = Storage::Instance().CAS(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + + auto const& ac = storage.ActionCache(); + auto const& cas = storage.CAS(); auto action_id1 = ArtifactDigest::Create<ObjectType::File>("action1"); auto action_id2 = ArtifactDigest::Create<ObjectType::File>("action2"); @@ -74,8 +79,10 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAC: Two different actions, same two results", "[storage]") { - auto const& ac = Storage::Instance().ActionCache(); - auto const& cas = Storage::Instance().CAS(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + + auto const& ac = storage.ActionCache(); + auto const& cas = storage.CAS(); auto action_id1 = ArtifactDigest::Create<ObjectType::File>("action1"); auto action_id2 = ArtifactDigest::Create<ObjectType::File>("action2"); @@ -103,8 +110,10 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalAC: Same two actions, two different results", "[storage]") { - auto const& ac = Storage::Instance().ActionCache(); - auto const& cas = Storage::Instance().CAS(); + auto const storage = Storage::Create(&StorageConfig::Instance()); + + auto const& ac = storage.ActionCache(); + auto const& cas = storage.CAS(); auto action_id = ArtifactDigest::Create<ObjectType::File>("same action"); CHECK(not ac.CachedResult(action_id)); diff --git a/test/buildtool/storage/local_cas.test.cpp b/test/buildtool/storage/local_cas.test.cpp index 55a8d946..b64ee780 100644 --- a/test/buildtool/storage/local_cas.test.cpp +++ b/test/buildtool/storage/local_cas.test.cpp @@ -20,15 +20,19 @@ #include "src/buildtool/execution_api/bazel_msg/bazel_blob_container.hpp" #include "src/buildtool/file_system/file_system_manager.hpp" #include "src/buildtool/file_system/object_type.hpp" +#include "src/buildtool/storage/config.hpp" +#include "src/buildtool/storage/storage.hpp" #include "test/utils/blob_creator.hpp" #include "test/utils/hermeticity/local.hpp" TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalCAS: Add blob to storage from bytes", "[storage]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + std::string test_bytes("test"); - auto const& cas = Storage::Instance().CAS(); + auto const& cas = storage.CAS(); auto test_digest = ArtifactDigest::Create<ObjectType::File>(test_bytes); // check blob not in storage @@ -73,10 +77,12 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalCAS: Add blob to storage from non-executable file", "[storage]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + std::filesystem::path non_exec_file{ "test/buildtool/storage/data/non_executable_file"}; - auto const& cas = Storage::Instance().CAS(); + auto const& cas = storage.CAS(); auto test_blob = CreateBlobFromPath(non_exec_file); REQUIRE(test_blob); @@ -122,10 +128,12 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalCAS: Add blob to storage from executable file", "[storage]") { + auto const storage = Storage::Create(&StorageConfig::Instance()); + std::filesystem::path exec_file{ "test/buildtool/storage/data/executable_file"}; - auto const& cas = Storage::Instance().CAS(); + auto const& cas = storage.CAS(); auto test_blob = CreateBlobFromPath(exec_file); REQUIRE(test_blob); diff --git a/test/utils/TARGETS b/test/utils/TARGETS index e5ef694a..f1bcf8d0 100644 --- a/test/utils/TARGETS +++ b/test/utils/TARGETS @@ -73,7 +73,8 @@ , ["@", "src", "src/buildtool/execution_api/remote", "config"] , ["@", "src", "src/buildtool/logging", "log_level"] , ["@", "src", "src/buildtool/logging", "logging"] - , ["@", "src", "src/buildtool/storage", "storage"] + , ["@", "src", "src/buildtool/storage", "config"] + , ["@", "src", "src/buildtool/file_system", "git_context"] , ["@", "src", "src/buildtool/file_system", "file_system_manager"] , ["@", "src", "src/buildtool/compatibility", "compatibility"] , "log_config" diff --git a/test/utils/hermeticity/local.hpp b/test/utils/hermeticity/local.hpp index 5cb3d530..a547e59e 100644 --- a/test/utils/hermeticity/local.hpp +++ b/test/utils/hermeticity/local.hpp @@ -41,7 +41,6 @@ class HermeticLocalTestFixture { StorageConfig::Instance().SetBuildRoot(case_dir)) { // After the build root has been changed, the file roots of the // static storage instances need to be updated. - Storage::Reinitialize(); Logger::Log(LogLevel::Debug, "created test-local cache dir {}", case_dir.string()); diff --git a/test/utils/remote_execution/main-remote-execution.cpp b/test/utils/remote_execution/main-remote-execution.cpp index 9c6edbc1..a691860a 100644 --- a/test/utils/remote_execution/main-remote-execution.cpp +++ b/test/utils/remote_execution/main-remote-execution.cpp @@ -24,9 +24,10 @@ #include "src/buildtool/compatibility/compatibility.hpp" #include "src/buildtool/execution_api/remote/config.hpp" #include "src/buildtool/file_system/file_system_manager.hpp" +#include "src/buildtool/file_system/git_context.hpp" #include "src/buildtool/logging/log_level.hpp" #include "src/buildtool/logging/logger.hpp" -#include "src/buildtool/storage/storage.hpp" +#include "src/buildtool/storage/config.hpp" #include "test/utils/logging/log_config.hpp" #include "test/utils/remote_execution/test_auth_config.hpp" #include "test/utils/test_env.hpp" @@ -73,9 +74,6 @@ void wait_for_grpc_to_shutdown() { not StorageConfig::Instance().SetBuildRoot(cache_dir)) { return false; } - // After the build root has been changed, the file roots of the - // static storage instances need to be updated. - Storage::Reinitialize(); return true; } |