4b50f49172
- node_runner: track all readers/writers in flow_resources vector, release them via mxlReleaseFlowWriter/mxlReleaseFlowReader before destroying the MXL instance (fixes 'leaked flow writer' warning) - node_runner: remove_writer/remove_reader commands now also release the MXL flow resources, not just reset the node's optional<> - engine: call process_manager.stop_all(graph) on shutdown to kill child node processes (prevents orphaned passthrough processes) - graph: add get_node_mut() for process_manager to update node state - process_manager: implement stop_all(Graph&) that SIGTERMs all running node processes - passthrough: reduce logging to first-grain and realign-once only - tests: update flow format assertion to match NMOS (urn:x-nmos:format:video instead of video/v210)
90 lines
2.6 KiB
C++
90 lines
2.6 KiB
C++
#include <dmf-engine/graph.hpp>
|
|
#include <dmf-engine/flow_manager.hpp>
|
|
|
|
#include <catch2/catch_test_macros.hpp>
|
|
|
|
TEST_CASE("Graph add and remove nodes", "[graph]") {
|
|
dmf_engine::Graph graph;
|
|
|
|
auto id1 = graph.add_node("passthrough");
|
|
auto id2 = graph.add_node("test-source");
|
|
|
|
REQUIRE(graph.get_node(id1) != nullptr);
|
|
REQUIRE(graph.get_node(id2) != nullptr);
|
|
REQUIRE(graph.get_node(id1)->type == "passthrough");
|
|
REQUIRE(graph.get_node(id2)->type == "test-source");
|
|
|
|
auto nodes = graph.get_nodes();
|
|
REQUIRE(nodes.size() == 2);
|
|
|
|
graph.remove_node(id1);
|
|
REQUIRE(graph.get_node(id1) == nullptr);
|
|
REQUIRE(graph.get_nodes().size() == 1);
|
|
}
|
|
|
|
TEST_CASE("Graph add and remove edges", "[graph]") {
|
|
dmf_engine::Graph graph;
|
|
|
|
auto n1 = graph.add_node("test-source");
|
|
auto n2 = graph.add_node("passthrough");
|
|
|
|
auto edge_id = graph.add_edge(n1, "video_out", n2, "video_in", "flow1", {});
|
|
REQUIRE(graph.get_edges().size() == 1);
|
|
|
|
graph.remove_edge(edge_id);
|
|
REQUIRE(graph.get_edges().size() == 0);
|
|
}
|
|
|
|
TEST_CASE("Graph remove node also removes edges", "[graph]") {
|
|
dmf_engine::Graph graph;
|
|
|
|
auto n1 = graph.add_node("test-source");
|
|
auto n2 = graph.add_node("passthrough");
|
|
|
|
graph.add_edge(n1, "video_out", n2, "video_in", "flow1", {});
|
|
graph.add_edge(n2, "video_out", n1, "video_in", "flow2", {});
|
|
|
|
REQUIRE(graph.get_edges().size() == 2);
|
|
|
|
graph.remove_node(n1);
|
|
REQUIRE(graph.get_edges().size() == 0);
|
|
}
|
|
|
|
TEST_CASE("FlowManager creates unique IDs", "[flow_manager]") {
|
|
dmf_engine::FlowManager fm1;
|
|
dmf_engine::FlowManager fm2;
|
|
|
|
auto id1 = fm1.create_flow_id();
|
|
auto id2 = fm1.create_flow_id();
|
|
auto id3 = fm2.create_flow_id();
|
|
|
|
REQUIRE(id1 != id2);
|
|
REQUIRE(id2 != id3);
|
|
}
|
|
|
|
TEST_CASE("FlowManager creates V210 flow definition", "[flow_manager]") {
|
|
dmf_engine::FlowManager fm;
|
|
auto flow_id = fm.create_flow_id();
|
|
auto def = fm.create_v210_flow_def(flow_id, 1920, 1080, 50, 1);
|
|
|
|
REQUIRE(def["id"] == flow_id);
|
|
REQUIRE(def["format"] == "urn:x-nmos:format:video");
|
|
REQUIRE(def["media_type"] == "video/v210");
|
|
REQUIRE(def["frame_width"] == 1920);
|
|
REQUIRE(def["frame_height"] == 1080);
|
|
}
|
|
|
|
TEST_CASE("Graph serialize", "[graph]") {
|
|
dmf_engine::Graph graph;
|
|
|
|
auto n1 = graph.add_node("test-source");
|
|
auto n2 = graph.add_node("passthrough");
|
|
graph.add_edge(n1, "video_out", n2, "video_in", "flow1", {});
|
|
|
|
auto j = graph.serialize();
|
|
REQUIRE(j.contains("nodes"));
|
|
REQUIRE(j.contains("edges"));
|
|
REQUIRE(j["nodes"].size() == 2);
|
|
REQUIRE(j["edges"].size() == 1);
|
|
}
|