From 594de427aaedc15e5c13ca87febe1ed9e5d16866 Mon Sep 17 00:00:00 2001 From: wenda Date: Thu, 11 Apr 2024 15:34:03 +0000 Subject: [PATCH 1/8] implement common functions and single ip assigment test --- tests/common/utilities.py | 7 +- tests/dhcp_server/conftest.py | 27 +++ tests/dhcp_server/test_dhcp_server.py | 337 ++++++++++++++++++++++++++ 3 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 tests/dhcp_server/conftest.py create mode 100644 tests/dhcp_server/test_dhcp_server.py diff --git a/tests/common/utilities.py b/tests/common/utilities.py index 50f1590dcde..9025f6aaef9 100644 --- a/tests/common/utilities.py +++ b/tests/common/utilities.py @@ -1081,6 +1081,8 @@ def capture_and_check_packet_on_dut( interface='any', pkts_filter='', pkts_validator=lambda pkts: pytest_assert(len(pkts) > 0, "No packets captured"), + pkts_validator_args=[], + pkts_validator_kwargs={}, wait_time=1 ): """ @@ -1090,6 +1092,9 @@ def capture_and_check_packet_on_dut( interface: the interface to capture packets on, default is 'any' pkts_filter: the PCAP-FILTER to apply to the captured packets, default is '' means no filter pkts_validator: the function to validate the captured packets, default is to check if any packet is captured + pkts_validator_args: ther args to pass to the pkts_validator function + pkts_validator_kwargs: the kwargs to pass to the pkts_validator function + wait_time: the time to wait before stopping the packet capture, default is 1 second """ pcap_save_path = "/tmp/func_capture_and_check_packet_on_dut_%s.pcap" % (str(uuid.uuid4())) cmd_capture_pkts = "sudo nohup tcpdump --immediate-mode -U -i %s -w %s >/dev/null 2>&1 %s & echo $!" \ @@ -1106,6 +1111,6 @@ def capture_and_check_packet_on_dut( duthost.shell("kill -s 2 %s" % tcpdump_pid) with tempfile.NamedTemporaryFile() as temp_pcap: duthost.fetch(src=pcap_save_path, dest=temp_pcap.name, flat=True) - pkts_validator(scapy_sniff(offline=temp_pcap.name)) + pkts_validator(scapy_sniff(offline=temp_pcap.name), *pkts_validator_args, **pkts_validator_kwargs) finally: duthost.file(path=pcap_save_path, state="absent") diff --git a/tests/dhcp_server/conftest.py b/tests/dhcp_server/conftest.py new file mode 100644 index 00000000000..c306d1fa210 --- /dev/null +++ b/tests/dhcp_server/conftest.py @@ -0,0 +1,27 @@ +import pytest +from tests.common.utilities import wait_until + +DHCP_SERVER_CONTAINER_NAME = "dhcp_server" +DHCP_SERVER_FEATRUE_NAME = "dhcp_server" + + +@pytest.fixture(scope="module", autouse=True) +def dhcp_server_setup_teardown(duthost): + features_state, _ = duthost.get_feature_status() + if DHCP_SERVER_FEATRUE_NAME not in DHCP_SERVER_FEATRUE_NAME: + pytest.fail('There is no dhcp server feature in the DUT') + restore_state_flag = True + if "enabled" not in features_state.get(DHCP_SERVER_FEATRUE_NAME, ""): + duthost.shell("config feature state dhcp_server enabled") + features_state, _ = duthost.get_feature_status() + if "enabled" not in features_state.get(DHCP_SERVER_FEATRUE_NAME, ""): + pytest.fail('Enabling dhcp server feature failed') + else: + restore_state_flag = False + if not wait_until(10, 1, 1, duthost.is_container_running, DHCP_SERVER_CONTAINER_NAME): + pytest.fail('feature dhcp_server is enabled but container is not running') + + yield + + if restore_state_flag: + duthost.shell("config feature state dhcp_server disabled", module_ignore_errors=True) diff --git a/tests/dhcp_server/test_dhcp_server.py b/tests/dhcp_server/test_dhcp_server.py new file mode 100644 index 00000000000..66aa866e61e --- /dev/null +++ b/tests/dhcp_server/test_dhcp_server.py @@ -0,0 +1,337 @@ +import binascii +import logging +import pytest +import ptf.packet as scapy +import ptf.testutils as testutils +from tests.common.utilities import capture_and_check_packet_on_dut +from tests.common.helpers.assertions import pytest_assert + + +pytestmark = [ + pytest.mark.topology('m0', 'mx'), +] + + +VLAN_GATE_WAY = '192.168.0.1' +VLAN_SUBNET_MASK = '255.255.255.0' +DHCP_DEFAULT_LEASE_TIME = 300 +DHCP_DEFAULT_CUSTOM_OPTION_VALUE = 'hello_from_sonic' +DHCP_MAC_BROADCAST = "ff:ff:ff:ff:ff:ff" +DHCP_IP_DEFAULT_ROUTE = "0.0.0.0" +DHCP_IP_BROADCAST = "255.255.255.255" +DHCP_UDP_CLIENT_PORT = 68 +DHCP_UDP_SERVER_PORT = 67 +DHCP_MESSAGE_TYPE_DISCOVER_NUM = 1 +DHCP_MESSAGE_TYPE_OFFER_NUM = 2 +DHCP_MESSAGE_TYPE_REQUEST_NUM = 3 +DHCP_MESSAGE_TYPE_ACK_NUM = 5 +DHCP_MESSAGE_TYPE_NAK_NUM = 6 + + +def clean_fdb_table(duthost): + duthost.shell("sonic-clear fdb all") + + +def ping_dut_refresh_fdb(ptfhost, interface, vlan_ip): + ptfhost.shell("timeout 1 ping -c 1 -w 1 -I {} {}".format(interface, vlan_ip), module_ignore_errors=True) + + +def clean_dhcp_server_config(duthost): + keys = duthost.shell("sonic-db-cli CONFIG_DB KEYS DHCP_SERVER_IPV4*") + for key in keys["stdout_lines"]: + duthost.shell("sonic-db-cli CONFIG_DB DEL '{}'".format(key)) + + +@pytest.fixture(scope="module", autouse=True) +def dhcp_server_config_setup_and_teardown(duthost): + clean_dhcp_server_config(duthost) + config_commands = [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask 255.255.255.0 Vlan1000' % VLAN_GATE_WAY, + 'config dhcp_server ipv4 enable Vlan1000', + # config part 1: for single ip assignment test + 'config dhcp_server ipv4 range add test_single_0 192.168.0.10', + 'config dhcp_server ipv4 bind Vlan1000 Ethernet0 --range test_single_0', + 'config dhcp_server ipv4 range add test_single_1 192.168.0.11', + 'config dhcp_server ipv4 bind Vlan1000 Ethernet1 --range test_single_1', + 'config dhcp_server ipv4 range add test_single_2 192.168.0.12', + 'config dhcp_server ipv4 bind Vlan1000 Ethernet2 --range test_single_2', + # config part 2: for range assignment test + 'config dhcp_server ipv4 range add test_range_5 192.168.0.20 192.168.0.24', + 'config dhcp_server ipv4 bind Vlan1000 Ethernet5 --range test_range_5', + # config part 3: for customize options test + 'config dhcp_server ipv4 option add ' + + 'sonic_test_option 147 string %s' % DHCP_DEFAULT_CUSTOM_OPTION_VALUE, + 'config dhcp_server ipv4 option bind Vlan1000 sonic_test_option' + ] + for cmd in config_commands: + duthost.shell(cmd) + + yield + + clean_dhcp_server_config(duthost) + + +def match_expected_dhcp_options(pkt_dhcp_options, option_name, expected_value): + for option in pkt_dhcp_options: + if option[0] == option_name: + return option[1] == expected_value + return False + + +def convert_mac_to_chaddr(mac): + return binascii.unhexlify(mac.replace(":", "")) + b'\x00' * 10 + + +def create_dhcp_client_packet(src_mac, message_type, client_options=[], xid=123): + dhcp_options = [("message-type", message_type)] + client_options + ["end"] + pkt = scapy.Ether(dst=DHCP_MAC_BROADCAST, src=src_mac) + pkt /= scapy.IP(src=DHCP_IP_DEFAULT_ROUTE, dst=DHCP_IP_BROADCAST) + pkt /= scapy.UDP(sport=DHCP_UDP_CLIENT_PORT, dport=DHCP_UDP_SERVER_PORT) + pkt /= scapy.BOOTP(chaddr=convert_mac_to_chaddr(src_mac), xid=xid) + pkt /= scapy.DHCP(options=dhcp_options) + return pkt + + +def send_and_verify( + duthost, + ptfhost, + ptfadapter, + senario_context, + test_pkt, + pkts_validator, + pkts_validator_args=[], + pkts_validator_kwargs={} +): + dut_port_to_capture_pkt = senario_context['dut_port_to_capture_pkt'] + pkts_filter = "udp dst port %s" % (DHCP_UDP_CLIENT_PORT) + with capture_and_check_packet_on_dut( + duthost=duthost, + interface=dut_port_to_capture_pkt, + pkts_filter=pkts_filter, + pkts_validator=pkts_validator, + pkts_validator_args=pkts_validator_args, + pkts_validator_kwargs=pkts_validator_kwargs, + wait_time=3 + ): + clean_fdb_table(duthost) + if 'refresh_fdb_ptf_port' in senario_context: + ping_dut_refresh_fdb(ptfhost, senario_context['refresh_fdb_ptf_port'], VLAN_GATE_WAY) + ptf_port_index = senario_context['ptf_port_index'] + testutils.send_packet(ptfadapter, ptf_port_index, test_pkt) + + +def validate_dhcp_server_pkts(pkts, test_xid, expected_ip, expected_msg_type): + def is_expected_pkt(pkt): + logging.info("validate_dhcp_server_pkts: %s" % repr(pkt)) + pkt_dhcp_options = pkt[scapy.DHCP].options + if pkt[scapy.BOOTP].xid != test_xid: + return False + elif pkt[scapy.BOOTP].yiaddr != expected_ip: + return False + elif not match_expected_dhcp_options(pkt_dhcp_options, "subnet_mask", VLAN_SUBNET_MASK): + return False + elif not match_expected_dhcp_options(pkt_dhcp_options, "server_id", VLAN_GATE_WAY): + return False + elif not match_expected_dhcp_options(pkt_dhcp_options, "lease_time", DHCP_DEFAULT_LEASE_TIME): + return False + elif not match_expected_dhcp_options(pkt_dhcp_options, "message-type", expected_msg_type): + return False + return True + pytest_assert(len([pkt for pkt in pkts if is_expected_pkt(pkt)]) == 1, + "Didn't got dhcp packet with expected ip and xid") + + +def validate_no_dhcp_server_pkts(pkts, test_xid): + def is_expected_pkt(pkt): + logging.info("validate_no_dhcp_server_pkts: %s" % repr(pkt)) + pkt_dhcp_options = pkt[scapy.DHCP].options + if pkt[scapy.BOOTP].xid != test_xid: + return False + elif match_expected_dhcp_options(pkt_dhcp_options, "message-type", DHCP_MESSAGE_TYPE_NAK_NUM): + return False + return True + pytest_assert(len([pkt for pkt in pkts if is_expected_pkt(pkt)]) == 0, + "Got unexpected dhcp packet") + + +def validate_dhcp_server_pkts_custom_option(pkts, test_xid, **options): + def has_custom_option(pkt): + logging.info("validate_dhcp_server_pkts_custom_option: %s" % repr(pkt)) + if pkt[scapy.BOOTP].xid != test_xid: + return False + pkt_dhcp_options = pkt[scapy.DHCP].options + for option_type, expected_value in options.items(): + if not match_expected_dhcp_options(pkt_dhcp_options, int(option_type), expected_value): + return False + return True + pytest_assert(len([pkt for pkt in pkts if has_custom_option(pkt)]) == 1, + "Didn't got dhcp packet with expected custom option") + + +# dhcp_server/test_dhcp_server.py::test_dhcp_server_port_based_assignment_single_ip +@pytest.mark.parametrize('senario_context', [ + { + 'description': 'Verify configured interface with \ + client mac not in FDB table can successfully get IP', + 'dut_port_to_capture_pkt': 'Ethernet0', + 'expected_assigned_ip': '192.168.0.10', + 'ptf_port_index': 0, + "test_xid": 11 + }, + { + 'description': 'Verify configured interface with \ + client mac in FDB table can successfully get IP', + 'dut_port_to_capture_pkt': 'Ethernet1', + 'expected_assigned_ip': '192.168.0.11', + 'ptf_port_index': 1, + 'refresh_fdb_ptf_port': 'eth1', + "test_xid": 12 + }, + { + 'description': 'Verify configured interface with \ + client mac in FDB table but mac was learnt \ + from another interface can successfully get IP.', + 'dut_port_to_capture_pkt': 'Ethernet2', + 'expected_assigned_ip': '192.168.0.12', + 'ptf_mac_port_index': 3, + 'ptf_port_index': 2, + 'refresh_fdb_ptf_port': 'eth3', + "test_xid": 13 + }, + { + 'description': 'Verify no-configured interface cannot get IP', + 'dut_port_to_capture_pkt': 'any', + "expected_assigned_ip": None, + 'ptf_port_index': 4, + 'refresh_fdb_ptf_port': 'eth4', + "test_xid": 14 + } +]) +def test_dhcp_server_port_based_assignment_single_ip(duthost, ptfhost, ptfadapter, senario_context): + """ + Test single ip assignment with different senarios, each senario has a description in senario_context. + """ + test_xid = senario_context['test_xid'] + ptf_mac_port_index = senario_context.get('ptf_mac_port_index', senario_context['ptf_port_index']) + client_mac = ptfadapter.dataplane.get_mac(0, ptf_mac_port_index).decode('utf-8') + expected_ip = senario_context['expected_assigned_ip'] + pkts_validator = validate_dhcp_server_pkts if expected_ip else validate_no_dhcp_server_pkts + pkts_validator_args = [test_xid, expected_ip, DHCP_MESSAGE_TYPE_OFFER_NUM] if expected_ip else [test_xid] + discover_pkt = create_dhcp_client_packet( + src_mac=client_mac, + message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, + client_options=[], + xid=test_xid + ) + send_and_verify( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + senario_context=senario_context, + test_pkt=discover_pkt, + pkts_validator=pkts_validator, + pkts_validator_args=pkts_validator_args + ) + request_pkt = create_dhcp_client_packet( + src_mac=client_mac, + message_type=DHCP_MESSAGE_TYPE_REQUEST_NUM, + client_options=[("requested_addr", expected_ip), ("server_id", VLAN_GATE_WAY)], + xid=test_xid + ) + pkts_validator_args = [test_xid, expected_ip, DHCP_MESSAGE_TYPE_ACK_NUM] if expected_ip else [test_xid] + send_and_verify( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + senario_context=senario_context, + test_pkt=request_pkt, + pkts_validator=pkts_validator, + pkts_validator_args=pkts_validator_args + ) + + +@pytest.mark.parametrize('senario_context', [ + { + 'dut_port_to_capture_pkt': 'Ethernet5', + 'expected_assigned_ip': '192.168.0.20', + 'ptf_port_index': 5, + "test_xid": 15 + } +]) +def test_dhcp_server_port_based_assignment_range(duthost, ptfhost, ptfadapter, senario_context): + """ + Test range ip assignment + """ + test_xid = senario_context['test_xid'] + ptf_mac_port_index = senario_context.get('ptf_mac_port_index', senario_context['ptf_port_index']) + client_mac = ptfadapter.dataplane.get_mac(0, ptf_mac_port_index).decode('utf-8') + expected_ip = senario_context['expected_assigned_ip'] + pkts_validator = validate_dhcp_server_pkts if expected_ip else validate_no_dhcp_server_pkts + pkts_validator_args = [test_xid, expected_ip, DHCP_MESSAGE_TYPE_OFFER_NUM] if expected_ip else [test_xid] + discover_pkt = create_dhcp_client_packet( + src_mac=client_mac, + message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, + client_options=[], + xid=test_xid + ) + send_and_verify( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + senario_context=senario_context, + test_pkt=discover_pkt, + pkts_validator=pkts_validator, + pkts_validator_args=pkts_validator_args + ) + request_pkt = create_dhcp_client_packet( + src_mac=client_mac, + message_type=DHCP_MESSAGE_TYPE_REQUEST_NUM, + client_options=[("requested_addr", expected_ip), ("server_id", VLAN_GATE_WAY)], + xid=test_xid + ) + pkts_validator_args = [test_xid, expected_ip, DHCP_MESSAGE_TYPE_ACK_NUM] if expected_ip else [test_xid] + send_and_verify( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + senario_context=senario_context, + test_pkt=request_pkt, + pkts_validator=pkts_validator, + pkts_validator_args=pkts_validator_args + ) + + +@pytest.mark.parametrize('senario_context', [ + { + 'dut_port_to_capture_pkt': 'Ethernet5', + 'ptf_port_index': 5, + "test_xid": 16 + } +]) +def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, senario_context): + """ + Test dhcp server packets if carry the customized options as expected + """ + test_xid = senario_context['test_xid'] + ptf_mac_port_index = senario_context['ptf_port_index'] + client_mac = ptfadapter.dataplane.get_mac(0, ptf_mac_port_index).decode('utf-8') + pkts_validator = validate_dhcp_server_pkts_custom_option + pkts_validator_args = [test_xid] + pkts_validator_kwargs = {"147": DHCP_DEFAULT_CUSTOM_OPTION_VALUE.encode('ascii')} + discover_pkt = create_dhcp_client_packet( + src_mac=client_mac, + message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, + client_options=[], + xid=test_xid + ) + send_and_verify( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + senario_context=senario_context, + test_pkt=discover_pkt, + pkts_validator=pkts_validator, + pkts_validator_args=pkts_validator_args, + pkts_validator_kwargs=pkts_validator_kwargs + ) From b447ab38763ea679e28a790db851dd3ea34317af Mon Sep 17 00:00:00 2001 From: wenda Date: Tue, 16 Apr 2024 04:18:33 +0000 Subject: [PATCH 2/8] split single configuration for all into per test case. --- tests/dhcp_server/conftest.py | 6 +- tests/dhcp_server/test_dhcp_server.py | 512 +++++++++++++++++--------- 2 files changed, 341 insertions(+), 177 deletions(-) diff --git a/tests/dhcp_server/conftest.py b/tests/dhcp_server/conftest.py index c306d1fa210..df2171524db 100644 --- a/tests/dhcp_server/conftest.py +++ b/tests/dhcp_server/conftest.py @@ -8,14 +8,11 @@ @pytest.fixture(scope="module", autouse=True) def dhcp_server_setup_teardown(duthost): features_state, _ = duthost.get_feature_status() - if DHCP_SERVER_FEATRUE_NAME not in DHCP_SERVER_FEATRUE_NAME: + if DHCP_SERVER_FEATRUE_NAME not in features_state: pytest.fail('There is no dhcp server feature in the DUT') restore_state_flag = True if "enabled" not in features_state.get(DHCP_SERVER_FEATRUE_NAME, ""): duthost.shell("config feature state dhcp_server enabled") - features_state, _ = duthost.get_feature_status() - if "enabled" not in features_state.get(DHCP_SERVER_FEATRUE_NAME, ""): - pytest.fail('Enabling dhcp server feature failed') else: restore_state_flag = False if not wait_until(10, 1, 1, duthost.is_container_running, DHCP_SERVER_CONTAINER_NAME): @@ -25,3 +22,4 @@ def dhcp_server_setup_teardown(duthost): if restore_state_flag: duthost.shell("config feature state dhcp_server disabled", module_ignore_errors=True) + duthost.shell("docker rm dhcp_server", module_ignore_errors=True) diff --git a/tests/dhcp_server/test_dhcp_server.py b/tests/dhcp_server/test_dhcp_server.py index 66aa866e61e..d563b333c63 100644 --- a/tests/dhcp_server/test_dhcp_server.py +++ b/tests/dhcp_server/test_dhcp_server.py @@ -1,8 +1,11 @@ import binascii +import contextlib import logging +import ipaddress import pytest import ptf.packet as scapy import ptf.testutils as testutils +import random from tests.common.utilities import capture_and_check_packet_on_dut from tests.common.helpers.assertions import pytest_assert @@ -11,9 +14,8 @@ pytest.mark.topology('m0', 'mx'), ] - -VLAN_GATE_WAY = '192.168.0.1' -VLAN_SUBNET_MASK = '255.255.255.0' +MINIMUM_HOSTS_COUNT = 2 +MINIMUM_INTERFACE_MEMBERS_COUNT = 2 DHCP_DEFAULT_LEASE_TIME = 300 DHCP_DEFAULT_CUSTOM_OPTION_VALUE = 'hello_from_sonic' DHCP_MAC_BROADCAST = "ff:ff:ff:ff:ff:ff" @@ -26,14 +28,15 @@ DHCP_MESSAGE_TYPE_REQUEST_NUM = 3 DHCP_MESSAGE_TYPE_ACK_NUM = 5 DHCP_MESSAGE_TYPE_NAK_NUM = 6 +DHCP_MESSAGE_TYPE_RELEASE_NUM = 7 def clean_fdb_table(duthost): duthost.shell("sonic-clear fdb all") -def ping_dut_refresh_fdb(ptfhost, interface, vlan_ip): - ptfhost.shell("timeout 1 ping -c 1 -w 1 -I {} {}".format(interface, vlan_ip), module_ignore_errors=True) +def ping_dut_refresh_fdb(ptfhost, interface): + ptfhost.shell("timeout 1 ping -c 1 -w 1 -I {} 255.255.255.255 -b".format(interface), module_ignore_errors=True) def clean_dhcp_server_config(duthost): @@ -42,28 +45,44 @@ def clean_dhcp_server_config(duthost): duthost.shell("sonic-db-cli CONFIG_DB DEL '{}'".format(key)) -@pytest.fixture(scope="module", autouse=True) -def dhcp_server_config_setup_and_teardown(duthost): +@pytest.fixture(scope="module") +def parse_vlan_setting_from_running_config(duthost, tbinfo): + vlan_brief = duthost.get_vlan_brief() + first_vlan_name = list(vlan_brief.keys())[0] + first_vlan_info = list(vlan_brief.values())[0] + first_vlan_prefix = first_vlan_info['interface_ipv4'][0] + connected_ptf_ports_idx = tbinfo['topo']['properties']['topology']['host_interfaces'] + dut_intf_to_ptf_index = duthost.get_extended_minigraph_facts(tbinfo)['minigraph_ptf_indices'] + connected_dut_intf_to_ptf_index = {k: v for k, v in dut_intf_to_ptf_index.items() if v in connected_ptf_ports_idx} + vlan_members = first_vlan_info['members'] + vlan_member_with_ptf_idx = [(member, connected_dut_intf_to_ptf_index[member]) + for member in vlan_members if member in dut_intf_to_ptf_index] + pytest_assert(len(vlan_members) >= MINIMUM_INTERFACE_MEMBERS_COUNT, 'Vlan size is too small for testing') + vlan_net = ipaddress.ip_network(address=first_vlan_prefix, strict=False) + vlan_gate_way = first_vlan_prefix.split('/')[0] + vlan_hosts = [str(host) for host in vlan_net.hosts()] + # to avoid configurate an range contains gateway ip, simply ignore all ip before gateway and gateway itself + vlan_hosts_after_gateway = vlan_hosts[vlan_hosts.index(vlan_gate_way) + 1:] + pytest_assert(len(vlan_hosts_after_gateway) >= MINIMUM_HOSTS_COUNT, 'Vlan size is too small for testing') + vlan_setting = { + 'vlan_name': first_vlan_name, + 'vlan_gate_way': vlan_gate_way, + 'vlan_subnet_mask': str(vlan_net.netmask), + 'vlan_hosts': vlan_hosts_after_gateway, + 'vlan_member_with_ptf_idx': vlan_member_with_ptf_idx, + } + + logging.info("The vlan_setting before test is %s" % vlan_setting) + return vlan_setting['vlan_name'], \ + vlan_setting['vlan_gate_way'], \ + vlan_setting['vlan_subnet_mask'], \ + vlan_setting['vlan_hosts'], \ + vlan_setting['vlan_member_with_ptf_idx'] + + +@contextlib.contextmanager +def dhcp_server_config(duthost, config_commands): clean_dhcp_server_config(duthost) - config_commands = [ - 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask 255.255.255.0 Vlan1000' % VLAN_GATE_WAY, - 'config dhcp_server ipv4 enable Vlan1000', - # config part 1: for single ip assignment test - 'config dhcp_server ipv4 range add test_single_0 192.168.0.10', - 'config dhcp_server ipv4 bind Vlan1000 Ethernet0 --range test_single_0', - 'config dhcp_server ipv4 range add test_single_1 192.168.0.11', - 'config dhcp_server ipv4 bind Vlan1000 Ethernet1 --range test_single_1', - 'config dhcp_server ipv4 range add test_single_2 192.168.0.12', - 'config dhcp_server ipv4 bind Vlan1000 Ethernet2 --range test_single_2', - # config part 2: for range assignment test - 'config dhcp_server ipv4 range add test_range_5 192.168.0.20 192.168.0.24', - 'config dhcp_server ipv4 bind Vlan1000 Ethernet5 --range test_range_5', - # config part 3: for customize options test - 'config dhcp_server ipv4 option add ' + - 'sonic_test_option 147 string %s' % DHCP_DEFAULT_CUSTOM_OPTION_VALUE, - 'config dhcp_server ipv4 option bind Vlan1000 sonic_test_option' - ] for cmd in config_commands: duthost.shell(cmd) @@ -83,12 +102,12 @@ def convert_mac_to_chaddr(mac): return binascii.unhexlify(mac.replace(":", "")) + b'\x00' * 10 -def create_dhcp_client_packet(src_mac, message_type, client_options=[], xid=123): +def create_dhcp_client_packet(src_mac, message_type, client_options=[], xid=123, ciaddr='0.0.0.0'): dhcp_options = [("message-type", message_type)] + client_options + ["end"] pkt = scapy.Ether(dst=DHCP_MAC_BROADCAST, src=src_mac) pkt /= scapy.IP(src=DHCP_IP_DEFAULT_ROUTE, dst=DHCP_IP_BROADCAST) pkt /= scapy.UDP(sport=DHCP_UDP_CLIENT_PORT, dport=DHCP_UDP_SERVER_PORT) - pkt /= scapy.BOOTP(chaddr=convert_mac_to_chaddr(src_mac), xid=xid) + pkt /= scapy.BOOTP(chaddr=convert_mac_to_chaddr(src_mac), xid=xid, ciaddr=ciaddr) pkt /= scapy.DHCP(options=dhcp_options) return pkt @@ -97,13 +116,14 @@ def send_and_verify( duthost, ptfhost, ptfadapter, - senario_context, test_pkt, + dut_port_to_capture_pkt, + ptf_port_index, pkts_validator, pkts_validator_args=[], - pkts_validator_kwargs={} + pkts_validator_kwargs={}, + refresh_fdb_ptf_port=None ): - dut_port_to_capture_pkt = senario_context['dut_port_to_capture_pkt'] pkts_filter = "udp dst port %s" % (DHCP_UDP_CLIENT_PORT) with capture_and_check_packet_on_dut( duthost=duthost, @@ -115,13 +135,12 @@ def send_and_verify( wait_time=3 ): clean_fdb_table(duthost) - if 'refresh_fdb_ptf_port' in senario_context: - ping_dut_refresh_fdb(ptfhost, senario_context['refresh_fdb_ptf_port'], VLAN_GATE_WAY) - ptf_port_index = senario_context['ptf_port_index'] + if refresh_fdb_ptf_port: + ping_dut_refresh_fdb(ptfhost, refresh_fdb_ptf_port) testutils.send_packet(ptfadapter, ptf_port_index, test_pkt) -def validate_dhcp_server_pkts(pkts, test_xid, expected_ip, expected_msg_type): +def validate_dhcp_server_pkts(pkts, test_xid, expected_ip, exp_msg_type, exp_net_mask, exp_server_ip): def is_expected_pkt(pkt): logging.info("validate_dhcp_server_pkts: %s" % repr(pkt)) pkt_dhcp_options = pkt[scapy.DHCP].options @@ -129,13 +148,13 @@ def is_expected_pkt(pkt): return False elif pkt[scapy.BOOTP].yiaddr != expected_ip: return False - elif not match_expected_dhcp_options(pkt_dhcp_options, "subnet_mask", VLAN_SUBNET_MASK): + elif not match_expected_dhcp_options(pkt_dhcp_options, "subnet_mask", exp_net_mask): return False - elif not match_expected_dhcp_options(pkt_dhcp_options, "server_id", VLAN_GATE_WAY): + elif not match_expected_dhcp_options(pkt_dhcp_options, "server_id", exp_server_ip): return False elif not match_expected_dhcp_options(pkt_dhcp_options, "lease_time", DHCP_DEFAULT_LEASE_TIME): return False - elif not match_expected_dhcp_options(pkt_dhcp_options, "message-type", expected_msg_type): + elif not match_expected_dhcp_options(pkt_dhcp_options, "message-type", exp_msg_type): return False return True pytest_assert(len([pkt for pkt in pkts if is_expected_pkt(pkt)]) == 1, @@ -169,55 +188,23 @@ def has_custom_option(pkt): "Didn't got dhcp packet with expected custom option") -# dhcp_server/test_dhcp_server.py::test_dhcp_server_port_based_assignment_single_ip -@pytest.mark.parametrize('senario_context', [ - { - 'description': 'Verify configured interface with \ - client mac not in FDB table can successfully get IP', - 'dut_port_to_capture_pkt': 'Ethernet0', - 'expected_assigned_ip': '192.168.0.10', - 'ptf_port_index': 0, - "test_xid": 11 - }, - { - 'description': 'Verify configured interface with \ - client mac in FDB table can successfully get IP', - 'dut_port_to_capture_pkt': 'Ethernet1', - 'expected_assigned_ip': '192.168.0.11', - 'ptf_port_index': 1, - 'refresh_fdb_ptf_port': 'eth1', - "test_xid": 12 - }, - { - 'description': 'Verify configured interface with \ - client mac in FDB table but mac was learnt \ - from another interface can successfully get IP.', - 'dut_port_to_capture_pkt': 'Ethernet2', - 'expected_assigned_ip': '192.168.0.12', - 'ptf_mac_port_index': 3, - 'ptf_port_index': 2, - 'refresh_fdb_ptf_port': 'eth3', - "test_xid": 13 - }, - { - 'description': 'Verify no-configured interface cannot get IP', - 'dut_port_to_capture_pkt': 'any', - "expected_assigned_ip": None, - 'ptf_port_index': 4, - 'refresh_fdb_ptf_port': 'eth4', - "test_xid": 14 - } -]) -def test_dhcp_server_port_based_assignment_single_ip(duthost, ptfhost, ptfadapter, senario_context): - """ - Test single ip assignment with different senarios, each senario has a description in senario_context. - """ - test_xid = senario_context['test_xid'] - ptf_mac_port_index = senario_context.get('ptf_mac_port_index', senario_context['ptf_port_index']) +def verify_discover_and_request_then_release( + duthost, + ptfhost, + ptfadapter, + dut_port_to_capture_pkt, + test_xid, + ptf_port_index, + ptf_mac_port_index, + expected_assigned_ip, + exp_server_ip, + net_mask, + refresh_fdb_ptf_port=None +): client_mac = ptfadapter.dataplane.get_mac(0, ptf_mac_port_index).decode('utf-8') - expected_ip = senario_context['expected_assigned_ip'] - pkts_validator = validate_dhcp_server_pkts if expected_ip else validate_no_dhcp_server_pkts - pkts_validator_args = [test_xid, expected_ip, DHCP_MESSAGE_TYPE_OFFER_NUM] if expected_ip else [test_xid] + pkts_validator = validate_dhcp_server_pkts if expected_assigned_ip else validate_no_dhcp_server_pkts + pkts_validator_args = [test_xid, expected_assigned_ip, DHCP_MESSAGE_TYPE_OFFER_NUM, net_mask, exp_server_ip] \ + if expected_assigned_ip else [test_xid] discover_pkt = create_dhcp_client_packet( src_mac=client_mac, message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, @@ -228,110 +215,289 @@ def test_dhcp_server_port_based_assignment_single_ip(duthost, ptfhost, ptfadapte duthost=duthost, ptfhost=ptfhost, ptfadapter=ptfadapter, - senario_context=senario_context, + dut_port_to_capture_pkt=dut_port_to_capture_pkt, + ptf_port_index=ptf_port_index, test_pkt=discover_pkt, pkts_validator=pkts_validator, - pkts_validator_args=pkts_validator_args + pkts_validator_args=pkts_validator_args, + refresh_fdb_ptf_port=refresh_fdb_ptf_port ) request_pkt = create_dhcp_client_packet( src_mac=client_mac, message_type=DHCP_MESSAGE_TYPE_REQUEST_NUM, - client_options=[("requested_addr", expected_ip), ("server_id", VLAN_GATE_WAY)], + client_options=[("requested_addr", expected_assigned_ip), ("server_id", exp_server_ip)], xid=test_xid ) - pkts_validator_args = [test_xid, expected_ip, DHCP_MESSAGE_TYPE_ACK_NUM] if expected_ip else [test_xid] + pkts_validator_args = [test_xid, expected_assigned_ip, DHCP_MESSAGE_TYPE_ACK_NUM, net_mask, exp_server_ip] \ + if expected_assigned_ip else [test_xid] send_and_verify( duthost=duthost, ptfhost=ptfhost, ptfadapter=ptfadapter, - senario_context=senario_context, + dut_port_to_capture_pkt=dut_port_to_capture_pkt, + ptf_port_index=ptf_port_index, test_pkt=request_pkt, pkts_validator=pkts_validator, - pkts_validator_args=pkts_validator_args + pkts_validator_args=pkts_validator_args, + refresh_fdb_ptf_port=refresh_fdb_ptf_port ) - - -@pytest.mark.parametrize('senario_context', [ - { - 'dut_port_to_capture_pkt': 'Ethernet5', - 'expected_assigned_ip': '192.168.0.20', - 'ptf_port_index': 5, - "test_xid": 15 - } -]) -def test_dhcp_server_port_based_assignment_range(duthost, ptfhost, ptfadapter, senario_context): + if expected_assigned_ip: + release_pkt = create_dhcp_client_packet( + src_mac=client_mac, + message_type=DHCP_MESSAGE_TYPE_RELEASE_NUM, + client_options=[("server_id", exp_server_ip)], + xid=test_xid, + ciaddr=expected_assigned_ip + ) + pkts_validator_args = [test_xid, expected_assigned_ip, DHCP_MESSAGE_TYPE_ACK_NUM, net_mask, exp_server_ip] + send_and_verify( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port_to_capture_pkt, + ptf_port_index=ptf_port_index, + test_pkt=release_pkt, + pkts_validator=pkts_validator, + pkts_validator_args=pkts_validator_args, + refresh_fdb_ptf_port=refresh_fdb_ptf_port + ) + + +def test_dhcp_server_port_based_assignment_single_ip_s1( + duthost, + ptfhost, + ptfadapter, + parse_vlan_setting_from_running_config +): """ - Test range ip assignment + Verify configured interface with client mac not in FDB table can successfully get IP """ - test_xid = senario_context['test_xid'] - ptf_mac_port_index = senario_context.get('ptf_mac_port_index', senario_context['ptf_port_index']) - client_mac = ptfadapter.dataplane.get_mac(0, ptf_mac_port_index).decode('utf-8') - expected_ip = senario_context['expected_assigned_ip'] - pkts_validator = validate_dhcp_server_pkts if expected_ip else validate_no_dhcp_server_pkts - pkts_validator_args = [test_xid, expected_ip, DHCP_MESSAGE_TYPE_OFFER_NUM] if expected_ip else [test_xid] - discover_pkt = create_dhcp_client_packet( - src_mac=client_mac, - message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, - client_options=[], - xid=test_xid - ) - send_and_verify( - duthost=duthost, - ptfhost=ptfhost, - ptfadapter=ptfadapter, - senario_context=senario_context, - test_pkt=discover_pkt, - pkts_validator=pkts_validator, - pkts_validator_args=pkts_validator_args - ) - request_pkt = create_dhcp_client_packet( - src_mac=client_mac, - message_type=DHCP_MESSAGE_TYPE_REQUEST_NUM, - client_options=[("requested_addr", expected_ip), ("server_id", VLAN_GATE_WAY)], - xid=test_xid - ) - pkts_validator_args = [test_xid, expected_ip, DHCP_MESSAGE_TYPE_ACK_NUM] if expected_ip else [test_xid] - send_and_verify( - duthost=duthost, - ptfhost=ptfhost, - ptfadapter=ptfadapter, - senario_context=senario_context, - test_pkt=request_pkt, - pkts_validator=pkts_validator, - pkts_validator_args=pkts_validator_args - ) - - -@pytest.mark.parametrize('senario_context', [ - { - 'dut_port_to_capture_pkt': 'Ethernet5', - 'ptf_port_index': 5, - "test_xid": 16 - } -]) -def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, senario_context): + test_xid = 1 + vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + expected_assigned_ip = random.choice(vlan_hosts) + dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) + config_commands = [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + 'config dhcp_server ipv4 enable %s' % vlan_name, + 'config dhcp_server ipv4 range add test_single_0_ip %s' % expected_assigned_ip, + 'config dhcp_server ipv4 bind %s %s --range test_single_0_ip' % (vlan_name, dut_port) + ] + with dhcp_server_config(duthost, config_commands): + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port, + ptf_port_index=ptf_port_index, + ptf_mac_port_index=ptf_port_index, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip, + exp_server_ip=gate_way, + net_mask=net_mask + ) + + +def test_dhcp_server_port_based_assignment_single_ip_s2( + duthost, + ptfhost, + ptfadapter, + parse_vlan_setting_from_running_config +): + """ + Verify configured interface with client mac in FDB table can successfully get IP + """ + test_xid = 2 + vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + expected_assigned_ip = random.choice(vlan_hosts) + dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) + config_commands = [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + 'config dhcp_server ipv4 enable %s' % vlan_name, + 'config dhcp_server ipv4 range add test_single_0_ip %s' % expected_assigned_ip, + 'config dhcp_server ipv4 bind %s %s --range test_single_0_ip' % (vlan_name, dut_port) + ] + ptf_port_index = int(dut_port.replace('Ethernet', '')) + with dhcp_server_config(duthost, config_commands): + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port, + ptf_port_index=ptf_port_index, + ptf_mac_port_index=ptf_port_index, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip, + exp_server_ip=gate_way, + net_mask=net_mask, + refresh_fdb_ptf_port='eth'+str(ptf_port_index) + ) + + +def test_dhcp_server_port_based_assignment_single_ip_s3( + duthost, + ptfhost, + ptfadapter, + parse_vlan_setting_from_running_config +): + """ + Verify configured interface with client mac in FDB table + but mac was learnt from another interface successfully get IP. + """ + test_xid = 3 + vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + expected_assigned_ip = random.choice(vlan_hosts) + dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) + config_commands = [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + 'config dhcp_server ipv4 enable %s' % vlan_name, + 'config dhcp_server ipv4 range add test_single_0_ip %s' % expected_assigned_ip, + 'config dhcp_server ipv4 bind %s %s --range test_single_0_ip' % (vlan_name, dut_port) + ] + _, ptf_mac_port_index = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != dut_port]) + with dhcp_server_config(duthost, config_commands): + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port, + ptf_port_index=ptf_port_index, + ptf_mac_port_index=ptf_mac_port_index, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip, + exp_server_ip=gate_way, + net_mask=net_mask, + refresh_fdb_ptf_port='eth'+str(ptf_mac_port_index) + ) + + +def test_dhcp_server_port_based_assignment_single_ip_s4( + duthost, + ptfhost, + ptfadapter, + parse_vlan_setting_from_running_config +): + """ + Verify no-configured interface cannot get IP + """ + test_xid = 4 + vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + expected_assigned_ip = random.choice(vlan_hosts) + _, ptf_port_index = random.choice(vlan_members_with_ptf_idx) + config_commands = [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + 'config dhcp_server ipv4 enable %s' % vlan_name, + 'config dhcp_server ipv4 range add test_single_0_ip %s' % expected_assigned_ip + ] + with dhcp_server_config(duthost, config_commands): + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt='any', + ptf_port_index=ptf_port_index, + ptf_mac_port_index=ptf_port_index, + test_xid=test_xid, + expected_assigned_ip=None, + exp_server_ip=gate_way, + net_mask=net_mask, + refresh_fdb_ptf_port='eth'+str(ptf_port_index) + ) + + +def test_dhcp_server_port_based_assignment_range_ip( + duthost, + ptfhost, + ptfadapter, + parse_vlan_setting_from_running_config +): + """ + Test single ip assignment with different scenarios, each scenario has a description in scenario_context. + """ + test_xid = 5 + vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + expected_assigned_ip = random.choice(vlan_hosts[:-1]) + last_ip_in_range = random.choice(vlan_hosts[vlan_hosts.index(expected_assigned_ip) + 1:]) + dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) + config_commands = [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + 'config dhcp_server ipv4 enable %s' % vlan_name, + 'config dhcp_server ipv4 range add test_single_0_ip %s %s' % (expected_assigned_ip, last_ip_in_range), + 'config dhcp_server ipv4 bind %s %s --range test_single_0_ip' % (vlan_name, dut_port), + ] + with dhcp_server_config(duthost, config_commands): + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port, + ptf_port_index=ptf_port_index, + ptf_mac_port_index=ptf_port_index, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip, + exp_server_ip=gate_way, + net_mask=net_mask, + refresh_fdb_ptf_port='eth'+str(ptf_port_index) + ) + + +def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, parse_vlan_setting_from_running_config): """ Test dhcp server packets if carry the customized options as expected """ - test_xid = senario_context['test_xid'] - ptf_mac_port_index = senario_context['ptf_port_index'] - client_mac = ptfadapter.dataplane.get_mac(0, ptf_mac_port_index).decode('utf-8') - pkts_validator = validate_dhcp_server_pkts_custom_option - pkts_validator_args = [test_xid] - pkts_validator_kwargs = {"147": DHCP_DEFAULT_CUSTOM_OPTION_VALUE.encode('ascii')} - discover_pkt = create_dhcp_client_packet( - src_mac=client_mac, - message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, - client_options=[], - xid=test_xid - ) - send_and_verify( - duthost=duthost, - ptfhost=ptfhost, - ptfadapter=ptfadapter, - senario_context=senario_context, - test_pkt=discover_pkt, - pkts_validator=pkts_validator, - pkts_validator_args=pkts_validator_args, - pkts_validator_kwargs=pkts_validator_kwargs - ) + test_xid = 6 + vlan_name, gate_way, net_mask, _, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) + client_mac = ptfadapter.dataplane.get_mac(0, ptf_port_index).decode('utf-8') + config_commands = [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + 'config dhcp_server ipv4 enable %s' % vlan_name, + 'config dhcp_server ipv4 option add ' + + 'sonic_test_option 147 string %s' % DHCP_DEFAULT_CUSTOM_OPTION_VALUE, + 'config dhcp_server ipv4 option bind %s sonic_test_option' % vlan_name + ] + with dhcp_server_config(duthost, config_commands): + pkts_validator = validate_dhcp_server_pkts_custom_option + pkts_validator_args = [test_xid] + pkts_validator_kwargs = {"147": DHCP_DEFAULT_CUSTOM_OPTION_VALUE.encode('ascii')} + discover_pkt = create_dhcp_client_packet( + src_mac=client_mac, + message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, + client_options=[], + xid=test_xid + ) + send_and_verify( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + test_pkt=discover_pkt, + dut_port_to_capture_pkt=dut_port, + ptf_port_index=ptf_port_index, + pkts_validator=pkts_validator, + pkts_validator_args=pkts_validator_args, + pkts_validator_kwargs=pkts_validator_kwargs, + refresh_fdb_ptf_port='eth'+str(ptf_port_index) + ) + discover_pkt = create_dhcp_client_packet( + src_mac=client_mac, + message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, + client_options=[], + xid=test_xid + ) + send_and_verify( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + test_pkt=discover_pkt, + dut_port_to_capture_pkt=dut_port, + ptf_port_index=ptf_port_index, + pkts_validator=pkts_validator, + pkts_validator_args=pkts_validator_args, + pkts_validator_kwargs=pkts_validator_kwargs, + refresh_fdb_ptf_port='eth'+str(ptf_port_index) + ) From 1209f65bbe4b255ead29f60bd6f9be0ee0728d28 Mon Sep 17 00:00:00 2001 From: wenda Date: Tue, 16 Apr 2024 05:25:24 +0000 Subject: [PATCH 3/8] update option test --- tests/dhcp_server/test_dhcp_server.py | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/tests/dhcp_server/test_dhcp_server.py b/tests/dhcp_server/test_dhcp_server.py index d563b333c63..e45a711f8b8 100644 --- a/tests/dhcp_server/test_dhcp_server.py +++ b/tests/dhcp_server/test_dhcp_server.py @@ -249,18 +249,7 @@ def verify_discover_and_request_then_release( xid=test_xid, ciaddr=expected_assigned_ip ) - pkts_validator_args = [test_xid, expected_assigned_ip, DHCP_MESSAGE_TYPE_ACK_NUM, net_mask, exp_server_ip] - send_and_verify( - duthost=duthost, - ptfhost=ptfhost, - ptfadapter=ptfadapter, - dut_port_to_capture_pkt=dut_port_to_capture_pkt, - ptf_port_index=ptf_port_index, - test_pkt=release_pkt, - pkts_validator=pkts_validator, - pkts_validator_args=pkts_validator_args, - refresh_fdb_ptf_port=refresh_fdb_ptf_port - ) + testutils.send_packet(ptfadapter, ptf_port_index, release_pkt) def test_dhcp_server_port_based_assignment_single_ip_s1( @@ -450,13 +439,16 @@ def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, Test dhcp server packets if carry the customized options as expected """ test_xid = 6 - vlan_name, gate_way, net_mask, _, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + expected_assigned_ip = random.choice(vlan_hosts) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) client_mac = ptfadapter.dataplane.get_mac(0, ptf_port_index).decode('utf-8') config_commands = [ 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, + 'config dhcp_server ipv4 range add test_option_0_ip %s' % expected_assigned_ip, + 'config dhcp_server ipv4 bind %s %s --range test_option_0_ip' % (vlan_name, dut_port), 'config dhcp_server ipv4 option add ' + 'sonic_test_option 147 string %s' % DHCP_DEFAULT_CUSTOM_OPTION_VALUE, 'config dhcp_server ipv4 option bind %s sonic_test_option' % vlan_name @@ -483,19 +475,19 @@ def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, pkts_validator_kwargs=pkts_validator_kwargs, refresh_fdb_ptf_port='eth'+str(ptf_port_index) ) - discover_pkt = create_dhcp_client_packet( + request_pkt = create_dhcp_client_packet( src_mac=client_mac, - message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, - client_options=[], + message_type=DHCP_MESSAGE_TYPE_REQUEST_NUM, + client_options=[("requested_addr", expected_assigned_ip), ("server_id", gate_way)], xid=test_xid ) send_and_verify( duthost=duthost, ptfhost=ptfhost, ptfadapter=ptfadapter, - test_pkt=discover_pkt, dut_port_to_capture_pkt=dut_port, ptf_port_index=ptf_port_index, + test_pkt=request_pkt, pkts_validator=pkts_validator, pkts_validator_args=pkts_validator_args, pkts_validator_kwargs=pkts_validator_kwargs, From edd75d298c4ff48dd5b608b4345563dbd3657172 Mon Sep 17 00:00:00 2001 From: wenda Date: Tue, 16 Apr 2024 08:10:22 +0000 Subject: [PATCH 4/8] add mac moving and swaping test cases --- tests/dhcp_server/test_dhcp_server.py | 148 ++++++++++++++++++++++++-- 1 file changed, 137 insertions(+), 11 deletions(-) diff --git a/tests/dhcp_server/test_dhcp_server.py b/tests/dhcp_server/test_dhcp_server.py index e45a711f8b8..d7e8c5692c6 100644 --- a/tests/dhcp_server/test_dhcp_server.py +++ b/tests/dhcp_server/test_dhcp_server.py @@ -269,8 +269,8 @@ def test_dhcp_server_port_based_assignment_single_ip_s1( 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_0_ip %s' % expected_assigned_ip, - 'config dhcp_server ipv4 bind %s %s --range test_single_0_ip' % (vlan_name, dut_port) + 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip, + 'config dhcp_server ipv4 bind %s %s --range test_single_ip' % (vlan_name, dut_port) ] with dhcp_server_config(duthost, config_commands): verify_discover_and_request_then_release( @@ -304,8 +304,8 @@ def test_dhcp_server_port_based_assignment_single_ip_s2( 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_0_ip %s' % expected_assigned_ip, - 'config dhcp_server ipv4 bind %s %s --range test_single_0_ip' % (vlan_name, dut_port) + 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip, + 'config dhcp_server ipv4 bind %s %s --range test_single_ip' % (vlan_name, dut_port) ] ptf_port_index = int(dut_port.replace('Ethernet', '')) with dhcp_server_config(duthost, config_commands): @@ -342,8 +342,8 @@ def test_dhcp_server_port_based_assignment_single_ip_s3( 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_0_ip %s' % expected_assigned_ip, - 'config dhcp_server ipv4 bind %s %s --range test_single_0_ip' % (vlan_name, dut_port) + 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip, + 'config dhcp_server ipv4 bind %s %s --range test_single_ip' % (vlan_name, dut_port) ] _, ptf_mac_port_index = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != dut_port]) with dhcp_server_config(duthost, config_commands): @@ -379,7 +379,7 @@ def test_dhcp_server_port_based_assignment_single_ip_s4( 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_0_ip %s' % expected_assigned_ip + 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip ] with dhcp_server_config(duthost, config_commands): verify_discover_and_request_then_release( @@ -415,8 +415,8 @@ def test_dhcp_server_port_based_assignment_range_ip( 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_0_ip %s %s' % (expected_assigned_ip, last_ip_in_range), - 'config dhcp_server ipv4 bind %s %s --range test_single_0_ip' % (vlan_name, dut_port), + 'config dhcp_server ipv4 range add test_range_ip %s %s' % (expected_assigned_ip, last_ip_in_range), + 'config dhcp_server ipv4 bind %s %s --range test_range_ip' % (vlan_name, dut_port), ] with dhcp_server_config(duthost, config_commands): verify_discover_and_request_then_release( @@ -447,8 +447,8 @@ def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_option_0_ip %s' % expected_assigned_ip, - 'config dhcp_server ipv4 bind %s %s --range test_option_0_ip' % (vlan_name, dut_port), + 'config dhcp_server ipv4 range add test_option_ip %s' % expected_assigned_ip, + 'config dhcp_server ipv4 bind %s %s --range test_option_ip' % (vlan_name, dut_port), 'config dhcp_server ipv4 option add ' + 'sonic_test_option 147 string %s' % DHCP_DEFAULT_CUSTOM_OPTION_VALUE, 'config dhcp_server ipv4 option bind %s sonic_test_option' % vlan_name @@ -493,3 +493,129 @@ def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, pkts_validator_kwargs=pkts_validator_kwargs, refresh_fdb_ptf_port='eth'+str(ptf_port_index) ) + + +def test_dhcp_server_port_based_assigenment_single_ip_mac_move( + duthost, + ptfhost, + ptfadapter, + parse_vlan_setting_from_running_config +): + """ + To test port based single ip assignment with client move to an interface has free IP to assign. + """ + test_xid = 7 + vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + expected_assigned_ip_0 = random.choice(vlan_hosts) + dut_port_0, ptf_port_index_0 = random.choice(vlan_members_with_ptf_idx) + expected_assigned_ip_1 = random.choice([v for v in vlan_hosts if v != expected_assigned_ip_0]) + dut_port_1, ptf_port_index_1 = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != dut_port_0]) + config_commands = [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + 'config dhcp_server ipv4 enable %s' % vlan_name, + 'config dhcp_server ipv4 range add test_single_ip_0 %s' % expected_assigned_ip_0, + 'config dhcp_server ipv4 bind %s %s --range test_single_ip_0' % (vlan_name, dut_port_0), + 'config dhcp_server ipv4 range add test_single_ip_1 %s' % expected_assigned_ip_1, + 'config dhcp_server ipv4 bind %s %s --range test_single_ip_1' % (vlan_name, dut_port_1) + ] + with dhcp_server_config(duthost, config_commands): + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port_0, + ptf_port_index=ptf_port_index_0, + ptf_mac_port_index=ptf_port_index_0, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip_0, + exp_server_ip=gate_way, + net_mask=net_mask + ) + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port_1, + ptf_port_index=ptf_port_index_1, + ptf_mac_port_index=ptf_port_index_0, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip_1, + exp_server_ip=gate_way, + net_mask=net_mask + ) + + +def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( + duthost, + ptfhost, + ptfadapter, + parse_vlan_setting_from_running_config +): + """ + To test port based single ip assignment with two clients swap their interfaces. + """ + test_xid = 8 + vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + expected_assigned_ip_0 = random.choice(vlan_hosts) + dut_port_0, ptf_port_index_0 = random.choice(vlan_members_with_ptf_idx) + expected_assigned_ip_1 = random.choice([v for v in vlan_hosts if v != expected_assigned_ip_0]) + dut_port_1, ptf_port_index_1 = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != dut_port_0]) + config_commands = [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + 'config dhcp_server ipv4 enable %s' % vlan_name, + 'config dhcp_server ipv4 range add test_single_ip_0 %s' % expected_assigned_ip_0, + 'config dhcp_server ipv4 bind %s %s --range test_single_ip_0' % (vlan_name, dut_port_0), + 'config dhcp_server ipv4 range add test_single_ip_1 %s' % expected_assigned_ip_1, + 'config dhcp_server ipv4 bind %s %s --range test_single_ip_1' % (vlan_name, dut_port_1) + ] + with dhcp_server_config(duthost, config_commands): + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port_0, + ptf_port_index=ptf_port_index_0, + ptf_mac_port_index=ptf_port_index_0, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip_0, + exp_server_ip=gate_way, + net_mask=net_mask + ) + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port_1, + ptf_port_index=ptf_port_index_1, + ptf_mac_port_index=ptf_port_index_1, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip_1, + exp_server_ip=gate_way, + net_mask=net_mask + ) + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port_1, + ptf_port_index=ptf_port_index_1, + ptf_mac_port_index=ptf_port_index_0, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip_1, + exp_server_ip=gate_way, + net_mask=net_mask + ) + verify_discover_and_request_then_release( + duthost=duthost, + ptfhost=ptfhost, + ptfadapter=ptfadapter, + dut_port_to_capture_pkt=dut_port_0, + ptf_port_index=ptf_port_index_0, + ptf_mac_port_index=ptf_port_index_1, + test_xid=test_xid, + expected_assigned_ip=expected_assigned_ip_0, + exp_server_ip=gate_way, + net_mask=net_mask + ) From 452dc8535c1f83e9163bb88f35afc8a148a992ee Mon Sep 17 00:00:00 2001 From: wenda Date: Tue, 16 Apr 2024 10:58:24 +0000 Subject: [PATCH 5/8] verify lease via cli --- tests/dhcp_server/conftest.py | 9 +-- tests/dhcp_server/test_dhcp_server.py | 95 ++++++++++++++++----------- 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/tests/dhcp_server/conftest.py b/tests/dhcp_server/conftest.py index df2171524db..19932e675a6 100644 --- a/tests/dhcp_server/conftest.py +++ b/tests/dhcp_server/conftest.py @@ -1,5 +1,7 @@ import pytest from tests.common.utilities import wait_until +from tests.common.helpers.assertions import pytest_assert as py_assert +from tests.common.helpers.assertions import pytest_require as py_require DHCP_SERVER_CONTAINER_NAME = "dhcp_server" DHCP_SERVER_FEATRUE_NAME = "dhcp_server" @@ -8,15 +10,14 @@ @pytest.fixture(scope="module", autouse=True) def dhcp_server_setup_teardown(duthost): features_state, _ = duthost.get_feature_status() - if DHCP_SERVER_FEATRUE_NAME not in features_state: - pytest.fail('There is no dhcp server feature in the DUT') + py_require(DHCP_SERVER_FEATRUE_NAME in features_state, "Skip on vs testbed without dhcp server feature") restore_state_flag = True if "enabled" not in features_state.get(DHCP_SERVER_FEATRUE_NAME, ""): duthost.shell("config feature state dhcp_server enabled") else: restore_state_flag = False - if not wait_until(10, 1, 1, duthost.is_container_running, DHCP_SERVER_CONTAINER_NAME): - pytest.fail('feature dhcp_server is enabled but container is not running') + py_assert(wait_until(10, 1, 1, duthost.is_container_running, DHCP_SERVER_CONTAINER_NAME), + 'feature dhcp_server is enabled but container is not running') yield diff --git a/tests/dhcp_server/test_dhcp_server.py b/tests/dhcp_server/test_dhcp_server.py index d7e8c5692c6..446722d7122 100644 --- a/tests/dhcp_server/test_dhcp_server.py +++ b/tests/dhcp_server/test_dhcp_server.py @@ -1,5 +1,6 @@ import binascii import contextlib +from datetime import datetime import logging import ipaddress import pytest @@ -45,6 +46,21 @@ def clean_dhcp_server_config(duthost): duthost.shell("sonic-db-cli CONFIG_DB DEL '{}'".format(key)) +def verify_lease_via_cli(duthost, mac, ip, lease_time): + lease_table_raw = duthost.shell('show dhcp_server ipv4 lease')['stdout'] + header_and_leases = [[r.strip() for r in line.strip('|').split('|')] + for line in lease_table_raw.split('\n') if line[0] == '|'] + logging.info("The lease table is %s" % header_and_leases) + matched_lease = [(line[4], line[5]) for line in header_and_leases if line[2] == mac and line[3] == ip] + pytest_assert(len(matched_lease) == 1, + "Got %d lease for mac=%s, ip=%s, while only expected one" % (len(matched_lease), mac, ip)) + time_str_format = '%Y-%m-%d %H:%M:%S' + mac_lease_start_time = datetime.strptime(matched_lease[0][0], time_str_format) + mac_lease_end_time = datetime.strptime(matched_lease[0][1], time_str_format) + time_gap = int((mac_lease_end_time - mac_lease_start_time).total_seconds()) + pytest_assert(time_gap == lease_time, "Expected lease_time=%d while got %d" % (lease_time, time_gap)) + + @pytest.fixture(scope="module") def parse_vlan_setting_from_running_config(duthost, tbinfo): vlan_brief = duthost.get_vlan_brief() @@ -59,14 +75,14 @@ def parse_vlan_setting_from_running_config(duthost, tbinfo): for member in vlan_members if member in dut_intf_to_ptf_index] pytest_assert(len(vlan_members) >= MINIMUM_INTERFACE_MEMBERS_COUNT, 'Vlan size is too small for testing') vlan_net = ipaddress.ip_network(address=first_vlan_prefix, strict=False) - vlan_gate_way = first_vlan_prefix.split('/')[0] + vlan_gateway = first_vlan_prefix.split('/')[0] vlan_hosts = [str(host) for host in vlan_net.hosts()] # to avoid configurate an range contains gateway ip, simply ignore all ip before gateway and gateway itself - vlan_hosts_after_gateway = vlan_hosts[vlan_hosts.index(vlan_gate_way) + 1:] + vlan_hosts_after_gateway = vlan_hosts[vlan_hosts.index(vlan_gateway) + 1:] pytest_assert(len(vlan_hosts_after_gateway) >= MINIMUM_HOSTS_COUNT, 'Vlan size is too small for testing') vlan_setting = { 'vlan_name': first_vlan_name, - 'vlan_gate_way': vlan_gate_way, + 'vlan_gateway': vlan_gateway, 'vlan_subnet_mask': str(vlan_net.netmask), 'vlan_hosts': vlan_hosts_after_gateway, 'vlan_member_with_ptf_idx': vlan_member_with_ptf_idx, @@ -74,7 +90,7 @@ def parse_vlan_setting_from_running_config(duthost, tbinfo): logging.info("The vlan_setting before test is %s" % vlan_setting) return vlan_setting['vlan_name'], \ - vlan_setting['vlan_gate_way'], \ + vlan_setting['vlan_gateway'], \ vlan_setting['vlan_subnet_mask'], \ vlan_setting['vlan_hosts'], \ vlan_setting['vlan_member_with_ptf_idx'] @@ -225,7 +241,10 @@ def verify_discover_and_request_then_release( request_pkt = create_dhcp_client_packet( src_mac=client_mac, message_type=DHCP_MESSAGE_TYPE_REQUEST_NUM, - client_options=[("requested_addr", expected_assigned_ip), ("server_id", exp_server_ip)], + client_options=[ + ("requested_addr", expected_assigned_ip), + ("server_id", exp_server_ip) + ], xid=test_xid ) pkts_validator_args = [test_xid, expected_assigned_ip, DHCP_MESSAGE_TYPE_ACK_NUM, net_mask, exp_server_ip] \ @@ -242,6 +261,7 @@ def verify_discover_and_request_then_release( refresh_fdb_ptf_port=refresh_fdb_ptf_port ) if expected_assigned_ip: + verify_lease_via_cli(duthost, client_mac, expected_assigned_ip, DHCP_DEFAULT_LEASE_TIME) release_pkt = create_dhcp_client_packet( src_mac=client_mac, message_type=DHCP_MESSAGE_TYPE_RELEASE_NUM, @@ -252,7 +272,7 @@ def verify_discover_and_request_then_release( testutils.send_packet(ptfadapter, ptf_port_index, release_pkt) -def test_dhcp_server_port_based_assignment_single_ip_s1( +def test_dhcp_server_port_based_assignment_single_ip_tc1( duthost, ptfhost, ptfadapter, @@ -262,12 +282,12 @@ def test_dhcp_server_port_based_assignment_single_ip_s1( Verify configured interface with client mac not in FDB table can successfully get IP """ test_xid = 1 - vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip = random.choice(vlan_hosts) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) config_commands = [ 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip, 'config dhcp_server ipv4 bind %s %s --range test_single_ip' % (vlan_name, dut_port) @@ -282,12 +302,12 @@ def test_dhcp_server_port_based_assignment_single_ip_s1( ptf_mac_port_index=ptf_port_index, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask ) -def test_dhcp_server_port_based_assignment_single_ip_s2( +def test_dhcp_server_port_based_assignment_single_ip_tc2( duthost, ptfhost, ptfadapter, @@ -297,17 +317,16 @@ def test_dhcp_server_port_based_assignment_single_ip_s2( Verify configured interface with client mac in FDB table can successfully get IP """ test_xid = 2 - vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip = random.choice(vlan_hosts) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) config_commands = [ 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip, 'config dhcp_server ipv4 bind %s %s --range test_single_ip' % (vlan_name, dut_port) ] - ptf_port_index = int(dut_port.replace('Ethernet', '')) with dhcp_server_config(duthost, config_commands): verify_discover_and_request_then_release( duthost=duthost, @@ -318,13 +337,13 @@ def test_dhcp_server_port_based_assignment_single_ip_s2( ptf_mac_port_index=ptf_port_index, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask, refresh_fdb_ptf_port='eth'+str(ptf_port_index) ) -def test_dhcp_server_port_based_assignment_single_ip_s3( +def test_dhcp_server_port_based_assignment_single_ip_tc3( duthost, ptfhost, ptfadapter, @@ -335,12 +354,12 @@ def test_dhcp_server_port_based_assignment_single_ip_s3( but mac was learnt from another interface successfully get IP. """ test_xid = 3 - vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip = random.choice(vlan_hosts) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) config_commands = [ 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip, 'config dhcp_server ipv4 bind %s %s --range test_single_ip' % (vlan_name, dut_port) @@ -356,13 +375,13 @@ def test_dhcp_server_port_based_assignment_single_ip_s3( ptf_mac_port_index=ptf_mac_port_index, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask, refresh_fdb_ptf_port='eth'+str(ptf_mac_port_index) ) -def test_dhcp_server_port_based_assignment_single_ip_s4( +def test_dhcp_server_port_based_assignment_single_ip_tc4( duthost, ptfhost, ptfadapter, @@ -372,12 +391,12 @@ def test_dhcp_server_port_based_assignment_single_ip_s4( Verify no-configured interface cannot get IP """ test_xid = 4 - vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip = random.choice(vlan_hosts) _, ptf_port_index = random.choice(vlan_members_with_ptf_idx) config_commands = [ 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip ] @@ -391,7 +410,7 @@ def test_dhcp_server_port_based_assignment_single_ip_s4( ptf_mac_port_index=ptf_port_index, test_xid=test_xid, expected_assigned_ip=None, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask, refresh_fdb_ptf_port='eth'+str(ptf_port_index) ) @@ -407,13 +426,13 @@ def test_dhcp_server_port_based_assignment_range_ip( Test single ip assignment with different scenarios, each scenario has a description in scenario_context. """ test_xid = 5 - vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip = random.choice(vlan_hosts[:-1]) last_ip_in_range = random.choice(vlan_hosts[vlan_hosts.index(expected_assigned_ip) + 1:]) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) config_commands = [ 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, 'config dhcp_server ipv4 range add test_range_ip %s %s' % (expected_assigned_ip, last_ip_in_range), 'config dhcp_server ipv4 bind %s %s --range test_range_ip' % (vlan_name, dut_port), @@ -428,7 +447,7 @@ def test_dhcp_server_port_based_assignment_range_ip( ptf_mac_port_index=ptf_port_index, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask, refresh_fdb_ptf_port='eth'+str(ptf_port_index) ) @@ -439,13 +458,13 @@ def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, Test dhcp server packets if carry the customized options as expected """ test_xid = 6 - vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip = random.choice(vlan_hosts) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) client_mac = ptfadapter.dataplane.get_mac(0, ptf_port_index).decode('utf-8') config_commands = [ 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, 'config dhcp_server ipv4 range add test_option_ip %s' % expected_assigned_ip, 'config dhcp_server ipv4 bind %s %s --range test_option_ip' % (vlan_name, dut_port), @@ -478,7 +497,7 @@ def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, request_pkt = create_dhcp_client_packet( src_mac=client_mac, message_type=DHCP_MESSAGE_TYPE_REQUEST_NUM, - client_options=[("requested_addr", expected_assigned_ip), ("server_id", gate_way)], + client_options=[("requested_addr", expected_assigned_ip), ("server_id", gateway)], xid=test_xid ) send_and_verify( @@ -505,14 +524,14 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_move( To test port based single ip assignment with client move to an interface has free IP to assign. """ test_xid = 7 - vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip_0 = random.choice(vlan_hosts) dut_port_0, ptf_port_index_0 = random.choice(vlan_members_with_ptf_idx) expected_assigned_ip_1 = random.choice([v for v in vlan_hosts if v != expected_assigned_ip_0]) dut_port_1, ptf_port_index_1 = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != dut_port_0]) config_commands = [ 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, 'config dhcp_server ipv4 range add test_single_ip_0 %s' % expected_assigned_ip_0, 'config dhcp_server ipv4 bind %s %s --range test_single_ip_0' % (vlan_name, dut_port_0), @@ -529,7 +548,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_move( ptf_mac_port_index=ptf_port_index_0, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip_0, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask ) verify_discover_and_request_then_release( @@ -541,7 +560,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_move( ptf_mac_port_index=ptf_port_index_0, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip_1, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask ) @@ -556,14 +575,14 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( To test port based single ip assignment with two clients swap their interfaces. """ test_xid = 8 - vlan_name, gate_way, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config + vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip_0 = random.choice(vlan_hosts) dut_port_0, ptf_port_index_0 = random.choice(vlan_members_with_ptf_idx) expected_assigned_ip_1 = random.choice([v for v in vlan_hosts if v != expected_assigned_ip_0]) dut_port_1, ptf_port_index_1 = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != dut_port_0]) config_commands = [ 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gate_way, net_mask, vlan_name), + '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), 'config dhcp_server ipv4 enable %s' % vlan_name, 'config dhcp_server ipv4 range add test_single_ip_0 %s' % expected_assigned_ip_0, 'config dhcp_server ipv4 bind %s %s --range test_single_ip_0' % (vlan_name, dut_port_0), @@ -580,7 +599,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( ptf_mac_port_index=ptf_port_index_0, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip_0, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask ) verify_discover_and_request_then_release( @@ -592,7 +611,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( ptf_mac_port_index=ptf_port_index_1, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip_1, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask ) verify_discover_and_request_then_release( @@ -604,7 +623,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( ptf_mac_port_index=ptf_port_index_0, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip_1, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask ) verify_discover_and_request_then_release( @@ -616,6 +635,6 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( ptf_mac_port_index=ptf_port_index_1, test_xid=test_xid, expected_assigned_ip=expected_assigned_ip_0, - exp_server_ip=gate_way, + exp_server_ip=gateway, net_mask=net_mask ) From 9a2434f664aca5eba9b007460b3f0e54a194583b Mon Sep 17 00:00:00 2001 From: wenda Date: Fri, 26 Apr 2024 09:02:54 +0000 Subject: [PATCH 6/8] extend gcu for configuration setting --- tests/dhcp_server/conftest.py | 29 +- tests/dhcp_server/test_dhcp_server.py | 404 ++++++++++++++++---------- 2 files changed, 274 insertions(+), 159 deletions(-) diff --git a/tests/dhcp_server/conftest.py b/tests/dhcp_server/conftest.py index 19932e675a6..564069ecd06 100644 --- a/tests/dhcp_server/conftest.py +++ b/tests/dhcp_server/conftest.py @@ -3,6 +3,7 @@ from tests.common.helpers.assertions import pytest_assert as py_assert from tests.common.helpers.assertions import pytest_require as py_require +DHCP_RELAY_CONTAINER_NAME = "dhcp_relay" DHCP_SERVER_CONTAINER_NAME = "dhcp_server" DHCP_SERVER_FEATRUE_NAME = "dhcp_server" @@ -11,16 +12,34 @@ def dhcp_server_setup_teardown(duthost): features_state, _ = duthost.get_feature_status() py_require(DHCP_SERVER_FEATRUE_NAME in features_state, "Skip on vs testbed without dhcp server feature") - restore_state_flag = True + restore_state_flag = False if "enabled" not in features_state.get(DHCP_SERVER_FEATRUE_NAME, ""): + restore_state_flag = True duthost.shell("config feature state dhcp_server enabled") - else: - restore_state_flag = False - py_assert(wait_until(10, 1, 1, duthost.is_container_running, DHCP_SERVER_CONTAINER_NAME), - 'feature dhcp_server is enabled but container is not running') + duthost.shell("sudo systemctl restart dhcp_relay.service") + + def is_supervisor_subprocess_running(duthost, container_name, app_name): + return "RUNNING" in duthost.shell(f"docker exec {container_name} supervisorctl status {app_name}")["stdout"] + py_assert( + wait_until(20, 1, 1, + is_supervisor_subprocess_running, + duthost, + DHCP_SERVER_CONTAINER_NAME, + "dhcp-server-ipv4:kea-dhcp4"), + 'feature dhcp_server is enabled but container is not running' + ) + py_assert( + wait_until(30, 1, 1, + is_supervisor_subprocess_running, + duthost, + DHCP_RELAY_CONTAINER_NAME, + "dhcp-relay:dhcprelayd"), + 'dhcprelayd in container dhcp_relay is not running' + ) yield if restore_state_flag: duthost.shell("config feature state dhcp_server disabled", module_ignore_errors=True) + duthost.shell("sudo systemctl restart dhcp_relay.service") duthost.shell("docker rm dhcp_server", module_ignore_errors=True) diff --git a/tests/dhcp_server/test_dhcp_server.py b/tests/dhcp_server/test_dhcp_server.py index 446722d7122..694a0ce218c 100644 --- a/tests/dhcp_server/test_dhcp_server.py +++ b/tests/dhcp_server/test_dhcp_server.py @@ -8,11 +8,12 @@ import ptf.testutils as testutils import random from tests.common.utilities import capture_and_check_packet_on_dut -from tests.common.helpers.assertions import pytest_assert +from tests.common.helpers.assertions import pytest_assert, pytest_require +from tests.generic_config_updater.gu_utils import apply_patch, expect_op_success, generate_tmpfile, delete_tmpfile pytestmark = [ - pytest.mark.topology('m0', 'mx'), + pytest.mark.topology('mx'), ] MINIMUM_HOSTS_COUNT = 2 @@ -31,6 +32,14 @@ DHCP_MESSAGE_TYPE_NAK_NUM = 6 DHCP_MESSAGE_TYPE_RELEASE_NUM = 7 +STATE_DB_KEY_LEASE_START = 'lease_start' +STATE_DB_KEY_LEASE_END = 'lease_end' +STATE_DB_KEY_IP = 'ip' + +DHCP_SERVER_CONFIG_TOOL_GCU = 'gcu' +DHCP_SERVER_CONFIG_TOOL_CLI = 'cli' +DHCP_SERVER_CONFIG_PREFIX_SERVER = 'DHCP_SERVER_IPV4' + def clean_fdb_table(duthost): duthost.shell("sonic-clear fdb all") @@ -46,19 +55,18 @@ def clean_dhcp_server_config(duthost): duthost.shell("sonic-db-cli CONFIG_DB DEL '{}'".format(key)) -def verify_lease_via_cli(duthost, mac, ip, lease_time): - lease_table_raw = duthost.shell('show dhcp_server ipv4 lease')['stdout'] - header_and_leases = [[r.strip() for r in line.strip('|').split('|')] - for line in lease_table_raw.split('\n') if line[0] == '|'] - logging.info("The lease table is %s" % header_and_leases) - matched_lease = [(line[4], line[5]) for line in header_and_leases if line[2] == mac and line[3] == ip] - pytest_assert(len(matched_lease) == 1, - "Got %d lease for mac=%s, ip=%s, while only expected one" % (len(matched_lease), mac, ip)) - time_str_format = '%Y-%m-%d %H:%M:%S' - mac_lease_start_time = datetime.strptime(matched_lease[0][0], time_str_format) - mac_lease_end_time = datetime.strptime(matched_lease[0][1], time_str_format) - time_gap = int((mac_lease_end_time - mac_lease_start_time).total_seconds()) - pytest_assert(time_gap == lease_time, "Expected lease_time=%d while got %d" % (lease_time, time_gap)) +def verify_lease(duthost, dhcp_interface, client_mac, exp_ip, exp_lease_time): + lease_start = duthost.shell("sonic-db-cli STATE_DB HGET 'DHCP_SERVER_IPV4_LEASE|{}|{}' '{}'" + .format(dhcp_interface, client_mac, STATE_DB_KEY_LEASE_START))['stdout'] + lease_end = duthost.shell("sonic-db-cli STATE_DB HGET 'DHCP_SERVER_IPV4_LEASE|{}|{}' '{}'" + .format(dhcp_interface, client_mac, STATE_DB_KEY_LEASE_END))['stdout'] + lease_ip = duthost.shell("sonic-db-cli STATE_DB HGET 'DHCP_SERVER_IPV4_LEASE|{}|{}' '{}'" + .format(dhcp_interface, client_mac, STATE_DB_KEY_IP))['stdout'] + pytest_assert(lease_ip == exp_ip, "Expected ip=%s while got %s" % (exp_ip, lease_ip)) + lease_start_time = datetime.fromtimestamp(int(lease_start)) + lease_end_time = datetime.fromtimestamp(int(lease_end)) + lease_time = int((lease_end_time - lease_start_time).total_seconds()) + pytest_assert(lease_time == exp_lease_time, "Expected lease_time=%d while got %d" % (exp_lease_time, lease_time)) @pytest.fixture(scope="module") @@ -67,7 +75,10 @@ def parse_vlan_setting_from_running_config(duthost, tbinfo): first_vlan_name = list(vlan_brief.keys())[0] first_vlan_info = list(vlan_brief.values())[0] first_vlan_prefix = first_vlan_info['interface_ipv4'][0] - connected_ptf_ports_idx = tbinfo['topo']['properties']['topology']['host_interfaces'] + disabled_host_interfaces = tbinfo['topo']['properties']['topology'].get('disabled_host_interfaces', []) + connected_ptf_ports_idx = [interface for interface in + tbinfo['topo']['properties']['topology'].get('host_interfaces', []) + if interface not in disabled_host_interfaces] dut_intf_to_ptf_index = duthost.get_extended_minigraph_facts(tbinfo)['minigraph_ptf_indices'] connected_dut_intf_to_ptf_index = {k: v for k, v in dut_intf_to_ptf_index.items() if v in connected_ptf_ports_idx} vlan_members = first_vlan_info['members'] @@ -97,16 +108,130 @@ def parse_vlan_setting_from_running_config(duthost, tbinfo): @contextlib.contextmanager -def dhcp_server_config(duthost, config_commands): +def dhcp_server_config(duthost, config_tool, config_to_apply): clean_dhcp_server_config(duthost) - for cmd in config_commands: - duthost.shell(cmd) + logging.info("The dhcp_server_config: %s" % config_to_apply) + if config_tool == DHCP_SERVER_CONFIG_TOOL_GCU: + dhcp_server_config_gcu(duthost, config_to_apply) + elif config_tool == DHCP_SERVER_CONFIG_TOOL_CLI: + dhcp_server_config_cli(duthost, config_to_apply) yield clean_dhcp_server_config(duthost) +def dhcp_server_config_cli(duthost, config_commands): + clean_dhcp_server_config(duthost) + for cmd in config_commands: + duthost.shell(cmd) + + +def dhcp_server_config_gcu(duthost, config_to_apply): + tmpfile = generate_tmpfile(duthost) + try: + output = apply_patch(duthost, json_data=config_to_apply, dest_file=tmpfile) + expect_op_success(duthost, output) + finally: + delete_tmpfile(duthost, tmpfile) + + +def generate_common_config_patch(vlan_name, gateway, net_mask, dut_ports, ip_ranges): + pytest_require(len(dut_ports) == len(ip_ranges), "Invalid input, dut_ports and ip_ranges should have same length") + ret_patch = generate_dhcp_interface_config_patch(vlan_name, gateway, net_mask) + range_names = ["range_" + ip_range[0] for ip_range in ip_ranges] + ret_patch += generate_dhcp_range_config_patch(ip_ranges, range_names) + ret_patch += generate_dhcp_port_config_patch(vlan_name, dut_ports, range_names) + return ret_patch + + +def generate_dhcp_interface_config_patch(vlan_name, gateway, net_mask): + return [ + { + "op": "add", + "path": "/DHCP_SERVER_IPV4", + "value": { + "%s" % vlan_name: { + "gateway": "%s" % gateway, + "lease_time": "%s" % DHCP_DEFAULT_LEASE_TIME, + "mode": "PORT", + "netmask": "%s" % net_mask, + "state": "enabled" + } + } + } + ] + + +def generate_dhcp_range_config_patch(ip_ranges, range_names): + ret_range_config_patch = [ + { + "op": "add", + "path": "/DHCP_SERVER_IPV4_RANGE", + "value": {} + } + ] + for range_name, ip_range in zip(range_names, ip_ranges): + ret_range_config_patch[0]["value"][range_name] = { + "range": ip_range + } + + return ret_range_config_patch + + +def generate_dhcp_port_config_patch(vlan_name, dut_ports, range_names): + ret_port_config_patch = [ + { + "op": "add", + "path": "/DHCP_SERVER_IPV4_PORT", + "value": {} + } + ] + for range_name, dut_port in zip(range_names, dut_ports): + ret_port_config_patch[0]["value"]["%s|%s" % (vlan_name, dut_port)] = { + "ranges": [ + range_name + ] + } + + return ret_port_config_patch + + +def generate_common_config_cli_commands(vlan_name, gateway, net_mask, dut_ports, ip_ranges): + pytest_require(len(dut_ports) == len(ip_ranges), "Invalid input, dut_ports and ip_ranges should have same length") + ret_commands = generate_dhcp_interface_config_cli_commands(vlan_name, gateway, net_mask) + for i in range(len(dut_ports)): + range_name = "range_" + ip_ranges[i][0] + ret_commands += generate_dhcp_range_config_cli_commands(ip_ranges[i], range_name) + ret_commands += generate_dhcp_port_config_cli_commands(vlan_name, dut_ports[i], range_name) + return ret_commands + + +def generate_dhcp_interface_config_cli_commands(vlan_name, gateway, net_mask): + return [ + 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + + '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), + 'config dhcp_server ipv4 enable %s' % vlan_name + ] + + +def generate_dhcp_range_config_cli_commands(ip_range, range_name="test_single_ip"): + ret_command = "" + if len(ip_range) == 1: + ret_command += 'config dhcp_server ipv4 range add %s %s' % (range_name, ip_range[0]) + elif len(ip_range) == 2: + ret_command += 'config dhcp_server ipv4 range add %s %s %s' % (range_name, ip_range[0], ip_range[1]) + else: + pytest.fail("Invalid ip range:%s" % ip_range) + return [ret_command] + + +def generate_dhcp_port_config_cli_commands(vlan_name, dut_port, range_name="test_single_ip"): + return [ + 'config dhcp_server ipv4 bind %s %s --range %s' % (vlan_name, dut_port, range_name) + ] + + def match_expected_dhcp_options(pkt_dhcp_options, option_name, expected_value): for option in pkt_dhcp_options: if option[0] == option_name: @@ -210,6 +335,7 @@ def verify_discover_and_request_then_release( ptfadapter, dut_port_to_capture_pkt, test_xid, + dhcp_interface, ptf_port_index, ptf_mac_port_index, expected_assigned_ip, @@ -261,7 +387,7 @@ def verify_discover_and_request_then_release( refresh_fdb_ptf_port=refresh_fdb_ptf_port ) if expected_assigned_ip: - verify_lease_via_cli(duthost, client_mac, expected_assigned_ip, DHCP_DEFAULT_LEASE_TIME) + verify_lease(duthost, dhcp_interface, client_mac, expected_assigned_ip, DHCP_DEFAULT_LEASE_TIME) release_pkt = create_dhcp_client_packet( src_mac=client_mac, message_type=DHCP_MESSAGE_TYPE_RELEASE_NUM, @@ -272,11 +398,13 @@ def verify_discover_and_request_then_release( testutils.send_packet(ptfadapter, ptf_port_index, release_pkt) +@pytest.mark.parametrize("config_tool", [DHCP_SERVER_CONFIG_TOOL_GCU, DHCP_SERVER_CONFIG_TOOL_CLI]) def test_dhcp_server_port_based_assignment_single_ip_tc1( duthost, ptfhost, ptfadapter, - parse_vlan_setting_from_running_config + parse_vlan_setting_from_running_config, + config_tool ): """ Verify configured interface with client mac not in FDB table can successfully get IP @@ -285,14 +413,14 @@ def test_dhcp_server_port_based_assignment_single_ip_tc1( vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip = random.choice(vlan_hosts) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) - config_commands = [ - 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), - 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip, - 'config dhcp_server ipv4 bind %s %s --range test_single_ip' % (vlan_name, dut_port) - ] - with dhcp_server_config(duthost, config_commands): + config_cli = generate_common_config_cli_commands(vlan_name, gateway, net_mask, [dut_port], [[expected_assigned_ip]]) + config_gcu = generate_common_config_patch(vlan_name, gateway, net_mask, [dut_port], [[expected_assigned_ip]]) + config_to_apply = None + if config_tool == DHCP_SERVER_CONFIG_TOOL_CLI: + config_to_apply = config_cli + elif config_tool == DHCP_SERVER_CONFIG_TOOL_GCU: + config_to_apply = config_gcu + with dhcp_server_config(duthost, config_tool, config_to_apply): verify_discover_and_request_then_release( duthost=duthost, ptfhost=ptfhost, @@ -301,17 +429,20 @@ def test_dhcp_server_port_based_assignment_single_ip_tc1( ptf_port_index=ptf_port_index, ptf_mac_port_index=ptf_port_index, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip, exp_server_ip=gateway, net_mask=net_mask ) +@pytest.mark.parametrize("config_tool", [DHCP_SERVER_CONFIG_TOOL_GCU, DHCP_SERVER_CONFIG_TOOL_CLI]) def test_dhcp_server_port_based_assignment_single_ip_tc2( duthost, ptfhost, ptfadapter, - parse_vlan_setting_from_running_config + parse_vlan_setting_from_running_config, + config_tool, ): """ Verify configured interface with client mac in FDB table can successfully get IP @@ -320,14 +451,14 @@ def test_dhcp_server_port_based_assignment_single_ip_tc2( vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip = random.choice(vlan_hosts) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) - config_commands = [ - 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), - 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip, - 'config dhcp_server ipv4 bind %s %s --range test_single_ip' % (vlan_name, dut_port) - ] - with dhcp_server_config(duthost, config_commands): + config_cli = generate_common_config_cli_commands(vlan_name, gateway, net_mask, [dut_port], [[expected_assigned_ip]]) + config_gcu = generate_common_config_patch(vlan_name, gateway, net_mask, [dut_port], [[expected_assigned_ip]]) + config_to_apply = None + if config_tool == DHCP_SERVER_CONFIG_TOOL_CLI: + config_to_apply = config_cli + elif config_tool == DHCP_SERVER_CONFIG_TOOL_GCU: + config_to_apply = config_gcu + with dhcp_server_config(duthost, config_tool, config_to_apply): verify_discover_and_request_then_release( duthost=duthost, ptfhost=ptfhost, @@ -336,6 +467,7 @@ def test_dhcp_server_port_based_assignment_single_ip_tc2( ptf_port_index=ptf_port_index, ptf_mac_port_index=ptf_port_index, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip, exp_server_ip=gateway, net_mask=net_mask, @@ -343,11 +475,13 @@ def test_dhcp_server_port_based_assignment_single_ip_tc2( ) +@pytest.mark.parametrize("config_tool", [DHCP_SERVER_CONFIG_TOOL_GCU, DHCP_SERVER_CONFIG_TOOL_CLI]) def test_dhcp_server_port_based_assignment_single_ip_tc3( duthost, ptfhost, ptfadapter, - parse_vlan_setting_from_running_config + parse_vlan_setting_from_running_config, + config_tool ): """ Verify configured interface with client mac in FDB table @@ -357,15 +491,15 @@ def test_dhcp_server_port_based_assignment_single_ip_tc3( vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip = random.choice(vlan_hosts) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) - config_commands = [ - 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), - 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip, - 'config dhcp_server ipv4 bind %s %s --range test_single_ip' % (vlan_name, dut_port) - ] + config_cli = generate_common_config_cli_commands(vlan_name, gateway, net_mask, [dut_port], [[expected_assigned_ip]]) _, ptf_mac_port_index = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != dut_port]) - with dhcp_server_config(duthost, config_commands): + config_gcu = generate_common_config_patch(vlan_name, gateway, net_mask, [dut_port], [[expected_assigned_ip]]) + config_to_apply = None + if config_tool == DHCP_SERVER_CONFIG_TOOL_CLI: + config_to_apply = config_cli + elif config_tool == DHCP_SERVER_CONFIG_TOOL_GCU: + config_to_apply = config_gcu + with dhcp_server_config(duthost, config_tool, config_to_apply): verify_discover_and_request_then_release( duthost=duthost, ptfhost=ptfhost, @@ -374,6 +508,7 @@ def test_dhcp_server_port_based_assignment_single_ip_tc3( ptf_port_index=ptf_port_index, ptf_mac_port_index=ptf_mac_port_index, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip, exp_server_ip=gateway, net_mask=net_mask, @@ -381,46 +516,55 @@ def test_dhcp_server_port_based_assignment_single_ip_tc3( ) +@pytest.mark.parametrize("config_tool", [DHCP_SERVER_CONFIG_TOOL_GCU, DHCP_SERVER_CONFIG_TOOL_CLI]) def test_dhcp_server_port_based_assignment_single_ip_tc4( duthost, ptfhost, ptfadapter, - parse_vlan_setting_from_running_config + parse_vlan_setting_from_running_config, + config_tool ): """ Verify no-configured interface cannot get IP """ test_xid = 4 vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config - expected_assigned_ip = random.choice(vlan_hosts) - _, ptf_port_index = random.choice(vlan_members_with_ptf_idx) - config_commands = [ - 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), - 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_ip %s' % expected_assigned_ip - ] - with dhcp_server_config(duthost, config_commands): + assigned_ip = random.choice(vlan_hosts) + unconfigured_dut_port, unconfigured_ptf_port_index = random.choice(vlan_members_with_ptf_idx) + configured_dut_port, _ = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != unconfigured_dut_port]) + config_cli = generate_common_config_cli_commands( + vlan_name, gateway, net_mask, [configured_dut_port], [[assigned_ip]]) + config_gcu = generate_common_config_patch( + vlan_name, gateway, net_mask, [configured_dut_port], [[assigned_ip]]) + config_to_apply = None + if config_tool == DHCP_SERVER_CONFIG_TOOL_CLI: + config_to_apply = config_cli + elif config_tool == DHCP_SERVER_CONFIG_TOOL_GCU: + config_to_apply = config_gcu + with dhcp_server_config(duthost, config_tool, config_to_apply): verify_discover_and_request_then_release( duthost=duthost, ptfhost=ptfhost, ptfadapter=ptfadapter, dut_port_to_capture_pkt='any', - ptf_port_index=ptf_port_index, - ptf_mac_port_index=ptf_port_index, + ptf_port_index=unconfigured_ptf_port_index, + ptf_mac_port_index=unconfigured_ptf_port_index, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=None, exp_server_ip=gateway, net_mask=net_mask, - refresh_fdb_ptf_port='eth'+str(ptf_port_index) + refresh_fdb_ptf_port='eth'+str(unconfigured_ptf_port_index) ) +@pytest.mark.parametrize("config_tool", [DHCP_SERVER_CONFIG_TOOL_GCU, DHCP_SERVER_CONFIG_TOOL_CLI]) def test_dhcp_server_port_based_assignment_range_ip( duthost, ptfhost, ptfadapter, - parse_vlan_setting_from_running_config + parse_vlan_setting_from_running_config, + config_tool ): """ Test single ip assignment with different scenarios, each scenario has a description in scenario_context. @@ -430,14 +574,16 @@ def test_dhcp_server_port_based_assignment_range_ip( expected_assigned_ip = random.choice(vlan_hosts[:-1]) last_ip_in_range = random.choice(vlan_hosts[vlan_hosts.index(expected_assigned_ip) + 1:]) dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) - config_commands = [ - 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), - 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_range_ip %s %s' % (expected_assigned_ip, last_ip_in_range), - 'config dhcp_server ipv4 bind %s %s --range test_range_ip' % (vlan_name, dut_port), - ] - with dhcp_server_config(duthost, config_commands): + config_cli = generate_common_config_cli_commands( + vlan_name, gateway, net_mask, [dut_port], [[expected_assigned_ip, last_ip_in_range]]) + config_gcu = generate_common_config_patch( + vlan_name, gateway, net_mask, [dut_port], [[expected_assigned_ip, last_ip_in_range]]) + config_to_apply = None + if config_tool == DHCP_SERVER_CONFIG_TOOL_CLI: + config_to_apply = config_cli + elif config_tool == DHCP_SERVER_CONFIG_TOOL_GCU: + config_to_apply = config_gcu + with dhcp_server_config(duthost, config_tool, config_to_apply): verify_discover_and_request_then_release( duthost=duthost, ptfhost=ptfhost, @@ -446,6 +592,7 @@ def test_dhcp_server_port_based_assignment_range_ip( ptf_port_index=ptf_port_index, ptf_mac_port_index=ptf_port_index, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip, exp_server_ip=gateway, net_mask=net_mask, @@ -453,92 +600,33 @@ def test_dhcp_server_port_based_assignment_range_ip( ) -def test_dhcp_server_port_based_customize_options(duthost, ptfhost, ptfadapter, parse_vlan_setting_from_running_config): - """ - Test dhcp server packets if carry the customized options as expected - """ - test_xid = 6 - vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config - expected_assigned_ip = random.choice(vlan_hosts) - dut_port, ptf_port_index = random.choice(vlan_members_with_ptf_idx) - client_mac = ptfadapter.dataplane.get_mac(0, ptf_port_index).decode('utf-8') - config_commands = [ - 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), - 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_option_ip %s' % expected_assigned_ip, - 'config dhcp_server ipv4 bind %s %s --range test_option_ip' % (vlan_name, dut_port), - 'config dhcp_server ipv4 option add ' + - 'sonic_test_option 147 string %s' % DHCP_DEFAULT_CUSTOM_OPTION_VALUE, - 'config dhcp_server ipv4 option bind %s sonic_test_option' % vlan_name - ] - with dhcp_server_config(duthost, config_commands): - pkts_validator = validate_dhcp_server_pkts_custom_option - pkts_validator_args = [test_xid] - pkts_validator_kwargs = {"147": DHCP_DEFAULT_CUSTOM_OPTION_VALUE.encode('ascii')} - discover_pkt = create_dhcp_client_packet( - src_mac=client_mac, - message_type=DHCP_MESSAGE_TYPE_DISCOVER_NUM, - client_options=[], - xid=test_xid - ) - send_and_verify( - duthost=duthost, - ptfhost=ptfhost, - ptfadapter=ptfadapter, - test_pkt=discover_pkt, - dut_port_to_capture_pkt=dut_port, - ptf_port_index=ptf_port_index, - pkts_validator=pkts_validator, - pkts_validator_args=pkts_validator_args, - pkts_validator_kwargs=pkts_validator_kwargs, - refresh_fdb_ptf_port='eth'+str(ptf_port_index) - ) - request_pkt = create_dhcp_client_packet( - src_mac=client_mac, - message_type=DHCP_MESSAGE_TYPE_REQUEST_NUM, - client_options=[("requested_addr", expected_assigned_ip), ("server_id", gateway)], - xid=test_xid - ) - send_and_verify( - duthost=duthost, - ptfhost=ptfhost, - ptfadapter=ptfadapter, - dut_port_to_capture_pkt=dut_port, - ptf_port_index=ptf_port_index, - test_pkt=request_pkt, - pkts_validator=pkts_validator, - pkts_validator_args=pkts_validator_args, - pkts_validator_kwargs=pkts_validator_kwargs, - refresh_fdb_ptf_port='eth'+str(ptf_port_index) - ) - - +@pytest.mark.parametrize("config_tool", [DHCP_SERVER_CONFIG_TOOL_GCU, DHCP_SERVER_CONFIG_TOOL_CLI]) def test_dhcp_server_port_based_assigenment_single_ip_mac_move( duthost, ptfhost, ptfadapter, - parse_vlan_setting_from_running_config + parse_vlan_setting_from_running_config, + config_tool ): """ To test port based single ip assignment with client move to an interface has free IP to assign. """ - test_xid = 7 + test_xid = 6 vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip_0 = random.choice(vlan_hosts) dut_port_0, ptf_port_index_0 = random.choice(vlan_members_with_ptf_idx) expected_assigned_ip_1 = random.choice([v for v in vlan_hosts if v != expected_assigned_ip_0]) dut_port_1, ptf_port_index_1 = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != dut_port_0]) - config_commands = [ - 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), - 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_ip_0 %s' % expected_assigned_ip_0, - 'config dhcp_server ipv4 bind %s %s --range test_single_ip_0' % (vlan_name, dut_port_0), - 'config dhcp_server ipv4 range add test_single_ip_1 %s' % expected_assigned_ip_1, - 'config dhcp_server ipv4 bind %s %s --range test_single_ip_1' % (vlan_name, dut_port_1) - ] - with dhcp_server_config(duthost, config_commands): + config_cli = generate_common_config_cli_commands( + vlan_name, gateway, net_mask, [dut_port_0, dut_port_1], [[expected_assigned_ip_0], [expected_assigned_ip_1]]) + config_gcu = generate_common_config_patch( + vlan_name, gateway, net_mask, [dut_port_0, dut_port_1], [[expected_assigned_ip_0], [expected_assigned_ip_1]]) + config_to_apply = None + if config_tool == DHCP_SERVER_CONFIG_TOOL_CLI: + config_to_apply = config_cli + elif config_tool == DHCP_SERVER_CONFIG_TOOL_GCU: + config_to_apply = config_gcu + with dhcp_server_config(duthost, config_tool, config_to_apply): verify_discover_and_request_then_release( duthost=duthost, ptfhost=ptfhost, @@ -547,6 +635,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_move( ptf_port_index=ptf_port_index_0, ptf_mac_port_index=ptf_port_index_0, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip_0, exp_server_ip=gateway, net_mask=net_mask @@ -559,37 +648,40 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_move( ptf_port_index=ptf_port_index_1, ptf_mac_port_index=ptf_port_index_0, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip_1, exp_server_ip=gateway, net_mask=net_mask ) +@pytest.mark.parametrize("config_tool", [DHCP_SERVER_CONFIG_TOOL_GCU, DHCP_SERVER_CONFIG_TOOL_CLI]) def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( duthost, ptfhost, ptfadapter, - parse_vlan_setting_from_running_config + parse_vlan_setting_from_running_config, + config_tool ): """ To test port based single ip assignment with two clients swap their interfaces. """ - test_xid = 8 + test_xid = 7 vlan_name, gateway, net_mask, vlan_hosts, vlan_members_with_ptf_idx = parse_vlan_setting_from_running_config expected_assigned_ip_0 = random.choice(vlan_hosts) dut_port_0, ptf_port_index_0 = random.choice(vlan_members_with_ptf_idx) expected_assigned_ip_1 = random.choice([v for v in vlan_hosts if v != expected_assigned_ip_0]) dut_port_1, ptf_port_index_1 = random.choice([m for m in vlan_members_with_ptf_idx if m[0] != dut_port_0]) - config_commands = [ - 'config dhcp_server ipv4 add --mode PORT --lease_time %s ' % DHCP_DEFAULT_LEASE_TIME + - '--gateway %s --netmask %s %s' % (gateway, net_mask, vlan_name), - 'config dhcp_server ipv4 enable %s' % vlan_name, - 'config dhcp_server ipv4 range add test_single_ip_0 %s' % expected_assigned_ip_0, - 'config dhcp_server ipv4 bind %s %s --range test_single_ip_0' % (vlan_name, dut_port_0), - 'config dhcp_server ipv4 range add test_single_ip_1 %s' % expected_assigned_ip_1, - 'config dhcp_server ipv4 bind %s %s --range test_single_ip_1' % (vlan_name, dut_port_1) - ] - with dhcp_server_config(duthost, config_commands): + config_cli = generate_common_config_cli_commands( + vlan_name, gateway, net_mask, [dut_port_0, dut_port_1], [[expected_assigned_ip_0], [expected_assigned_ip_1]]) + config_gcu = generate_common_config_patch( + vlan_name, gateway, net_mask, [dut_port_0, dut_port_1], [[expected_assigned_ip_0], [expected_assigned_ip_1]]) + config_to_apply = None + if config_tool == DHCP_SERVER_CONFIG_TOOL_CLI: + config_to_apply = config_cli + elif config_tool == DHCP_SERVER_CONFIG_TOOL_GCU: + config_to_apply = config_gcu + with dhcp_server_config(duthost, config_tool, config_to_apply): verify_discover_and_request_then_release( duthost=duthost, ptfhost=ptfhost, @@ -598,6 +690,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( ptf_port_index=ptf_port_index_0, ptf_mac_port_index=ptf_port_index_0, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip_0, exp_server_ip=gateway, net_mask=net_mask @@ -610,6 +703,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( ptf_port_index=ptf_port_index_1, ptf_mac_port_index=ptf_port_index_1, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip_1, exp_server_ip=gateway, net_mask=net_mask @@ -622,6 +716,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( ptf_port_index=ptf_port_index_1, ptf_mac_port_index=ptf_port_index_0, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip_1, exp_server_ip=gateway, net_mask=net_mask @@ -634,6 +729,7 @@ def test_dhcp_server_port_based_assigenment_single_ip_mac_swap( ptf_port_index=ptf_port_index_0, ptf_mac_port_index=ptf_port_index_1, test_xid=test_xid, + dhcp_interface=vlan_name, expected_assigned_ip=expected_assigned_ip_0, exp_server_ip=gateway, net_mask=net_mask From d72176c57e10a727db87f5a4f7df2d50e9195873 Mon Sep 17 00:00:00 2001 From: Wenda Chu <32250288+w1nda@users.noreply.github.com> Date: Tue, 7 May 2024 15:28:36 +0800 Subject: [PATCH 7/8] remove dependences on gcu_util --- tests/dhcp_server/test_dhcp_server.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/dhcp_server/test_dhcp_server.py b/tests/dhcp_server/test_dhcp_server.py index 694a0ce218c..216f904e356 100644 --- a/tests/dhcp_server/test_dhcp_server.py +++ b/tests/dhcp_server/test_dhcp_server.py @@ -9,13 +9,13 @@ import random from tests.common.utilities import capture_and_check_packet_on_dut from tests.common.helpers.assertions import pytest_assert, pytest_require -from tests.generic_config_updater.gu_utils import apply_patch, expect_op_success, generate_tmpfile, delete_tmpfile pytestmark = [ pytest.mark.topology('mx'), ] + MINIMUM_HOSTS_COUNT = 2 MINIMUM_INTERFACE_MEMBERS_COUNT = 2 DHCP_DEFAULT_LEASE_TIME = 300 @@ -128,12 +128,18 @@ def dhcp_server_config_cli(duthost, config_commands): def dhcp_server_config_gcu(duthost, config_to_apply): - tmpfile = generate_tmpfile(duthost) + logging.info("The dhcp_server_config: %s" % config_to_apply) + tmpfile = duthost.shell('mktemp')['stdout'] try: - output = apply_patch(duthost, json_data=config_to_apply, dest_file=tmpfile) - expect_op_success(duthost, output) + duthost.copy(content=json.dumps(config_to_apply, indent=4), dest=tmpfile) + output = duthost.shell('config apply-patch {}'.format(tmpfile), module_ignore_errors=True) + pytest_assert(not output['rc'], "Command is not running successfully") + pytest_assert( + "Patch applied successfully" in output['stdout'], + "Please check if json file is validate" + ) finally: - delete_tmpfile(duthost, tmpfile) + duthost.file(path=tmpfile, state='absent') def generate_common_config_patch(vlan_name, gateway, net_mask, dut_ports, ip_ranges): From 499ea3b26729c1b713ee978101535ed83642f8f0 Mon Sep 17 00:00:00 2001 From: Wenda Chu <32250288+w1nda@users.noreply.github.com> Date: Tue, 7 May 2024 15:32:30 +0800 Subject: [PATCH 8/8] Update test_dhcp_server.py --- tests/dhcp_server/test_dhcp_server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/dhcp_server/test_dhcp_server.py b/tests/dhcp_server/test_dhcp_server.py index 216f904e356..f47cfb1a569 100644 --- a/tests/dhcp_server/test_dhcp_server.py +++ b/tests/dhcp_server/test_dhcp_server.py @@ -1,6 +1,7 @@ import binascii import contextlib from datetime import datetime +import json import logging import ipaddress import pytest