From b468a25a6102c0ffe5e0ab90c2d0adfca05bf402 Mon Sep 17 00:00:00 2001 From: Song GUO Date: Wed, 23 Nov 2022 13:39:11 +0800 Subject: [PATCH] [nat64] use dbus API for NAT64 tests (#8392) --- .../nat64/test_multi_border_routers.py | 48 ++++++------- .../nat64/test_single_border_router.py | 12 ++-- tests/scripts/thread-cert/call_dbus_method.py | 2 +- tests/scripts/thread-cert/node.py | 70 ++++++++++++++++++- 4 files changed, 100 insertions(+), 32 deletions(-) diff --git a/tests/scripts/thread-cert/border_router/nat64/test_multi_border_routers.py b/tests/scripts/thread-cert/border_router/nat64/test_multi_border_routers.py index 623b221a3..a53466dec 100644 --- a/tests/scripts/thread-cert/border_router/nat64/test_multi_border_routers.py +++ b/tests/scripts/thread-cert/border_router/nat64/test_multi_border_routers.py @@ -55,10 +55,10 @@ HOST = 4 NAT64_PREFIX_REFRESH_DELAY = 305 -NAT64_STATE_DISABLED = 'Disabled' -NAT64_STATE_NOT_RUNNING = 'NotRunning' -NAT64_STATE_IDLE = 'Idle' -NAT64_STATE_ACTIVE = 'Active' +NAT64_STATE_DISABLED = 'disabled' +NAT64_STATE_NOT_RUNNING = 'not_running' +NAT64_STATE_IDLE = 'idle' +NAT64_STATE_ACTIVE = 'active' class Nat64MultiBorderRouter(thread_cert.TestCase): @@ -111,7 +111,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): self.simulator.go(5) br1.start() - br1.enable_nat64() + br1.nat64_set_enabled(True) self.simulator.go(config.LEADER_STARTUP_DELAY) br1.bash("service bind9 stop") self.simulator.go(NAT64_PREFIX_REFRESH_DELAY) @@ -126,7 +126,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): # it will add the infrastructure nat64 prefix to Network Data. # br2.start() - br2.enable_nat64() + br2.nat64_set_enabled(True) self.simulator.go(config.BORDER_ROUTER_STARTUP_DELAY) self.assertEqual('router', br2.get_state()) @@ -139,11 +139,11 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): nat64_prefix = br1.get_netdata_nat64_prefix()[0] self.assertEqual(nat64_prefix, br2_infra_nat64_prefix) self.assertNotEqual(nat64_prefix, br1_local_nat64_prefix) - self.assertDictIncludes(br1.get_nat64_state(), { + self.assertDictIncludes(br1.nat64_state, { 'PrefixManager': NAT64_STATE_IDLE, 'Translator': NAT64_STATE_NOT_RUNNING }) - self.assertDictIncludes(br2.get_nat64_state(), { + self.assertDictIncludes(br2.nat64_state, { 'PrefixManager': NAT64_STATE_ACTIVE, 'Translator': NAT64_STATE_ACTIVE }) @@ -152,17 +152,17 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): # Case 2. Disable NAT64 on BR2. # BR1 will add its local nat64 prefix. # - br2.disable_nat64() + br2.nat64_set_enabled(False) self.simulator.go(10) self.assertEqual(len(br1.get_netdata_nat64_prefix()), 1) nat64_prefix = br1.get_netdata_nat64_prefix()[0] self.assertEqual(nat64_prefix, br1_local_nat64_prefix) - self.assertDictIncludes(br1.get_nat64_state(), { + self.assertDictIncludes(br1.nat64_state, { 'PrefixManager': NAT64_STATE_ACTIVE, 'Translator': NAT64_STATE_ACTIVE }) - self.assertDictIncludes(br2.get_nat64_state(), { + self.assertDictIncludes(br2.nat64_state, { 'PrefixManager': NAT64_STATE_DISABLED, 'Translator': NAT64_STATE_DISABLED }) @@ -173,7 +173,7 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): # br2.bash("service bind9 stop") self.simulator.go(5) - br2.enable_nat64() + br2.nat64_set_enabled(True) self.simulator.go(10) self.assertNotEqual(br2_infra_nat64_prefix, br2.get_br_favored_nat64_prefix()) @@ -183,11 +183,11 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): nat64_prefix = br1.get_netdata_nat64_prefix()[0] self.assertEqual(nat64_prefix, br1_local_nat64_prefix) self.assertNotEqual(nat64_prefix, br2_local_nat64_prefix) - self.assertDictIncludes(br1.get_nat64_state(), { + self.assertDictIncludes(br1.nat64_state, { 'PrefixManager': NAT64_STATE_ACTIVE, 'Translator': NAT64_STATE_ACTIVE }) - self.assertDictIncludes(br2.get_nat64_state(), { + self.assertDictIncludes(br2.nat64_state, { 'PrefixManager': NAT64_STATE_IDLE, 'Translator': NAT64_STATE_NOT_RUNNING }) @@ -196,18 +196,18 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): # Case 4. Disable NAT64 on BR1. # BR1 withdraws its local prefix and BR2 advertises its local prefix. # - br1.disable_nat64() + br1.nat64_set_enabled(False) self.simulator.go(10) self.assertEqual(len(br1.get_netdata_nat64_prefix()), 1) nat64_prefix = br1.get_netdata_nat64_prefix()[0] self.assertEqual(br2_local_nat64_prefix, nat64_prefix) self.assertNotEqual(br1_local_nat64_prefix, nat64_prefix) - self.assertDictIncludes(br1.get_nat64_state(), { + self.assertDictIncludes(br1.nat64_state, { 'PrefixManager': NAT64_STATE_DISABLED, 'Translator': NAT64_STATE_DISABLED }) - self.assertDictIncludes(br2.get_nat64_state(), { + self.assertDictIncludes(br2.nat64_state, { 'PrefixManager': NAT64_STATE_ACTIVE, 'Translator': NAT64_STATE_ACTIVE }) @@ -216,18 +216,18 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): # Case 5. Re-enable NAT64 on BR1. # NAT64 prefix in Network Data is still BR2's local prefix. # - br1.enable_nat64() + br1.nat64_set_enabled(True) self.simulator.go(10) self.assertEqual(len(br1.get_netdata_nat64_prefix()), 1) nat64_prefix = br1.get_netdata_nat64_prefix()[0] self.assertEqual(br2_local_nat64_prefix, nat64_prefix) self.assertNotEqual(br1_local_nat64_prefix, nat64_prefix) - self.assertDictIncludes(br1.get_nat64_state(), { + self.assertDictIncludes(br1.nat64_state, { 'PrefixManager': NAT64_STATE_IDLE, 'Translator': NAT64_STATE_NOT_RUNNING }) - self.assertDictIncludes(br2.get_nat64_state(), { + self.assertDictIncludes(br2.nat64_state, { 'PrefixManager': NAT64_STATE_ACTIVE, 'Translator': NAT64_STATE_ACTIVE }) @@ -242,11 +242,11 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): nat64_prefix = br1.get_netdata_nat64_prefix()[0] self.assertEqual(br1_local_nat64_prefix, nat64_prefix) self.assertNotEqual(br2_local_nat64_prefix, nat64_prefix) - self.assertDictIncludes(br1.get_nat64_state(), { + self.assertDictIncludes(br1.nat64_state, { 'PrefixManager': NAT64_STATE_ACTIVE, 'Translator': NAT64_STATE_ACTIVE }) - self.assertDictIncludes(br2.get_nat64_state(), { + self.assertDictIncludes(br2.nat64_state, { 'PrefixManager': NAT64_STATE_NOT_RUNNING, 'Translator': NAT64_STATE_NOT_RUNNING }) @@ -261,11 +261,11 @@ class Nat64MultiBorderRouter(thread_cert.TestCase): nat64_prefix = br1.get_netdata_nat64_prefix()[0] self.assertEqual(br1_local_nat64_prefix, nat64_prefix) self.assertNotEqual(br2_local_nat64_prefix, nat64_prefix) - self.assertDictIncludes(br1.get_nat64_state(), { + self.assertDictIncludes(br1.nat64_state, { 'PrefixManager': NAT64_STATE_ACTIVE, 'Translator': NAT64_STATE_ACTIVE }) - self.assertDictIncludes(br2.get_nat64_state(), { + self.assertDictIncludes(br2.nat64_state, { 'PrefixManager': NAT64_STATE_IDLE, 'Translator': NAT64_STATE_NOT_RUNNING }) diff --git a/tests/scripts/thread-cert/border_router/nat64/test_single_border_router.py b/tests/scripts/thread-cert/border_router/nat64/test_single_border_router.py index 687036a1a..7e7c3af4a 100644 --- a/tests/scripts/thread-cert/border_router/nat64/test_single_border_router.py +++ b/tests/scripts/thread-cert/border_router/nat64/test_single_border_router.py @@ -193,13 +193,13 @@ class Nat64SingleBorderRouter(thread_cert.TestCase): host_ip = self.get_host_ip() self.assertTrue(router.ping(ipaddr=host_ip)) - mappings = br.get_nat64_mappings() + mappings = br.nat64_mappings self.assertEqual(mappings[0]['counters']['ICMP']['4to6']['packets'], 1) self.assertEqual(mappings[0]['counters']['ICMP']['6to4']['packets'], 1) self.assertEqual(mappings[0]['counters']['total']['4to6']['packets'], 1) self.assertEqual(mappings[0]['counters']['total']['6to4']['packets'], 1) - counters = br.get_nat64_counters() + counters = br.nat64_counters self.assertEqual(counters['protocol']['ICMP']['4to6']['packets'], 1) self.assertEqual(counters['protocol']['ICMP']['6to4']['packets'], 1) @@ -212,9 +212,9 @@ class Nat64SingleBorderRouter(thread_cert.TestCase): sock.close() - counters = br.get_nat64_counters() + counters = br.nat64_counters self.assertEqual(counters['protocol']['UDP']['6to4']['packets'], 1) - mappings = br.get_nat64_mappings() + mappings = br.nat64_mappings self.assertEqual(mappings[0]['counters']['UDP']['6to4']['packets'], 1) # We should be able to get a IPv4 mapped IPv6 address. @@ -223,13 +223,13 @@ class Nat64SingleBorderRouter(thread_cert.TestCase): ipv6.synthesize_ip6_address(ipaddress.IPv6Network(nat64_prefix), ipaddress.IPv4Address('203.0.113.1'))) self.assertFalse(router.ping(ipaddr=mapped_ip6_address)) - mappings = br.get_nat64_mappings() + mappings = br.nat64_mappings self.assertEqual(mappings[0]['counters']['ICMP']['4to6']['packets'], 1) self.assertEqual(mappings[0]['counters']['ICMP']['6to4']['packets'], 2) self.assertEqual(mappings[0]['counters']['total']['4to6']['packets'], 1) self.assertEqual(mappings[0]['counters']['total']['6to4']['packets'], 3) - counters = br.get_nat64_counters() + counters = br.nat64_counters self.assertEqual(counters['protocol']['ICMP']['4to6']['packets'], 1) self.assertEqual(counters['protocol']['ICMP']['6to4']['packets'], 2) diff --git a/tests/scripts/thread-cert/call_dbus_method.py b/tests/scripts/thread-cert/call_dbus_method.py index 727eb1a94..913c6a51f 100644 --- a/tests/scripts/thread-cert/call_dbus_method.py +++ b/tests/scripts/thread-cert/call_dbus_method.py @@ -34,7 +34,7 @@ import sys def main(): args = sys.argv[1:] bus = dbus.SystemBus() - interface, method_name, arguments = args[0], args[1], args[2:] + interface, method_name, arguments = args[0], args[1], json.loads(args[2]) obj = bus.get_object('io.openthread.BorderRouter.wpan0', '/io/openthread/BorderRouter/wpan0') iface = dbus.Interface(obj, interface) method = getattr(iface, method_name) diff --git a/tests/scripts/thread-cert/node.py b/tests/scripts/thread-cert/node.py index bf58519d2..8b6ae87d5 100755 --- a/tests/scripts/thread-cert/node.py +++ b/tests/scripts/thread-cert/node.py @@ -33,6 +33,7 @@ import ipaddress import logging import os import re +import shlex import socket import subprocess import sys @@ -366,7 +367,7 @@ class OtbrDocker: return dig_result def call_dbus_method(self, *args): - args = ' '.join(args) + args = shlex.join([args[0], args[1], json.dumps(args[2:])]) return json.loads( self.bash(f'python3 /app/third_party/openthread/repo/tests/scripts/thread-cert/call_dbus_method.py {args}') [0]) @@ -386,6 +387,73 @@ class OtbrDocker: logging.info(f'counters = {counters} ') return counters + def _process_traffic_counters(self, counter): + return { + '4to6': { + 'packets': counter[0], + 'bytes': counter[1], + }, + '6to4': { + 'packets': counter[2], + 'bytes': counter[3], + } + } + + def _process_packet_counters(self, counter): + return {'4to6': {'packets': counter[0]}, '6to4': {'packets': counter[1]}} + + def nat64_set_enabled(self, enable): + return self.call_dbus_method('io.openthread.BorderRouter', 'SetNat64Enabled', enable) + + @property + def nat64_state(self): + state = self.get_dbus_property('Nat64State') + return {'PrefixManager': state[0], 'Translator': state[1]} + + @property + def nat64_mappings(self): + return [{ + 'id': row[0], + 'ip4': row[1], + 'ip6': row[2], + 'expiry': row[3], + 'counters': { + 'total': self._process_traffic_counters(row[4][0]), + 'ICMP': self._process_traffic_counters(row[4][1]), + 'UDP': self._process_traffic_counters(row[4][2]), + 'TCP': self._process_traffic_counters(row[4][3]), + } + } for row in self.get_dbus_property('Nat64Mappings')] + + @property + def nat64_counters(self): + res_error = self.get_dbus_property('Nat64ErrorCounters') + res_proto = self.get_dbus_property('Nat64ProtocolCounters') + return { + 'protocol': { + 'Total': self._process_traffic_counters(res_proto[0]), + 'ICMP': self._process_traffic_counters(res_proto[1]), + 'UDP': self._process_traffic_counters(res_proto[2]), + 'TCP': self._process_traffic_counters(res_proto[3]), + }, + 'errors': { + 'Unknown': self._process_packet_counters(res_error[0]), + 'Illegal Pkt': self._process_packet_counters(res_error[1]), + 'Unsup Proto': self._process_packet_counters(res_error[2]), + 'No Mapping': self._process_packet_counters(res_error[3]), + } + } + + @property + def nat64_traffic_counters(self): + res = self.get_dbus_property('Nat64TrafficCounters') + return { + 'Total': self._process_traffic_counters(res[0]), + 'ICMP': self._process_traffic_counters(res[1]), + 'UDP': self._process_traffic_counters(res[2]), + 'TCP': self._process_traffic_counters(res[3]), + } + def read_border_routing_counters_delta(self): old_counters = self._border_routing_counters new_counters = self.get_border_routing_counters()