From d9bf1d63768f1c3d660c3057d6d77c9b3b4a346d Mon Sep 17 00:00:00 2001 From: Maksim Denisov Date: Tue, 2 Apr 2024 17:58:12 +0200 Subject: Compactification: Remove spliced entries. During garbage collection remove from the storage every entry that has the large entry. --- test/buildtool/storage/large_object_cas.test.cpp | 50 ++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'test/buildtool/storage/large_object_cas.test.cpp') diff --git a/test/buildtool/storage/large_object_cas.test.cpp b/test/buildtool/storage/large_object_cas.test.cpp index da348727..fe3b8e6d 100644 --- a/test/buildtool/storage/large_object_cas.test.cpp +++ b/test/buildtool/storage/large_object_cas.test.cpp @@ -31,6 +31,7 @@ #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/garbage_collector.hpp" #include "src/buildtool/storage/large_object_cas.hpp" #include "src/buildtool/storage/storage.hpp" #include "src/utils/cpp/tmp_dir.hpp" @@ -421,6 +422,52 @@ static void TestExternal() noexcept { } } +// Test compactification of a storage generation. +// If there are objects in the storage that have an entry in +// the large CAS, they must be deleted during compactification. +template +static void TestCompactification() { + SECTION("Compactify") { + static constexpr bool kIsTree = IsTreeObject(kType); + static constexpr bool kIsExec = IsExecutableObject(kType); + + using TestType = std::conditional_t>; + + auto const& cas = Storage::Instance().CAS(); + + // Create a large object and split it: + auto object = TestType::Create( + cas, std::string(TestType::kLargeId), TestType::kLargeSize); + REQUIRE(object); + auto& [digest, path] = *object; + auto result = kIsTree ? cas.SplitTree(digest) : cas.SplitBlob(digest); + REQUIRE(std::get_if>(&result) != nullptr); + + // Ensure all entries are in the storage: + auto get_path = [](auto const& cas, bazel_re::Digest const& digest) { + return kIsTree ? cas.TreePath(digest) + : cas.BlobPath(digest, kIsExec); + }; + + auto const& latest = Storage::Generation(0).CAS(); + REQUIRE(get_path(latest, digest).has_value()); + + // Compactify the youngest generation: + // Generation rotation is disabled to exclude uplinking. + static constexpr bool no_rotation = true; + REQUIRE(GarbageCollector::TriggerGarbageCollection(no_rotation)); + + // All entries must be deleted during compactification, and for blobs + // and executables there are no synchronized entries in the storage: + REQUIRE_FALSE(get_path(latest, digest).has_value()); + + // All entries must be implicitly splicable: + REQUIRE(get_path(cas, digest).has_value()); + } +} + TEST_CASE_METHOD(HermeticLocalTestFixture, "LocalCAS: Split-Splice", "[storage]") { @@ -429,18 +476,21 @@ TEST_CASE_METHOD(HermeticLocalTestFixture, TestSmall(); TestEmpty(); TestExternal(); + TestCompactification(); } SECTION("Tree") { TestLarge(); TestSmall(); TestEmpty(); TestExternal(); + TestCompactification(); } SECTION("Executable") { TestLarge(); TestSmall(); TestEmpty(); TestExternal(); + TestCompactification(); } } -- cgit v1.2.3