diff options
Diffstat (limited to 'test/asf')
-rw-r--r-- | test/asf/asfframework.py | 72 | ||||
-rw-r--r-- | test/asf/test_adl.py | 2 | ||||
-rw-r--r-- | test/asf/test_api_trace.py | 2 | ||||
-rw-r--r-- | test/asf/test_http_static.py | 2 | ||||
-rw-r--r-- | test/asf/test_lb_api.py | 6 | ||||
-rw-r--r-- | test/asf/test_prom.py | 1 | ||||
-rw-r--r-- | test/asf/test_quic.py | 12 | ||||
-rw-r--r-- | test/asf/test_session.py | 193 | ||||
-rw-r--r-- | test/asf/test_session_sdl.py | 305 | ||||
-rw-r--r-- | test/asf/test_tcp.py | 10 | ||||
-rw-r--r-- | test/asf/test_tls.py | 6 | ||||
-rw-r--r-- | test/asf/test_vcl.py | 107 | ||||
-rw-r--r-- | test/asf/test_vhost.py | 2 | ||||
-rw-r--r-- | test/asf/vpp_session_sdl.py | 75 |
14 files changed, 773 insertions, 22 deletions
diff --git a/test/asf/asfframework.py b/test/asf/asfframework.py index 24880044cec..bd1b45c6476 100644 --- a/test/asf/asfframework.py +++ b/test/asf/asfframework.py @@ -166,25 +166,28 @@ def _is_distro_ubuntu2204(): is_distro_ubuntu2204 = _is_distro_ubuntu2204() -def _is_distro_debian11(): +def _is_distro_ubuntu2404(): with open("/etc/os-release") as f: for line in f.readlines(): - if "bullseye" in line: + if "noble" in line: return True return False -is_distro_debian11 = _is_distro_debian11() +is_distro_ubuntu2404 = _is_distro_ubuntu2404() -def _is_distro_ubuntu2204(): +def _is_distro_debian11(): with open("/etc/os-release") as f: for line in f.readlines(): - if "jammy" in line: + if "bullseye" in line: return True return False +is_distro_debian11 = _is_distro_debian11() + + class KeepAliveReporter(object): """ Singleton object which reports test start to parent process @@ -236,6 +239,8 @@ class TestCaseTag(Enum): FIXME_DEBIAN11 = 5 # marks suites broken on debug vpp image FIXME_VPP_DEBUG = 6 + # marks suites broken on Ubuntu-24.04 + FIXME_UBUNTU2404 = 7 def create_tag_decorator(e): @@ -255,6 +260,7 @@ tag_fixme_asan = create_tag_decorator(TestCaseTag.FIXME_ASAN) tag_fixme_ubuntu2204 = create_tag_decorator(TestCaseTag.FIXME_UBUNTU2204) tag_fixme_debian11 = create_tag_decorator(TestCaseTag.FIXME_DEBIAN11) tag_fixme_vpp_debug = create_tag_decorator(TestCaseTag.FIXME_VPP_DEBUG) +tag_fixme_ubuntu2404 = create_tag_decorator(TestCaseTag.FIXME_UBUNTU2404) class DummyVpp: @@ -317,6 +323,18 @@ class VppAsfTestCase(CPUInterface, unittest.TestCase): cls = unittest.skip("Skipping @tag_fixme_asan tests")(cls) @classmethod + def skip_fixme_ubuntu2204(cls): + """if @tag_fixme_ubuntu2204 & is Ubuntu22.04 - mark for skip""" + if cls.has_tag(TestCaseTag.FIXME_UBUNTU2204) and is_distro_ubuntu2204 == True: + cls = unittest.skip("Skipping @tag_fixme_ubuntu2204 tests")(cls) + + @classmethod + def skip_fixme_ubuntu2404(cls): + """if @tag_fixme_ubuntu2404 & is Ubuntu24.04 - mark for skip""" + if cls.has_tag(TestCaseTag.FIXME_UBUNTU2404) and is_distro_ubuntu2404 == True: + cls = unittest.skip("Skipping @tag_fixme_ubuntu2404 tests")(cls) + + @classmethod def instance(cls): """Return the instance of this testcase""" return cls.test_instance @@ -1155,16 +1173,13 @@ class VppTestResult(unittest.TestResult): self.runner = runner self.printed = [] - def decodePcapFiles(self, test, when_configured=False): - if when_configured == False or config.decode_pcaps == True: - if hasattr(test, "pg_interfaces") and len(test.pg_interfaces) > 0: - testcase_dir = os.path.dirname(test.pg_interfaces[0].out_path) - test.pg_interfaces[0].decode_pcap_files( - testcase_dir, f"suite{test.__class__.__name__}" - ) - test.pg_interfaces[0].decode_pcap_files( - testcase_dir, test._testMethodName - ) + def decodePcapFiles(self, test): + if hasattr(test, "pg_interfaces") and len(test.pg_interfaces) > 0: + testcase_dir = os.path.dirname(test.pg_interfaces[0].out_path) + test.pg_interfaces[0].decode_pcap_files( + testcase_dir, f"suite{test.__class__.__name__}" + ) + test.pg_interfaces[0].decode_pcap_files(testcase_dir, test._testMethodName) def addSuccess(self, test): """ @@ -1174,7 +1189,8 @@ class VppTestResult(unittest.TestResult): """ self.log_result("addSuccess", test) - self.decodePcapFiles(test, when_configured=True) + if "all" == config.decode_pcaps: + self.decodePcapFiles(test) unittest.TestResult.addSuccess(self, test) self.result_string = colorize("OK", GREEN) self.result_code = TestResultCode.PASS @@ -1182,7 +1198,8 @@ class VppTestResult(unittest.TestResult): def addExpectedFailure(self, test, err): self.log_result("addExpectedFailure", test, err) - self.decodePcapFiles(test) + if "none" != config.decode_pcaps: + self.decodePcapFiles(test) super().addExpectedFailure(test, err) self.result_string = colorize("FAIL", GREEN) self.result_code = TestResultCode.EXPECTED_FAIL @@ -1190,7 +1207,8 @@ class VppTestResult(unittest.TestResult): def addUnexpectedSuccess(self, test): self.log_result("addUnexpectedSuccess", test) - self.decodePcapFiles(test, when_configured=True) + if "none" != config.decode_pcaps: + self.decodePcapFiles(test) super().addUnexpectedSuccess(test) self.result_string = colorize("OK", RED) self.result_code = TestResultCode.UNEXPECTED_PASS @@ -1276,7 +1294,9 @@ class VppTestResult(unittest.TestResult): error_type_str = colorize("ERROR", RED) else: raise Exception(f"Unexpected result code {result_code}") - self.decodePcapFiles(test) + + if "none" != config.decode_pcaps: + self.decodePcapFiles(test) unittest_fn(self, test, err) if self.current_test_case_info: @@ -1361,6 +1381,20 @@ class VppTestResult(unittest.TestResult): test_title = colorize(f"FIXME with ASAN: {test_title}", RED) test.skip_fixme_asan() + if ( + test.has_tag(TestCaseTag.FIXME_UBUNTU2204) + and is_distro_ubuntu2204 == True + ): + test_title = colorize(f"FIXME with Ubuntu 22.04: {test_title}", RED) + test.skip_fixme_ubuntu2204() + + if ( + test.has_tag(TestCaseTag.FIXME_UBUNTU2404) + and is_distro_ubuntu2404 == True + ): + test_title = colorize(f"FIXME with Ubuntu 24.04: {test_title}", RED) + test.skip_fixme_ubuntu2404() + if hasattr(test, "vpp_worker_count"): if test.vpp_worker_count == 0: test_title += " [main thread only]" diff --git a/test/asf/test_adl.py b/test/asf/test_adl.py index 7e5ca8dcbe3..70d32bce9da 100644 --- a/test/asf/test_adl.py +++ b/test/asf/test_adl.py @@ -3,8 +3,10 @@ import unittest from asfframework import VppAsfTestCase, VppTestRunner +from config import config +@unittest.skipIf("adl" in config.excluded_plugins, "Exclude ADL plugin tests") class TestAdl(VppAsfTestCase): """Allow/Deny Plugin Unit Test Cases""" diff --git a/test/asf/test_api_trace.py b/test/asf/test_api_trace.py index 8776a79f0ac..04fcf63ca41 100644 --- a/test/asf/test_api_trace.py +++ b/test/asf/test_api_trace.py @@ -37,7 +37,7 @@ class TestJsonApiTrace(VppAsfTestCase): found = True break self.assertTrue(found) - self.assertEquals(o["_msgname"], "show_version") + self.assertEqual(o["_msgname"], "show_version") def test_json_api_trace_replay(self): fname = "/tmp/create_loop.json" diff --git a/test/asf/test_http_static.py b/test/asf/test_http_static.py index 18e8ba56a1e..73a95e992da 100644 --- a/test/asf/test_http_static.py +++ b/test/asf/test_http_static.py @@ -63,11 +63,13 @@ class TestHttpStaticVapi(VppAsfTestCase): "exec", "HttpStatic", "curl", + "-v", f"10.10.1.2/{self.temp.name[5:]}", ], capture_output=True, ) self.assertIn(b"Hello world", process.stdout) + self.assertIn(b"max-age=600", process.stderr) self.temp2.seek(0) process = subprocess.run( diff --git a/test/asf/test_lb_api.py b/test/asf/test_lb_api.py index 9608d0473a6..031479eb7f4 100644 --- a/test/asf/test_lb_api.py +++ b/test/asf/test_lb_api.py @@ -13,10 +13,14 @@ # limitations under the License. from asfframework import VppAsfTestCase +from config import config + +import unittest DEFAULT_VIP = "lb_vip_details(_0=978, context=12, vip=vl_api_lb_ip_addr_t(pfx=IPv6Network(u'::/0'), protocol=<vl_api_ip_proto_t.IP_API_PROTO_RESERVED: 255>, port=0), encap=<vl_api_lb_encap_type_t.LB_API_ENCAP_TYPE_GRE4: 0>, dscp=<vl_api_ip_dscp_t.IP_API_DSCP_CS0: 0>, srv_type=<vl_api_lb_srv_type_t.LB_API_SRV_TYPE_CLUSTERIP: 0>, target_port=0, flow_table_length=0)" # noqa +@unittest.skipIf("lb" in config.excluded_plugins, "Exclude LB plugin tests") class TestLbEmptyApi(VppAsfTestCase): """TestLbEmptyApi""" @@ -34,6 +38,7 @@ class TestLbEmptyApi(VppAsfTestCase): self.assertEqual(rv, [], "Expected: [] Received: %r." % rv) +@unittest.skipIf("lb" in config.excluded_plugins, "Exclude LB plugin tests") class TestLbApi(VppAsfTestCase): """TestLbApi""" @@ -55,6 +60,7 @@ class TestLbApi(VppAsfTestCase): self.vapi.cli("lb vip 2001::/16 del") +@unittest.skipIf("lb" in config.excluded_plugins, "Exclude LB plugin tests") class TestLbAsApi(VppAsfTestCase): """TestLbAsApi""" diff --git a/test/asf/test_prom.py b/test/asf/test_prom.py index 3f8fb4c7a44..f536fd19d34 100644 --- a/test/asf/test_prom.py +++ b/test/asf/test_prom.py @@ -39,6 +39,7 @@ class TestProm(VppAsfTestCase): """Enable HTTP Static server and prometheus exporter, get stats""" self.vapi.cli("http static server uri tcp://0.0.0.0/80 url-handlers") self.vapi.cli("prom enable") + self.sleep(1, "wait for min-scrape-interval to expire") process = subprocess.run( [ diff --git a/test/asf/test_quic.py b/test/asf/test_quic.py index e453bd5b3e5..c4fa6912114 100644 --- a/test/asf/test_quic.py +++ b/test/asf/test_quic.py @@ -117,6 +117,18 @@ class QUICTestCase(VppAsfTestCase): self.logger.debug(self.vapi.cli("show ip fib")) def tearDown(self): + self.vapi.app_namespace_add_del_v4( + is_add=0, + namespace_id=self.server_appns, + secret=self.server_appns_secret, + sw_if_index=self.loop0.sw_if_index, + ) + self.vapi.app_namespace_add_del_v4( + is_add=0, + namespace_id=self.client_appns, + secret=self.client_appns_secret, + sw_if_index=self.loop1.sw_if_index, + ) # Delete inter-table routes self.ip_t01.remove_vpp_config() self.ip_t10.remove_vpp_config() diff --git a/test/asf/test_session.py b/test/asf/test_session.py index 64f59df5758..fe8da126195 100644 --- a/test/asf/test_session.py +++ b/test/asf/test_session.py @@ -8,10 +8,16 @@ from asfframework import ( tag_fixme_vpp_workers, tag_run_solo, ) +from vpp_papi import VppEnum from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath +from ipaddress import IPv4Network +from config import config @tag_fixme_vpp_workers +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class TestSession(VppAsfTestCase): """Session Test Case""" @@ -56,8 +62,16 @@ class TestSession(VppAsfTestCase): i.set_table_ip4(0) i.admin_down() + # Unconfigure namespaces - remove our locks to the vrf tables + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index + ) + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index + ) + super(TestSession, self).tearDown() - self.vapi.session_enable_disable(is_enable=1) + self.vapi.session_enable_disable(is_enable=0) def test_segment_manager_alloc(self): """Session Segment Manager Multiple Segment Allocation""" @@ -109,6 +123,104 @@ class TestSession(VppAsfTestCase): @tag_fixme_vpp_workers +class TestApplicationNamespace(VppAsfTestCase): + """Application Namespacee""" + + @classmethod + def setUpClass(cls): + super(TestApplicationNamespace, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestApplicationNamespace, cls).tearDownClass() + + def setUp(self): + super(TestApplicationNamespace, self).setUp() + self.create_loopback_interfaces(1) + + def tearDown(self): + super(TestApplicationNamespace, self).tearDown() + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE + ) + + def test_application_namespace(self): + """Application Namespace Create""" + + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_RULE_TABLE + ) + + # Configure 2 namespaces, sharing the same interface + app0 = self.vapi.app_namespace_add_del_v4( + namespace_id="0", sw_if_index=self.loop0.sw_if_index + ) + app1 = self.vapi.app_namespace_add_del_v4( + namespace_id="1", sw_if_index=self.loop0.sw_if_index + ) + + self.vapi.session_rule_add_del( + transport_proto=VppEnum.vl_api_transport_proto_t.TRANSPORT_PROTO_API_TCP, + lcl="172.100.1.1/32", + rmt="172.100.1.2/32", + lcl_port=5000, + rmt_port=5000, + action_index=1, + appns_index=app0.appns_index, + scope=VppEnum.vl_api_session_rule_scope_t.SESSION_RULE_SCOPE_API_GLOBAL, + is_add=1, + ) + dump = self.vapi.session_rules_v2_dump() + # session table should contain 3 appns's indices (default, app0, and app1) + self.assertEqual(len(dump[1].appns_index), 3) + self.assertEqual(dump[1].count, 3) + self.assertEqual(dump[1].appns_index[0], 0) + self.assertEqual(dump[1].appns_index[1], app0.appns_index) + self.assertEqual(dump[1].appns_index[2], app1.appns_index) + + # remove the last namespace + self.vapi.app_namespace_add_del_v4( + namespace_id="1", sw_if_index=self.loop0.sw_if_index, is_add=0 + ) + dump = self.vapi.session_rules_v2_dump() + # session table should contain the remainging appns's index + self.assertEqual(len(dump[1].appns_index), 2) + self.assertEqual(dump[1].count, 2) + self.assertEqual(dump[1].appns_index[0], 0) + self.assertEqual(dump[1].appns_index[1], app0.appns_index) + + self.vapi.session_rule_add_del( + transport_proto=VppEnum.vl_api_transport_proto_t.TRANSPORT_PROTO_API_TCP, + lcl="172.100.1.1/32", + rmt="172.100.1.2/32", + lcl_port=5000, + rmt_port=5000, + action_index=1, + appns_index=app0.appns_index, + scope=VppEnum.vl_api_session_rule_scope_t.SESSION_RULE_SCOPE_API_GLOBAL, + is_add=0, + ) + self.vapi.app_namespace_add_del_v4( + namespace_id="0", sw_if_index=self.loop0.sw_if_index, is_add=0 + ) + + # test bad appns index for the API + with self.vapi.assert_negative_api_retval(): + rv = self.vapi.session_rule_add_del( + transport_proto=VppEnum.vl_api_transport_proto_t.TRANSPORT_PROTO_API_TCP, + lcl="172.100.1.1/32", + rmt="172.100.1.2/32", + lcl_port=5000, + rmt_port=5000, + action_index=1, + appns_index=10, + scope=VppEnum.vl_api_session_rule_scope_t.SESSION_RULE_SCOPE_API_GLOBAL, + is_add=1, + ) + self.assertEqual(rv.retval, -1) + + +@tag_fixme_vpp_workers class TestSessionUnitTests(VppAsfTestCase): """Session Unit Tests Case""" @@ -137,6 +249,85 @@ class TestSessionUnitTests(VppAsfTestCase): self.vapi.session_enable_disable(is_enable=0) +@tag_fixme_vpp_workers +class TestSessionRuleTableTests(VppAsfTestCase): + """Session Rule Table Tests Case""" + + @classmethod + def setUpClass(cls): + super(TestSessionRuleTableTests, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestSessionRuleTableTests, cls).tearDownClass() + + def setUp(self): + super(TestSessionRuleTableTests, self).setUp() + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_RULE_TABLE + ) + + def test_session_rule_table(self): + """Session Rule Table Tests""" + + LCL_IP = "172.100.1.1/32" + RMT_IP = "172.100.1.2/32" + LCL_PORT = 5000 + RMT_PORT = 80 + + # Add a rule table entry + self.vapi.session_rule_add_del( + transport_proto=VppEnum.vl_api_transport_proto_t.TRANSPORT_PROTO_API_TCP, + lcl=LCL_IP, + rmt=RMT_IP, + lcl_port=LCL_PORT, + rmt_port=RMT_PORT, + action_index=1, + is_add=1, + appns_index=0, + scope=VppEnum.vl_api_session_rule_scope_t.SESSION_RULE_SCOPE_API_GLOBAL, + tag="rule-1", + ) + + # Verify it is correctly injected + dump = self.vapi.session_rules_dump() + self.assertTrue(len(dump) > 1) + self.assertEqual(dump[1].rmt_port, RMT_PORT) + self.assertEqual(dump[1].lcl_port, LCL_PORT) + self.assertEqual(dump[1].lcl, IPv4Network(LCL_IP)) + self.assertEqual(dump[1].rmt, IPv4Network(RMT_IP)) + self.assertEqual(dump[1].action_index, 1) + self.assertEqual(dump[1].appns_index, 0) + self.assertEqual( + dump[1].scope, + VppEnum.vl_api_session_rule_scope_t.SESSION_RULE_SCOPE_API_GLOBAL, + ) + + # Delete the entry + self.vapi.session_rule_add_del( + transport_proto=VppEnum.vl_api_transport_proto_t.TRANSPORT_PROTO_API_TCP, + lcl=LCL_IP, + rmt=RMT_IP, + lcl_port=LCL_PORT, + rmt_port=RMT_PORT, + action_index=1, + is_add=0, + appns_index=0, + scope=VppEnum.vl_api_session_rule_scope_t.SESSION_RULE_SCOPE_API_GLOBAL, + tag="rule-1", + ) + dump2 = self.vapi.session_rules_dump() + + # Verify it is removed + self.assertTrue((len(dump) - 1) == len(dump2)) + + def tearDown(self): + super(TestSessionRuleTableTests, self).tearDown() + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE + ) + + @tag_run_solo class TestSegmentManagerTests(VppAsfTestCase): """SVM Fifo Unit Tests Case""" diff --git a/test/asf/test_session_sdl.py b/test/asf/test_session_sdl.py new file mode 100644 index 00000000000..952ad10bb79 --- /dev/null +++ b/test/asf/test_session_sdl.py @@ -0,0 +1,305 @@ +#!/usr/bin/env python3 + +import unittest + +from framework import VppTestCase +from asfframework import VppTestRunner, tag_fixme_vpp_workers +from ipaddress import IPv4Network, IPv6Network + +from vpp_ip_route import ( + VppIpRoute, + VppRoutePath, + VppIpTable, +) + +from vpp_papi import VppEnum + + +from vpp_session_sdl import VppSessionSdl +from vpp_session_sdl import SessionSdl + + +@tag_fixme_vpp_workers +class TestSessionSDL(VppTestCase): + """Session SDL Test Case""" + + @classmethod + def setUpClass(cls): + super(TestSessionSDL, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestSessionSDL, cls).tearDownClass() + + def setUp(self): + super(TestSessionSDL, self).setUp() + self.create_loopback_interfaces(2) + + table_id = 0 + + for i in self.lo_interfaces: + i.admin_up() + + if table_id != 0: + tbl = VppIpTable(self, table_id) + tbl.add_vpp_config() + tbl = VppIpTable(self, table_id, is_ip6=1) + tbl.add_vpp_config() + + i.set_table_ip4(table_id) + i.set_table_ip6(table_id) + i.config_ip4() + i.config_ip6() + table_id += 1 + + def tearDown(self): + for i in self.lo_interfaces: + i.unconfig_ip4() + i.set_table_ip4(0) + i.unconfig_ip6() + i.set_table_ip6(0) + i.admin_down() + self.loop0.remove_vpp_config() + self.loop1.remove_vpp_config() + super(TestSessionSDL, self).tearDown() + + def create_rule(self, rmt, action_index, tag): + return SessionSdl(rmt=rmt, action_index=action_index, tag=tag) + + def apply_rules(self, rules, is_add, appns_index): + r = VppSessionSdl(self, rules, is_add=is_add, appns_index=appns_index) + r.add_vpp_config() + + def test_session_sdl_ip4(self): + """Session SDL IP4 test""" + + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL + ) + + # Configure namespaces + app0 = self.vapi.app_namespace_add_del_v4( + namespace_id="0", sw_if_index=self.loop0.sw_if_index + ) + app1 = self.vapi.app_namespace_add_del_v4( + namespace_id="1", sw_if_index=self.loop1.sw_if_index + ) + + # Add inter-table routes + uri = "tcp://" + self.loop0.local_ip4 + "/1234" + server_cmd = "test echo server appns 0 fifo-size 4k " + "uri " + uri + client_cmd = ( + "test echo client bytes 100000 appns 1 " + + "fifo-size 4k " + + "syn-timeout 2 uri " + + uri + ) + ip_t01 = VppIpRoute( + self, + self.loop1.local_ip4, + 32, + [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=1)], + ) + ip_t10 = VppIpRoute( + self, + self.loop0.local_ip4, + 32, + [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=0)], + table_id=1, + ) + ip_t01.add_vpp_config() + ip_t10.add_vpp_config() + + # Start builtin server for ip4 on loop0 appns 0 + self.logger.info(self.vapi.cli(server_cmd)) + + # Add session filter to block loop1 (client on loop1 appns 1) + rules = [] + rules.append( + self.create_rule(rmt=self.loop1.local_ip4 + "/32", action_index=0, tag="") + ) + self.apply_rules(rules, is_add=1, appns_index=0) + + filter = self.vapi.session_sdl_v3_dump() + self.assertEqual(filter[0].rmt, IPv4Network(self.loop1.local_ip4 + "/32")) + self.assertEqual(len(filter[0].appns_index), 2) + self.assertEqual(filter[0].count, 2) + self.assertEqual(filter[0].appns_index[0], 0) + self.assertEqual(filter[0].appns_index[1], app0.appns_index) + + # irrelevant rules - add 64k entries in one API call + rules = [] + for i in range(255): + for j in range(255): + prefix = "10.1.{0}.{1}/32".format(i, j) + rules.append(self.create_rule(rmt=prefix, action_index=0, tag="")) + self.apply_rules(rules, is_add=1, appns_index=0) + + error = self.vapi.cli_return_response(client_cmd) + # Expecting an error because loop1 is blocked + self.assertEqual(-1, error.retval) + + # Remove the session filter + rules = [] + rules.append( + self.create_rule(rmt=self.loop1.local_ip4 + "/32", action_index=0, tag="") + ) + self.apply_rules(rules, is_add=0, appns_index=0) + + # Not expecting an error + self.logger.info(self.vapi.cli(client_cmd)) + + # Add a session filter not matching loop1 + rules = [] + rules.append(self.create_rule(rmt="172.100.1.0/24", action_index=0, tag="")) + self.apply_rules(rules, is_add=1, appns_index=0) + + # Not expecting an error + self.logger.info(self.vapi.cli(client_cmd)) + + self.logger.info(self.vapi.cli(server_cmd + " stop")) + + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index + ) + filter = self.vapi.session_sdl_v3_dump() + self.assertEqual(len(filter[0].appns_index), 1) + self.assertEqual(filter[0].count, 1) + self.assertEqual(filter[0].appns_index[0], 0) + + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index + ) + # Delete inter-table routes + ip_t01.remove_vpp_config() + ip_t10.remove_vpp_config() + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE + ) + + def test_session_sdl_ip6(self): + """Session SDL IP6 test""" + + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL + ) + + # Configure namespaces + self.vapi.app_namespace_add_del_v4( + namespace_id="0", sw_if_index=self.loop0.sw_if_index + ) + self.vapi.app_namespace_add_del_v4( + namespace_id="1", sw_if_index=self.loop1.sw_if_index + ) + + # IP6 Test + # Add inter-table routes + uri = "tcp://" + self.loop0.local_ip6 + "/1235" + client_cmd = ( + "test echo client bytes 100000 appns 1 " + + "fifo-size 4k " + + "syn-timeout 2 uri " + + uri + ) + server_cmd = "test echo server appns 0 fifo-size 4k " + "uri " + uri + + ip_t01 = VppIpRoute( + self, + self.loop1.local_ip6, + 128, + [VppRoutePath("0::0", 0xFFFFFFFF, nh_table_id=1)], + ) + ip_t10 = VppIpRoute( + self, + self.loop0.local_ip6, + 128, + [VppRoutePath("0::0", 0xFFFFFFFF, nh_table_id=0)], + table_id=1, + ) + ip_t01.add_vpp_config() + ip_t10.add_vpp_config() + + # Start builtin server for ip6 on loop0 appns 0 + self.logger.info(self.vapi.cli(server_cmd)) + + # case 1: No filter + + # Not expecting an error + self.logger.info(self.vapi.cli(client_cmd)) + + # case 2: filter to block + # Add session filter to block loop1, client appns 1 + rules = [] + rules.append( + self.create_rule(rmt=self.loop1.local_ip6 + "/128", action_index=0, tag="") + ) + self.apply_rules(rules, is_add=1, appns_index=0) + filter = self.vapi.session_sdl_v2_dump() + self.assertEqual(filter[0].rmt, IPv6Network(self.loop1.local_ip6 + "/128")) + + error = self.vapi.cli_return_response(client_cmd) + # Expecting an error because loop1 is blocked + self.assertEqual(-1, error.retval) + + # case 3: remove filter to unblock + rules = [] + rules.append( + self.create_rule(rmt=self.loop1.local_ip6 + "/128", action_index=0, tag="") + ) + self.apply_rules(rules, is_add=0, appns_index=0) + # Not expecting an error + self.logger.info(self.vapi.cli(client_cmd)) + + # stop the server + self.logger.info(self.vapi.cli(server_cmd + " stop")) + + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index + ) + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index + ) + # Delete inter-table routes + ip_t01.remove_vpp_config() + ip_t10.remove_vpp_config() + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE + ) + + def test_session_enable_disable(self): + """Session SDL enable/disable test""" + + for i in range(10): + # Enable sdl + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL + ) + + # Disable + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE + ) + + # Enable rule-table + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_RULE_TABLE + ) + + # Disable + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE + ) + + # Enable sdl + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL + ) + + # Disable + self.vapi.session_enable_disable_v2( + rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE + ) + + +if __name__ == "__main__": + unittest.main(testRunner=VppTestRunner) diff --git a/test/asf/test_tcp.py b/test/asf/test_tcp.py index 69fc5c472a5..23772d34c76 100644 --- a/test/asf/test_tcp.py +++ b/test/asf/test_tcp.py @@ -4,8 +4,12 @@ import unittest from asfframework import VppAsfTestCase, VppTestRunner from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath +from config import config +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class TestTCP(VppAsfTestCase): """TCP Test Case""" @@ -44,6 +48,12 @@ class TestTCP(VppAsfTestCase): ) def tearDown(self): + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index + ) + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index + ) for i in self.lo_interfaces: i.unconfig_ip4() i.set_table_ip4(0) diff --git a/test/asf/test_tls.py b/test/asf/test_tls.py index d2d1d9a4747..2ce87143339 100644 --- a/test/asf/test_tls.py +++ b/test/asf/test_tls.py @@ -91,6 +91,12 @@ class TestTLS(VppAsfTestCase): ) def tearDown(self): + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index + ) + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index + ) for i in self.lo_interfaces: i.unconfig_ip4() i.set_table_ip4(0) diff --git a/test/asf/test_vcl.py b/test/asf/test_vcl.py index a1113b863e8..124ea14089b 100644 --- a/test/asf/test_vcl.py +++ b/test/asf/test_vcl.py @@ -7,7 +7,7 @@ import subprocess import signal import glob from config import config -from asfframework import VppAsfTestCase, VppTestRunner, Worker +from asfframework import VppAsfTestCase, VppTestRunner, Worker, tag_fixme_ubuntu2404 from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath iperf3 = "/usr/bin/iperf3" @@ -189,6 +189,12 @@ class VCLTestCase(VppAsfTestCase): self.logger.debug(self.vapi.cli("show ip fib")) def thru_host_stack_tear_down(self): + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index + ) + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index + ) for i in self.lo_interfaces: i.unconfig_ip4() i.set_table_ip4(0) @@ -240,6 +246,12 @@ class VCLTestCase(VppAsfTestCase): self.logger.debug(self.vapi.cli("show ip6 fib")) def thru_host_stack_ipv6_tear_down(self): + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index + ) + self.vapi.app_namespace_add_del_v4( + is_add=0, namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index + ) for i in self.lo_interfaces: i.unconfig_ip6() i.set_table_ip6(0) @@ -299,6 +311,7 @@ class VCLTestCase(VppAsfTestCase): self.assert_equal(worker_client.result, 0, "Binary test return code") +@tag_fixme_ubuntu2404 class LDPCutThruTestCase(VCLTestCase): """LDP Cut Thru Tests""" @@ -403,6 +416,9 @@ class LDPCutThruTestCase(VCLTestCase): ) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLCutThruTestCase(VCLTestCase): """VCL Cut Thru Tests""" @@ -489,6 +505,9 @@ class VCLCutThruTestCase(VCLTestCase): ) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLThruHostStackEcho(VCLTestCase): """VCL Thru Host Stack Echo""" @@ -543,6 +562,9 @@ class VCLThruHostStackEcho(VCLTestCase): self.logger.debug(self.vapi.cli("show app mq")) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLThruHostStackTLS(VCLTestCase): """VCL Thru Host Stack TLS""" @@ -594,6 +616,9 @@ class VCLThruHostStackTLS(VCLTestCase): self.logger.debug(self.vapi.cli("show app mq")) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLThruHostStackEchoInterruptMode(VCLThruHostStackEcho): """VCL Thru Host Stack Echo interrupt mode""" @@ -625,6 +650,9 @@ class VCLThruHostStackTLSInterruptMode(VCLThruHostStackTLS): super(VCLThruHostStackTLS, cls).setUpClass() +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLThruHostStackDTLS(VCLTestCase): """VCL Thru Host Stack DTLS""" @@ -675,6 +703,9 @@ class VCLThruHostStackDTLS(VCLTestCase): self.logger.debug(self.vapi.cli("show app mq")) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLThruHostStackQUIC(VCLTestCase): """VCL Thru Host Stack QUIC""" @@ -726,6 +757,62 @@ class VCLThruHostStackQUIC(VCLTestCase): self.logger.debug(self.vapi.cli("show app mq")) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) +class VCLThruHostStackHTTPPost(VCLTestCase): + """VCL Thru Host Stack HTTP Post""" + + @classmethod + def setUpClass(cls): + cls.extra_vpp_plugin_config.append("plugin http_plugin.so { enable }") + super(VCLThruHostStackHTTPPost, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(VCLThruHostStackHTTPPost, cls).tearDownClass() + + def setUp(self): + super(VCLThruHostStackHTTPPost, self).setUp() + + self.thru_host_stack_setup() + self.client_uni_dir_http_post_timeout = 20 + self.server_http_post_args = ["-p", "http", self.server_port] + self.client_uni_dir_http_post_test_args = [ + "-N", + "10000", + "-U", + "-X", + "-p", + "http", + self.loop0.local_ip4, + self.server_port, + ] + + def test_vcl_thru_host_stack_http_post_uni_dir(self): + """run VCL thru host stack uni-directional HTTP POST test""" + + self.timeout = self.client_uni_dir_http_post_timeout + self.thru_host_stack_test( + "vcl_test_server", + self.server_http_post_args, + "vcl_test_client", + self.client_uni_dir_http_post_test_args, + ) + + def tearDown(self): + self.thru_host_stack_tear_down() + super(VCLThruHostStackHTTPPost, self).tearDown() + + def show_commands_at_teardown(self): + self.logger.debug(self.vapi.cli("show app server")) + self.logger.debug(self.vapi.cli("show session verbose 2")) + self.logger.debug(self.vapi.cli("show app mq")) + + +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLThruHostStackBidirNsock(VCLTestCase): """VCL Thru Host Stack Bidir Nsock""" @@ -780,6 +867,9 @@ class VCLThruHostStackBidirNsock(VCLTestCase): ) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class LDPThruHostStackBidirNsock(VCLTestCase): """LDP Thru Host Stack Bidir Nsock""" @@ -830,6 +920,9 @@ class LDPThruHostStackBidirNsock(VCLTestCase): ) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class LDPThruHostStackNsock(VCLTestCase): """LDP Thru Host Stack Nsock""" @@ -879,6 +972,9 @@ class LDPThruHostStackNsock(VCLTestCase): ) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLThruHostStackNsock(VCLTestCase): """VCL Thru Host Stack Nsock""" @@ -928,6 +1024,7 @@ class VCLThruHostStackNsock(VCLTestCase): ) +@tag_fixme_ubuntu2404 class LDPThruHostStackIperf(VCLTestCase): """LDP Thru Host Stack Iperf""" @@ -975,6 +1072,7 @@ class LDPThruHostStackIperf(VCLTestCase): ) +@tag_fixme_ubuntu2404 class LDPThruHostStackIperfUdp(VCLTestCase): """LDP Thru Host Stack Iperf UDP""" @@ -1020,6 +1118,7 @@ class LDPThruHostStackIperfUdp(VCLTestCase): ) +@tag_fixme_ubuntu2404 class LDPIpv6CutThruTestCase(VCLTestCase): """LDP IPv6 Cut Thru Tests""" @@ -1125,6 +1224,9 @@ class LDPIpv6CutThruTestCase(VCLTestCase): ) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLIpv6CutThruTestCase(VCLTestCase): """VCL IPv6 Cut Thru Tests""" @@ -1220,6 +1322,9 @@ class VCLIpv6CutThruTestCase(VCLTestCase): ) +@unittest.skipIf( + "hs_apps" in config.excluded_plugins, "Exclude tests requiring hs_apps plugin" +) class VCLIpv6ThruHostStackEcho(VCLTestCase): """VCL IPv6 Thru Host Stack Echo""" diff --git a/test/asf/test_vhost.py b/test/asf/test_vhost.py index 622716cafe3..f7cdecfa6de 100644 --- a/test/asf/test_vhost.py +++ b/test/asf/test_vhost.py @@ -5,8 +5,10 @@ import unittest from asfframework import VppAsfTestCase, VppTestRunner from vpp_vhost_interface import VppVhostInterface +from config import config +@unittest.skipIf("vhost" in config.excluded_plugins, "Exclude Vhost plugin tests") class TesVhostInterface(VppAsfTestCase): """Vhost User Test Case""" diff --git a/test/asf/vpp_session_sdl.py b/test/asf/vpp_session_sdl.py new file mode 100644 index 00000000000..2bebbe6e49d --- /dev/null +++ b/test/asf/vpp_session_sdl.py @@ -0,0 +1,75 @@ +from ipaddress import IPv4Network + +from vpp_object import VppObject +from vpp_papi import VppEnum +from vpp_ip import INVALID_INDEX +from vpp_papi_provider import UnexpectedApiReturnValueError + + +class SessionSdl: + """Session SDL""" + + def __init__( + self, + rmt, + action_index, + tag, + ): + + self.action_index = action_index + self.rmt = rmt + self.tag = tag + + def encode(self): + return { + "rmt": self.rmt, + "action_index": self.action_index, + "tag": self.tag, + } + + +class VppSessionSdl(VppObject): + """VPP Session SDL""" + + def __init__(self, test, rules, is_add, appns_index): + self._test = test + self._rules = rules + self.is_add = is_add + self.appns_index = appns_index + + @property + def rules(self): + return self._rules + + @property + def count(self): + return len(self._rules) + + def encode_rules(self): + rules = [] + for rule in self._rules: + rules.append(rule.encode()) + return rules + + def add_vpp_config(self, expect_error=False): + try: + reply = self._test.vapi.session_sdl_add_del_v2( + is_add=self.is_add, + appns_index=self.appns_index, + count=self.count, + r=self.encode_rules(), + ) + self._test.registry.register(self, self._test.logger) + if expect_error: + self._test.fail("Unexpected api reply") + return self + except UnexpectedApiReturnValueError: + if not expect_error: + self._test.fail("Unexpected api reply") + return None + + def query_vpp_config(self): + pass + + def remove_vpp_config(self, expect_error=False): + pass |