From ab70e5461b98ddf2b56268c53c171cab89157027 Mon Sep 17 00:00:00 2001 From: Estevan Castilho Date: Thu, 2 Jul 2026 00:31:57 +0000 Subject: Nuke the old code --- test/VM.cpp | 254 ------------------------------------------------------------ 1 file changed, 254 deletions(-) delete mode 100644 test/VM.cpp (limited to 'test/VM.cpp') diff --git a/test/VM.cpp b/test/VM.cpp deleted file mode 100644 index 7e61da6..0000000 --- a/test/VM.cpp +++ /dev/null @@ -1,254 +0,0 @@ -#include - -#include "CursorManager.h" -#include "HandlerManager.h" -#include "IdentityManager.h" -#include "InMemoryBackend.h" -#include "LifecycleManager.h" -#include "Merkle.h" -#include "NamespaceReferenceManager.h" -#include "ObjectManager.h" -#include "PermissionsManager.h" -#include "TupleCodec.h" -#include "VM.h" - -#include -#include -#include - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -// Stores a tuple in the backend and updates the Relation object's Merkle root. -static void store_tuple(nt::InMemoryBackend& backend, nt::ObjectManager& objects, - const std::vector& path, std::vector attrs) { - auto bytes = nt::TupleCodec::Serialize(attrs); - auto hash = backend.Put(std::move(bytes)); - - auto* entry = objects.Find(path); - if (!entry) - return; - auto* rel = dynamic_cast(entry->object.get()); - if (!rel) - return; - auto hash_bin = nt::hex_to_bin(hash); - rel->merkle_root = - nt::Merkle::Insert(backend, rel->merkle_root, hash_bin, hash_bin); -} - -static std::unique_ptr make_relation_type() { - auto t = std::make_unique(); - t->label = RELATION; - t->disposable = false; - t->methods = {OPEN, CLOSE}; - return t; -} - -// Generator for eq[A, B]: returns one tuple when A == B, nothing otherwise. -// Treats both args as integers when parseable, strings otherwise. -static std::unique_ptr make_eq_type() { - auto t = std::make_unique(); - t->label = EPHEMERAL_RELATION; - t->disposable = false; - t->methods = {OPEN, CLOSE}; - t->cardinality = nt::ObjectManager::ephemeral_object_type::Cardinality::AlephZero; - t->generator = [](const std::vector& args, std::size_t offset, - std::size_t limit) -> std::vector { - if (args.size() < 2 || offset > 0 || limit == 0) - return {}; - if (args[0] != args[1]) - return {}; - return {nt::Tuple({{"left", args[0]}, {"right", args[1]}})}; - }; - return t; -} - -// --------------------------------------------------------------------------- -// Fixture: shared manager stack -// --------------------------------------------------------------------------- - -struct Fixture { - nt::InMemoryBackend backend; - nt::ObjectManager objects; - nt::PermissionsManager permissions; - nt::IdentityManager identities; - nt::LifecycleManager lifecycles{objects, backend}; - nt::NamespaceReferenceManager references{objects, backend}; - nt::HandlerManager handler{objects, permissions, identities, lifecycles, references}; - nt::CursorManager cursors{backend, &lifecycles, &objects}; - int conn = 1; -}; - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -TEST_CASE("SCAN returns all tuples from a stored relation", "[scan]") { - Fixture f; - const std::vector path = {"relations", "villager"}; - - f.objects.Register(path, std::make_unique(), make_relation_type()); - store_tuple(f.backend, f.objects, path, {{"name", "John"}, {"age", "30"}}); - store_tuple(f.backend, f.objects, path, {{"name", "Peter"}, {"age", "25"}}); - - auto* handle = f.handler.Open(path, &f.conn); - REQUIRE(handle != nullptr); - auto* rel = dynamic_cast(f.objects.Find(path)->object.get()); - auto* cursor = f.cursors.Open(handle, rel->merkle_root); - REQUIRE(cursor != nullptr); - - nt::PlanNode plan; - plan.op = nt::FOL_OPERATION_SCAN; - plan.scan_cursor = cursor; - - nt::VM vm(f.cursors); - int count = 0; - while (vm.Next(&plan)) - ++count; - - REQUIRE(count == 2); - - f.cursors.Close(cursor); - f.handler.Close(handle); -} - -TEST_CASE("JOIN filters a stored relation with eq ephemeral", "[join]") { - Fixture f; - const std::vector people_path = {"relations", "people"}; - const std::vector eq_path = {"builtins", "eq"}; - - // Register stored relation: people(name, age) - f.objects.Register(people_path, std::make_unique(), - make_relation_type()); - - store_tuple(f.backend, f.objects, people_path, {{"name", "John"}, {"age", "30"}}); - store_tuple(f.backend, f.objects, people_path, {{"name", "Peter"}, {"age", "25"}}); - store_tuple(f.backend, f.objects, people_path, {{"name", "Jude"}, {"age", "25"}}); - - // Register ephemeral eq relation - f.objects.Register(eq_path, std::make_unique(), make_eq_type()); - - // Open handles and cursors - auto* people_handle = f.handler.Open(people_path, &f.conn); - REQUIRE(people_handle != nullptr); - auto* eq_handle = f.handler.Open(eq_path, &f.conn); - REQUIRE(eq_handle != nullptr); - - auto* people_rel = - dynamic_cast(f.objects.Find(people_path)->object.get()); - auto* people_cursor = f.cursors.Open(people_handle, people_rel->merkle_root); - REQUIRE(people_cursor != nullptr); - auto* eq_cursor = f.cursors.Open(eq_handle); // EPHEMERAL: starts exhausted, JOIN resets - REQUIRE(eq_cursor != nullptr); - - // Plan: JOIN( SCAN(people), SCAN(eq[ Var("age"), Const("25") ]) ) - nt::PlanNode right; - right.op = nt::FOL_OPERATION_SCAN; - right.scan_cursor = eq_cursor; - right.scan_args = {nt::PathArg::Var("age"), nt::PathArg::Const("25")}; - - nt::PlanNode left; - left.op = nt::FOL_OPERATION_SCAN; - left.scan_cursor = people_cursor; - - nt::PlanNode root; - root.op = nt::FOL_OPERATION_JOIN; - root.left = &left; - root.right = &right; - - // Execute and collect matched names - nt::VM vm(f.cursors); - std::vector matched; - while (nt::Tuple* t = vm.Next(&root)) { - for (const auto& attr : t->attrs()) - if (attr.name == "name") - matched.push_back(attr.value); - } - - // Jude (age=25) and Peter (age=25) should match; Jogn (age=30) should not - REQUIRE(matched.size() == 2); - REQUIRE(std::find(matched.begin(), matched.end(), "Jude") != matched.end()); - REQUIRE(std::find(matched.begin(), matched.end(), "Peter") != matched.end()); - REQUIRE(std::find(matched.begin(), matched.end(), "John") == matched.end()); - - f.cursors.Close(people_cursor); - f.cursors.Close(eq_cursor); - f.handler.Close(people_handle); - f.handler.Close(eq_handle); -} - -TEST_CASE("TAKE limits tuples emitted from a SCAN", "[take]") { - Fixture f; - const std::vector path = {"relations", "items"}; - - f.objects.Register(path, std::make_unique(), make_relation_type()); - store_tuple(f.backend, f.objects, path, {{"id", "1"}}); - store_tuple(f.backend, f.objects, path, {{"id", "2"}}); - store_tuple(f.backend, f.objects, path, {{"id", "3"}}); - - auto* handle = f.handler.Open(path, &f.conn); - REQUIRE(handle != nullptr); - auto* rel = dynamic_cast(f.objects.Find(path)->object.get()); - auto* cursor = f.cursors.Open(handle, rel->merkle_root); - REQUIRE(cursor != nullptr); - - nt::PlanNode scan; - scan.op = nt::FOL_OPERATION_SCAN; - scan.scan_cursor = cursor; - - nt::PlanNode take; - take.op = nt::FOL_OPERATION_TAKE; - take.left = &scan; - take.take_limit = 2; - - nt::VM vm(f.cursors); - int count = 0; - while (vm.Next(&take)) - ++count; - - REQUIRE(count == 2); - - f.cursors.Close(cursor); - f.handler.Close(handle); -} - -TEST_CASE("PROJECT filters tuple attributes by name", "[project]") { - Fixture f; - const std::vector path = {"relations", "people"}; - - f.objects.Register(path, std::make_unique(), make_relation_type()); - store_tuple(f.backend, f.objects, path, {{"name", "John"}, {"age", "30"}, {"city", "Lisbon"}}); - - auto* handle = f.handler.Open(path, &f.conn); - REQUIRE(handle != nullptr); - auto* rel = dynamic_cast(f.objects.Find(path)->object.get()); - auto* cursor = f.cursors.Open(handle, rel->merkle_root); - REQUIRE(cursor != nullptr); - - nt::PlanNode scan; - scan.op = nt::FOL_OPERATION_SCAN; - scan.scan_cursor = cursor; - - nt::PlanNode project; - project.op = nt::FOL_OPERATION_PROJECT; - project.left = &scan; - project.project_attrs = {"name", "city"}; - - nt::VM vm(f.cursors); - nt::Tuple* t = vm.Next(&project); - REQUIRE(t != nullptr); - - std::vector names; - for (const auto& attr : t->attrs()) - names.push_back(attr.name); - - REQUIRE(names.size() == 2); - REQUIRE(std::find(names.begin(), names.end(), "name") != names.end()); - REQUIRE(std::find(names.begin(), names.end(), "city") != names.end()); - REQUIRE(std::find(names.begin(), names.end(), "age") == names.end()); - REQUIRE(vm.Next(&project) == nullptr); - - f.cursors.Close(cursor); - f.handler.Close(handle); -} -- cgit v1.2.3