#include #include "render_3D/detail/Ordered_Artifact_Transaction.h" #include "render_3D/detail/Ordered_Backend_Shutdown.h" #include #include namespace renderive::detail { namespace { struct Fake_Artifact { int stream = 7; }; struct Fake_Transaction_Api { std::vector events; Fake_Artifact artifact; bool emit_succeeds = true; bool attach_succeeds = true; bool execute_succeeds = true; std::size_t execute_count{}; Fake_Artifact* emit() { events.emplace_back("emit"); return emit_succeeds ? &artifact : nullptr; } int* stream(Fake_Artifact& value) { events.emplace_back("stream"); return &value.stream; } bool attach() { events.emplace_back("attach"); return attach_succeeds; } bool execute(const int&) { events.emplace_back("execute"); ++execute_count; return execute_succeeds; } void destroy(Fake_Artifact&) { events.emplace_back("destroy"); } }; TEST(DatovizTransaction, SuccessfulEmitExecutesExactlyOnceInCausalOrder) { Fake_Transaction_Api api; EXPECT_TRUE(static_cast(execute_ordered_artifact_transaction(api))); EXPECT_EQ(api.execute_count, 1U); EXPECT_EQ(api.events, std::vector({"emit", "stream", "attach", "execute", "destroy"})); } TEST(DatovizTransaction, AttachFailureStillConsumesEmittedArtifactExactlyOnce) { Fake_Transaction_Api api; api.attach_succeeds = false; EXPECT_FALSE(static_cast(execute_ordered_artifact_transaction(api))); EXPECT_EQ(api.execute_count, 1U); EXPECT_EQ(api.events, std::vector({"emit", "stream", "attach", "execute", "destroy"})); } TEST(DatovizTransaction, ExecuteFailureConsumesAndDestroysArtifactBeforeRecovery) { Fake_Transaction_Api api; api.execute_succeeds = false; EXPECT_FALSE(static_cast(execute_ordered_artifact_transaction(api))); EXPECT_EQ(api.execute_count, 1U); EXPECT_EQ(api.events, std::vector({"emit", "stream", "attach", "execute", "destroy"})); } TEST(DatovizTransaction, FailedEmitDoesNotStartAttachOrExecute) { Fake_Transaction_Api api; api.emit_succeeds = false; EXPECT_FALSE(static_cast(execute_ordered_artifact_transaction(api))); EXPECT_EQ(api.execute_count, 0U); EXPECT_EQ(api.events, std::vector({"emit"})); } TEST(DatovizOwnership, ShutdownOrderProtectsBorrowedDeviceAndTargets) { std::vector events; ordered_backend_shutdown( [&] { events.emplace_back("runtime"); }, [&] { events.emplace_back("targets"); }, [&] { events.emplace_back("scene"); }, [&] { events.emplace_back("gpu_ctx"); }); EXPECT_EQ(events, std::vector({"runtime", "targets", "scene", "gpu_ctx"})); } } // namespace } // namespace renderive::detail