aboutsummaryrefslogtreecommitdiffstats
path: root/test/LifecycleManager.cpp
diff options
context:
space:
mode:
authorEstevan Castilho <tevo@riajuu.net>2026-07-02 00:31:57 +0000
committerEstevan Castilho <tevo@riajuu.net>2026-07-02 00:31:57 +0000
commitab70e5461b98ddf2b56268c53c171cab89157027 (patch)
tree3e57218edacc8e1366e0d1a86bdb922af7e51dca /test/LifecycleManager.cpp
parenta4f6637601548a7158869ad155f29db50b151823 (diff)
downloadRNT-ab70e5461b98ddf2b56268c53c171cab89157027.tar.gz
RNT-ab70e5461b98ddf2b56268c53c171cab89157027.zip
Nuke the old code
Diffstat (limited to '')
-rw-r--r--test/LifecycleManager.cpp169
1 files changed, 0 insertions, 169 deletions
diff --git a/test/LifecycleManager.cpp b/test/LifecycleManager.cpp
deleted file mode 100644
index 3712522..0000000
--- a/test/LifecycleManager.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-#include <catch2/catch_test_macros.hpp>
-
-#include "InMemoryBackend.h"
-#include "LifecycleManager.h"
-#include "ObjectManager.h"
-
-#include <memory>
-
-// ---------------------------------------------------------------------------
-// Step 6 — Pin/Unpin and the cascade
-//
-// LifecycleManager owns object lifetime. Pin/Unpin adjust reference_count;
-// Monitor/Unmonitor adjust handle_count. Both decrement paths call into
-// TryCollect, which gates GC on the joint condition (both counters zero)
-// and, for MULTIGROUP entries, cascades through CascadeMultigroup to
-// unpin every Relation registered under their snapshot subtree.
-// ---------------------------------------------------------------------------
-
-namespace {
- std::unique_ptr<nt::ObjectManager::object_type> make_type(OBJECT_TYPE label) {
- auto t = std::make_unique<nt::ObjectManager::object_type>();
- t->label = label;
- t->methods = {OPEN, CLOSE};
- return t;
- }
-} // namespace
-
-TEST_CASE("Pin and Unpin adjust reference_count symmetrically", "[step6][lifecycle][pin]") {
- nt::InMemoryBackend store;
- nt::ObjectManager om;
- nt::LifecycleManager lm(om, store);
- om.Register({"r1"}, std::make_unique<nt::ObjectManager::Relation>(), make_type(RELATION));
- auto* entry = om.Find({"r1"});
- REQUIRE(entry->head->reference_count == 0);
-
- lm.Pin(entry);
- lm.Pin(entry);
- REQUIRE(entry->head->reference_count == 2);
-
- lm.Unpin(entry);
- REQUIRE(entry->head->reference_count == 1);
-
- // Still alive at ref_count=1.
- REQUIRE(om.Find({"r1"}) != nullptr);
-}
-
-TEST_CASE("Pin on nullptr is a no-op", "[step6][lifecycle][pin]") {
- nt::InMemoryBackend store;
- nt::ObjectManager om;
- nt::LifecycleManager lm(om, store);
- REQUIRE_NOTHROW(lm.Pin(nullptr));
- REQUIRE_NOTHROW(lm.Unpin(nullptr));
-}
-
-TEST_CASE("Unpin below zero does not underflow", "[step6][lifecycle][pin]") {
- nt::InMemoryBackend store;
- nt::ObjectManager om;
- nt::LifecycleManager lm(om, store);
- om.Register({"r1"}, std::make_unique<nt::ObjectManager::Relation>(), make_type(RELATION));
- auto* entry = om.Find({"r1"});
-
- lm.Unpin(entry);
- REQUIRE(entry->head->reference_count == 0);
-}
-
-TEST_CASE("GC is gated on both counters reaching zero", "[step6][lifecycle][gc]") {
- nt::InMemoryBackend store;
- nt::ObjectManager om;
- nt::LifecycleManager lm(om, store);
- om.Register({"r1"}, std::make_unique<nt::ObjectManager::Relation>(), make_type(RELATION));
- auto* entry = om.Find({"r1"});
-
- lm.Monitor(entry);
- lm.Pin(entry);
-
- // handle_count=1, ref_count=1.
- lm.Unpin(entry); // ref_count → 0, but handle_count still 1.
- REQUIRE(om.Find({"r1"}) != nullptr);
-
- lm.Pin(entry);
- lm.Unmonitor(entry); // handle_count → 0, but ref_count still 1.
- REQUIRE(om.Find({"r1"}) != nullptr);
-
- lm.Unpin(entry); // both zero → GC.
- REQUIRE(om.Find({"r1"}) == nullptr);
-}
-
-TEST_CASE("Unmonitor that brings both counters to zero collects the entry",
- "[step6][lifecycle][gc]") {
- nt::InMemoryBackend store;
- nt::ObjectManager om;
- nt::LifecycleManager lm(om, store);
- om.Register({"r1"}, std::make_unique<nt::ObjectManager::Relation>(), make_type(RELATION));
- auto* entry = om.Find({"r1"});
-
- lm.Monitor(entry);
- REQUIRE(entry->head->handle_count == 1);
- lm.Unmonitor(entry);
- REQUIRE(om.Find({"r1"}) == nullptr);
-}
-
-TEST_CASE("IsEligibleForGC reflects the joint-zero rule", "[step6][lifecycle][gc]") {
- nt::InMemoryBackend store;
- nt::ObjectManager om;
- nt::LifecycleManager lm(om, store);
- om.Register({"r1"}, std::make_unique<nt::ObjectManager::Relation>(), make_type(RELATION));
- auto* entry = om.Find({"r1"});
-
- REQUIRE(lm.IsEligibleForGC(entry));
- lm.Pin(entry);
- REQUIRE_FALSE(lm.IsEligibleForGC(entry));
-}
-
-TEST_CASE("CascadeMultigroup unpins child Relations on snapshot collection",
- "[step6][lifecycle][cascade]") {
- nt::InMemoryBackend store;
- nt::ObjectManager om;
- nt::LifecycleManager lm(om, store);
-
- om.Register({"system", "snapshots", "H1"}, std::make_unique<nt::ObjectManager::Multigroup>(),
- make_type(MULTIGROUP));
- auto* mg_entry = om.Find({"system", "snapshots", "H1"});
-
- for (const auto& n : {std::string{"foo"}, std::string{"bar"}}) {
- om.Register({"system", "snapshots", "H1", "relations", n},
- std::make_unique<nt::ObjectManager::Relation>(), make_type(RELATION));
- // The parent Multigroup's pin on each child, mirroring what
- // register_snapshot does in the C API layer.
- lm.Pin(om.Find({"system", "snapshots", "H1", "relations", n}));
- }
- REQUIRE(om.Find({"system", "snapshots", "H1", "relations", "foo"}) != nullptr);
- REQUIRE(om.Find({"system", "snapshots", "H1", "relations", "bar"}) != nullptr);
-
- // One external pin on the Multigroup (e.g. a branch). Release it: cascade.
- lm.Pin(mg_entry);
- lm.Unpin(mg_entry);
-
- REQUIRE(om.Find({"system", "snapshots", "H1"}) == nullptr);
- REQUIRE(om.Find({"system", "snapshots", "H1", "relations", "foo"}) == nullptr);
- REQUIRE(om.Find({"system", "snapshots", "H1", "relations", "bar"}) == nullptr);
-}
-
-TEST_CASE("Cascade survives a child with an open handle", "[step6][lifecycle][cascade]") {
- nt::InMemoryBackend store;
- nt::ObjectManager om;
- nt::LifecycleManager lm(om, store);
-
- om.Register({"system", "snapshots", "H2"}, std::make_unique<nt::ObjectManager::Multigroup>(),
- make_type(MULTIGROUP));
- auto* mg_entry = om.Find({"system", "snapshots", "H2"});
-
- om.Register({"system", "snapshots", "H2", "relations", "live"},
- std::make_unique<nt::ObjectManager::Relation>(), make_type(RELATION));
- auto* child = om.Find({"system", "snapshots", "H2", "relations", "live"});
- lm.Pin(child); // parent's pin
- lm.Monitor(child); // simulate an open handle on the child
-
- // Drop the Multigroup's external ref: cascade unpins child (ref → 0),
- // but handle_count is still 1 — child must survive.
- lm.Pin(mg_entry);
- lm.Unpin(mg_entry);
-
- REQUIRE(om.Find({"system", "snapshots", "H2"}) == nullptr);
- REQUIRE(om.Find({"system", "snapshots", "H2", "relations", "live"}) != nullptr);
-
- // Closing the handle now releases the child.
- lm.Unmonitor(child);
- REQUIRE(om.Find({"system", "snapshots", "H2", "relations", "live"}) == nullptr);
-}