aboutsummaryrefslogtreecommitdiffstats
path: root/host/tests/actions_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/tests/actions_test.cpp')
-rw-r--r--host/tests/actions_test.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/host/tests/actions_test.cpp b/host/tests/actions_test.cpp
index 142e231cd..4b011361e 100644
--- a/host/tests/actions_test.cpp
+++ b/host/tests/actions_test.cpp
@@ -85,3 +85,140 @@ BOOST_AUTO_TEST_CASE(test_actions_simple_graph)
BOOST_CHECK_EQUAL(
NUM_SAMPS * mock_ddc.get_property<int>("decim", 0), mock_rx_radio.last_num_samps);
}
+
+BOOST_AUTO_TEST_CASE(test_action_forwarding_map)
+{
+ node_accessor_t node_accessor{};
+ uhd::rfnoc::detail::graph_t graph{};
+
+ constexpr size_t NUM_GENERATOR_OUTPUTS = 8;
+ constexpr size_t NUM_RECEIVER_INPUTS = 8;
+
+ node_t::forwarding_map_t fwd_map = {
+ // input edges 0-3 --> output edges 3-0
+ {{res_source_info::INPUT_EDGE, 0}, {{res_source_info::OUTPUT_EDGE, 3}}},
+ {{res_source_info::INPUT_EDGE, 1}, {{res_source_info::OUTPUT_EDGE, 2}}},
+ {{res_source_info::INPUT_EDGE, 2}, {{res_source_info::OUTPUT_EDGE, 1}}},
+ {{res_source_info::INPUT_EDGE, 3}, {{res_source_info::OUTPUT_EDGE, 0}}},
+ // input edge 4 --> output edges 4 and 5
+ {{res_source_info::INPUT_EDGE, 4},
+ {{res_source_info::OUTPUT_EDGE, 4}, {res_source_info::OUTPUT_EDGE, 5}}},
+ // input edge 5 --> output edges 6 and 7
+ {{res_source_info::INPUT_EDGE, 5},
+ {{res_source_info::OUTPUT_EDGE, 6}, {res_source_info::OUTPUT_EDGE, 7}}},
+ // input edge 6 no destination (i.e. drop)
+ {{res_source_info::INPUT_EDGE, 6}, {}}
+ // input edge 7 not in map (i.e. drop)
+ };
+
+ mock_edge_node_t generator{0, NUM_GENERATOR_OUTPUTS, "MOCK_EDGE_NODE<generator>"};
+ mock_routing_node_t router{NUM_GENERATOR_OUTPUTS, NUM_RECEIVER_INPUTS};
+ mock_edge_node_t receiver{NUM_RECEIVER_INPUTS, 0, "MOCK_EDGE_NODE<receiver>"};
+
+ router.set_action_forwarding_map(fwd_map);
+
+ // These init calls would normally be done by the framework
+ node_accessor.init_props(&generator);
+ node_accessor.init_props(&router);
+ node_accessor.init_props(&receiver);
+
+ using graph_edge_t = uhd::rfnoc::detail::graph_t::graph_edge_t;
+
+ // Connect the nodes in the graph
+ for (size_t i = 0; i < NUM_GENERATOR_OUTPUTS; i++) {
+ graph.connect(&generator, &router, {i, i, graph_edge_t::DYNAMIC, true});
+ }
+ for (size_t i = 0; i < NUM_RECEIVER_INPUTS; i++) {
+ graph.connect(&router, &receiver, {i, i, graph_edge_t::DYNAMIC, true});
+ }
+ graph.commit();
+
+ UHD_LOG_INFO("TEST", "Now testing map-driven action forwarding");
+ for (size_t i = 0; i < NUM_GENERATOR_OUTPUTS; i++) {
+ auto cmd = action_info::make("action");
+ // The payload of the outgoing event sent from the generator
+ // consists of the port number on which the action was emitted.
+ // This makes it easier for us to ensure that the action was routed
+ // to the correct receiver port, since the actions are all named
+ // 'action'.
+ cmd->payload.push_back(static_cast<uint8_t>(i));
+ generator.post_output_edge_action(cmd, i);
+ }
+
+ auto received_actions = receiver.get_received_actions_map();
+ auto receiver_port_get_action_count = [received_actions](size_t port) -> size_t {
+ auto itr = received_actions.find({res_source_info::INPUT_EDGE, port});
+ if (itr == received_actions.end()) {
+ return 0;
+ }
+ return itr->second.size();
+ };
+ auto receiver_port_get_action = [received_actions](
+ size_t port, size_t n) -> action_info::sptr {
+ auto itr = received_actions.find({res_source_info::INPUT_EDGE, port});
+ if (itr == received_actions.end()) {
+ // If the action wasn't found, return a dummy action
+ auto bad_action = action_info::make("invalid_action");
+ return bad_action;
+ }
+ return itr->second.at(n);
+ };
+
+ // Ensure correct count of actions at each receiver port
+ BOOST_CHECK_EQUAL(receiver_port_get_action_count(0), 1);
+ BOOST_CHECK_EQUAL(receiver_port_get_action_count(1), 1);
+ BOOST_CHECK_EQUAL(receiver_port_get_action_count(2), 1);
+ BOOST_CHECK_EQUAL(receiver_port_get_action_count(3), 1);
+ BOOST_CHECK_EQUAL(receiver_port_get_action_count(4), 1);
+ BOOST_CHECK_EQUAL(receiver_port_get_action_count(5), 1);
+ BOOST_CHECK_EQUAL(receiver_port_get_action_count(6), 1);
+ BOOST_CHECK_EQUAL(receiver_port_get_action_count(7), 1);
+
+ // Ensure correct payload of received action (indicates source edge from
+ // which the action was generator)
+ BOOST_CHECK_EQUAL(receiver_port_get_action(0, 0)->payload.at(0), 3);
+ BOOST_CHECK_EQUAL(receiver_port_get_action(1, 0)->payload.at(0), 2);
+ BOOST_CHECK_EQUAL(receiver_port_get_action(2, 0)->payload.at(0), 1);
+ BOOST_CHECK_EQUAL(receiver_port_get_action(3, 0)->payload.at(0), 0);
+ BOOST_CHECK_EQUAL(receiver_port_get_action(4, 0)->payload.at(0), 4);
+ BOOST_CHECK_EQUAL(receiver_port_get_action(5, 0)->payload.at(0), 4);
+ BOOST_CHECK_EQUAL(receiver_port_get_action(6, 0)->payload.at(0), 5);
+ BOOST_CHECK_EQUAL(receiver_port_get_action(7, 0)->payload.at(0), 5);
+}
+
+BOOST_AUTO_TEST_CASE(test_action_forwarding_map_exception_invalid_destination)
+{
+ node_accessor_t node_accessor{};
+ uhd::rfnoc::detail::graph_t graph{};
+
+ // Create a map that will generate an exception at action forwarding time
+ // due to the mapping pointing to a non-existent port
+ node_t::forwarding_map_t invalid_fwd_map = {
+ // input edge 0 --> output edge 1 (output port does not exist)
+ {{res_source_info::INPUT_EDGE, 0}, {{res_source_info::OUTPUT_EDGE, 1}}},
+ };
+
+ mock_edge_node_t generator{0, 1, "MOCK_EDGE_NODE<generator>"};
+ mock_routing_node_t router{1, 1};
+ mock_edge_node_t receiver{1, 0, "MOCK_EDGE_NODE<receiver>"};
+
+ router.set_action_forwarding_map(invalid_fwd_map);
+
+ // These init calls would normally be done by the framework
+ node_accessor.init_props(&generator);
+ node_accessor.init_props(&router);
+ node_accessor.init_props(&receiver);
+
+ using graph_edge_t = uhd::rfnoc::detail::graph_t::graph_edge_t;
+
+ // Connect the nodes in the graph
+ graph.connect(&generator, &router, {0, 0, graph_edge_t::DYNAMIC, true});
+ graph.connect(&router, &receiver, {0, 0, graph_edge_t::DYNAMIC, true});
+ graph.commit();
+
+ UHD_LOG_INFO(
+ "TEST", "Now testing action forwarding with invalid map (no destination port)");
+ auto cmd = action_info::make("action");
+ BOOST_REQUIRE_THROW(generator.post_output_edge_action(cmd, 0), uhd::rfnoc_error);
+}
+