From a450110b97ad7768e56c53c09db5c1719e750511 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Fri, 14 Jun 2024 11:07:17 +0200 Subject: [PATCH] run/nic_router_uplinks: use test component So far, this test used dynamic_rom for the re-configuration of the nic router and tested for the expected ping results by inspecting the log with the run tool. However, this approach had two issues: * Timing differs significantly on different targets and so the dynamic_rom had the difficult task of compensating with heuristics without bloating the test duration too much. * In case of a failing test, it was difficult to determine the cause as the test kept running and produced output for quite some time and there was also no specific error message but only a generic timeout. These two issues are now fixed by introducing a test component that listens to the ping-result report and manages the nic router configuration. The new component exits early on failure and provides information on the error circumstances. Furthermore, the component advances to the next test step only after having seen the expected result of the active test step and thereby removes the need for heuristics about target timing. Fixes #5192 --- repos/dde_linux/run/nic_router_uplinks.run | 297 ++---------------- .../src/test/nic_router_uplinks/assertion.h | 35 +++ .../src/test/nic_router_uplinks/main.cc | 172 ++++++++++ .../src/test/nic_router_uplinks/target.mk | 14 + 4 files changed, 246 insertions(+), 272 deletions(-) create mode 100644 repos/dde_linux/src/test/nic_router_uplinks/assertion.h create mode 100644 repos/dde_linux/src/test/nic_router_uplinks/main.cc create mode 100644 repos/dde_linux/src/test/nic_router_uplinks/target.mk diff --git a/repos/dde_linux/run/nic_router_uplinks.run b/repos/dde_linux/run/nic_router_uplinks.run index ce5147f004..77fe902d95 100644 --- a/repos/dde_linux/run/nic_router_uplinks.run +++ b/repos/dde_linux/run/nic_router_uplinks.run @@ -7,18 +7,6 @@ proc wifi_ssid {} { proc wifi_psk {} { return "$::env(GENODE_WIFI_PSK2)" } -proc router_verbose {} { - return "no" } - -proc router_verbose_packet_drop {} { - return "no" } - -proc router_verbose_packets {} { - return "no" } - -proc router_verbose_domain_state {} { - return "yes" } - create_boot_directory import_from_depot [depot_user]/src/[base_src] \ [depot_user]/pkg/pc_wifi \ @@ -32,7 +20,7 @@ import_from_depot [depot_user]/src/[base_src] \ [depot_user]/src/report_rom \ [depot_user]/src/pc_rtc -build { app/ping } +build { app/ping server/nic_router test/nic_router_uplinks } install_config { @@ -52,14 +40,16 @@ install_config { - + - + + + @@ -110,7 +100,7 @@ install_config { - + @@ -140,7 +130,7 @@ install_config { - + @@ -152,221 +142,6 @@ install_config { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -375,9 +150,17 @@ install_config { - - - + + + + + + + + + + + @@ -386,8 +169,10 @@ install_config { + @@ -396,42 +181,10 @@ install_config { } +append qemu_args " -nographic " + build_boot_image [build_artifacts] -append done_string ".*router.config: change" -append done_string ".*router.config: sleep 5001 milliseconds" -append done_string ".*64 bytes from 1.1.1.1: icmp_seq=" - -append done_string ".*router.config: change" -append done_string ".*router.config: sleep 5002 milliseconds" -append done_string ".*64 bytes from 1.1.1.1: icmp_seq=" - -append done_string ".*router.config: change" -append done_string ".*router.config: sleep 5003 milliseconds" -append done_string ".*downlink.*invalid domain.*invalid ICMP rule" - -append done_string ".*router.config: change" -append done_string ".*router.config: sleep 5004 milliseconds" -append done_string ".*64 bytes from 1.1.1.1: icmp_seq=" - -append done_string ".*router.config: change" -append done_string ".*router.config: sleep 5005 milliseconds" -append done_string ".*64 bytes from 1.1.1.1: icmp_seq=" - -append done_string ".*router.config: change" -append done_string ".*router.config: sleep 5006 milliseconds" -append done_string ".*downlink.*invalid domain.*invalid ICMP rule" - -append done_string ".*router.config: change" -append done_string ".*router.config: sleep 5007 milliseconds" -append done_string ".*64 bytes from 1.1.1.1: icmp_seq=" - -append done_string ".*router.config: change" -append done_string ".*router.config: sleep 5008 milliseconds" -append done_string ".*64 bytes from 1.1.1.1: icmp_seq=" - -append done_string ".*router.config: change" -append done_string ".*router.config: sleep 600000 milliseconds" -append done_string ".*From 10.0.1.79 icmp_seq=.* Destination Unreachable" - -run_genode_until $done_string 90 +run_genode_until "child \"test\" exited with exit value.*\n" 300 +grep_output {\[init\] child "test" exited with exit value} +compare_output_to {[init] child "test" exited with exit value 0} diff --git a/repos/dde_linux/src/test/nic_router_uplinks/assertion.h b/repos/dde_linux/src/test/nic_router_uplinks/assertion.h new file mode 100644 index 0000000000..b3e6477cc3 --- /dev/null +++ b/repos/dde_linux/src/test/nic_router_uplinks/assertion.h @@ -0,0 +1,35 @@ +/* + * \brief Assertion macros + * \author Martin Stein + * \date 2023-06-09 + */ + +/* + * Copyright (C) 2023 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _TRESOR__ASSERTION_H_ +#define _TRESOR__ASSERTION_H_ + +/* base includes */ +#include +#include + +#define ASSERT(condition) \ + do { \ + if (!(condition)) { \ + Genode::error(__FILE__, ":", __LINE__, ": ", " assertion \"", #condition, "\" failed "); \ + Genode::sleep_forever(); \ + } \ + } while (false) + +#define ASSERT_NEVER_REACHED \ + do { \ + Genode::error(__FILE__, ":", __LINE__, ": ", " should have never been reached"); \ + Genode::sleep_forever(); \ + } while (false) + +#endif /* _TRESOR__ASSERTION_H_ */ diff --git a/repos/dde_linux/src/test/nic_router_uplinks/main.cc b/repos/dde_linux/src/test/nic_router_uplinks/main.cc new file mode 100644 index 0000000000..bb8aeeca46 --- /dev/null +++ b/repos/dde_linux/src/test/nic_router_uplinks/main.cc @@ -0,0 +1,172 @@ +/* + * \brief Server component for Network Address Translation on NIC sessions + * \author Martin Stein + * \date 2016-08-24 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* Genode */ +#include +#include +#include +#include + +/* local */ +#include + +using namespace Genode; + +enum { STEP_TIMEOUT_US = 60*1000*1000 }; + +using Driver = String<16>; + +struct Result +{ + enum { INVALID_ID = ~0U }; + enum Type { REPLY, DESTINATION_UNREACHABLE, INVALID }; + using Type_string = String<32>; + + unsigned id; + Type type; + + static Type string_to_type(Type_string const &string) + { + if (string == "reply") return REPLY; + if (string == "destination_unreachable") return DESTINATION_UNREACHABLE; + return INVALID; + } + + Result(Xml_node const &node) + : + id(node.attribute_value("id", (unsigned)INVALID_ID)), + type(string_to_type(node.attribute_value("type", Type_string()))) + { + ASSERT(id != INVALID_ID && type != INVALID); + } +}; + +struct Goal +{ + Result::Type result_type; + unsigned count; +}; + +struct Main +{ + Env &env; + Expanding_reporter router_config_reporter { env, "config", "router_config" }; + Attached_rom_dataspace result_rom { env, "ping_result" }; + Signal_handler
result_handler { env.ep(), *this, &Main::handle_result }; + unsigned last_result_id = Result::INVALID_ID; + Constructible goal { }; + Timer::Connection timer { env }; + Timer::One_shot_timeout
timeout { timer, *this, &Main::handle_timeout }; + unsigned step { 0UL }; + Constructible driver { }; + + void handle_result() + { + if (!goal.constructed()) { + step_succeeded(); + return; + } + result_rom.update(); + Result result(result_rom.xml()); + if (result.id != last_result_id) { + if (result.type == goal->result_type) { + ASSERT(goal->count); + if (!--goal->count) { + goal.destruct(); + step_succeeded(); + } + } else + warning("test step ", step, " observed unexpected result"); + last_result_id = result.id; + } + } + + void handle_timeout(Duration) + { + error("test step ", step, " timed out"); + env.parent().exit(-1); + } + + void update_router_config() + { + router_config_reporter.generate([&] (Xml_generator &xml) { + xml.attribute("dhcp_discover_timeout_sec", "1"); + xml.node("policy", [&] { + xml.attribute("label_prefix", "ping"); + xml.attribute("domain", "downlink"); }); + xml.node("policy", [&] { + xml.attribute("label_prefix", "dhcp"); + xml.attribute("domain", "uplink"); }); + + if (driver.constructed()) { + xml.node("policy", [&] { + xml.attribute("label_prefix", *driver); + xml.attribute("domain", "uplink"); }); + xml.node("domain", [&] { + xml.attribute("name", "uplink"); + xml.node("nat", [&] { + xml.attribute("domain", "downlink"); + xml.attribute("icmp-ids", "999"); }); }); + } + xml.node("domain", [&] { + xml.attribute("name", "downlink"); + xml.attribute("interface", "10.0.1.79/24"); + xml.node("dhcp-server", [&] { + xml.attribute("ip_first", "10.0.1.80"); + xml.attribute("ip_last", "10.0.1.100"); }); + + if (driver.constructed()) + xml.node("icmp", [&] { + xml.attribute("dst", "0.0.0.0/0"); + xml.attribute("domain", "uplink"); }); }); }); + } + + void start_step(unsigned step_arg, Driver driver_arg = Driver()) + { + if (driver_arg == Driver()) { + driver.destruct(); + goal.construct(Result::DESTINATION_UNREACHABLE, 3); + } else { + driver.construct(driver_arg); + goal.construct(Result::REPLY, 3); + } + timeout.schedule(Microseconds(STEP_TIMEOUT_US)); + update_router_config(); + step = step_arg; + log("test step ", step, " started"); + } + + void step_succeeded() + { + log("test step ", step, " succeeded"); + switch (step) { + case 0: start_step(1, "nic"); break; + case 1: start_step(2, "wifi"); break; + case 2: start_step(3); break; + case 3: start_step(4, "nic"); break; + case 4: start_step(5, "nic"); break; + case 5: start_step(6); break; + case 6: start_step(7, "wifi"); break; + case 7: start_step(8, "nic"); break; + case 8: env.parent().exit(0); break; + } + } + + Main(Env &env) : env(env) + { + result_rom.sigh(result_handler); + handle_result(); + } +}; + +void Component::construct(Env &env) { static Main main(env); } diff --git a/repos/dde_linux/src/test/nic_router_uplinks/target.mk b/repos/dde_linux/src/test/nic_router_uplinks/target.mk new file mode 100644 index 0000000000..2b878ec76e --- /dev/null +++ b/repos/dde_linux/src/test/nic_router_uplinks/target.mk @@ -0,0 +1,14 @@ +TARGET = test-nic_router_uplinks + +LIBS += base + +NIC_ROUTER_DIR := $(call select_from_repositories,src/server/nic_router) + +SRC_CC += main.cc dns.cc xml_node.cc + +INC_DIR += $(PRG_DIR) $(NIC_ROUTER_DIR) + +vpath dns.cc $(NIC_ROUTER_DIR) +vpath xml_node.cc $(NIC_ROUTER_DIR) + +CC_CXX_WARN_STRICT_CONVERSION =