From 185547fc78eb3dff84357cf3d73a9e00b2566b46 Mon Sep 17 00:00:00 2001 From: judyjoseph Date: Fri, 7 Oct 2022 02:53:25 -0400 Subject: [PATCH] Add UT to improve coverage, for namespace config update --- tests/common/mock_configdb.py | 2 +- tests/hostcfgd/hostcfgd_test.py | 74 +++++++++-------- tests/hostcfgd/test_vectors.py | 135 ++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 35 deletions(-) diff --git a/tests/common/mock_configdb.py b/tests/common/mock_configdb.py index 1ee279a6b9ae..70b8da6afabe 100644 --- a/tests/common/mock_configdb.py +++ b/tests/common/mock_configdb.py @@ -57,5 +57,5 @@ def listen(self, init_data_handler=None): class MockDBConnector(): - def __init__(self, db, val): + def __init__(self, db, val, tcpFlag=False, name=None): pass diff --git a/tests/hostcfgd/hostcfgd_test.py b/tests/hostcfgd/hostcfgd_test.py index 93ba7b9666a6..bc79aeb164f8 100644 --- a/tests/hostcfgd/hostcfgd_test.py +++ b/tests/hostcfgd/hostcfgd_test.py @@ -28,7 +28,6 @@ hostcfgd.DBConnector = MockDBConnector hostcfgd.Table = mock.Mock() - class TestFeatureHandler(TestCase): """Test methods of `FeatureHandler` class. """ @@ -127,39 +126,46 @@ def test_sync_state_field(self, test_scenario_name, config_data, fs): with mock.patch("sonic_py_common.device_info.get_device_runtime_metadata", return_value=config_data['device_runtime_metadata']): with mock.patch("sonic_py_common.device_info.is_multi_npu", return_value=True if 'num_npu' in config_data else False): with mock.patch("sonic_py_common.device_info.get_num_npus", return_value=config_data['num_npu'] if 'num_npu' in config_data else 1): - popen_mock = mock.Mock() - attrs = config_data['popen_attributes'] - popen_mock.configure_mock(**attrs) - mocked_subprocess.Popen.return_value = popen_mock - - device_config = {} - device_config['DEVICE_METADATA'] = MockConfigDb.CONFIG_DB['DEVICE_METADATA'] - device_config.update(config_data['device_runtime_metadata']) - - feature_handler = hostcfgd.FeatureHandler(MockConfigDb(), feature_state_table_mock, device_config) - - feature_table = MockConfigDb.CONFIG_DB['FEATURE'] - feature_handler.sync_state_field(feature_table) - - feature_systemd_name_map = {} - for feature_name in feature_table.keys(): - feature = hostcfgd.Feature(feature_name, feature_table[feature_name], device_config) - feature_names, _ = feature_handler.get_multiasic_feature_instances(feature) - feature_systemd_name_map[feature_name] = feature_names - - is_any_difference = self.checks_config_table(MockConfigDb.get_config_db()['FEATURE'], - config_data['expected_config_db']['FEATURE']) - assert is_any_difference, "'FEATURE' table in 'CONFIG_DB' is modified unexpectedly!" - - feature_table_state_db_calls = self.get_state_db_set_calls(feature_table) - - self.checks_systemd_config_file(config_data['config_db']['FEATURE'], feature_systemd_name_map) - mocked_subprocess.check_call.assert_has_calls(config_data['enable_feature_subprocess_calls'], - any_order=True) - mocked_subprocess.check_call.assert_has_calls(config_data['daemon_reload_subprocess_call'], - any_order=True) - feature_state_table_mock.set.assert_has_calls(feature_table_state_db_calls) - self.checks_systemd_config_file(config_data['config_db']['FEATURE'], feature_systemd_name_map) + with mock.patch("sonic_py_common.device_info.get_namespaces", return_value=["asic{}".format(a) for a in range(config_data['num_npu'])] if 'num_npu' in config_data else []): + popen_mock = mock.Mock() + attrs = config_data['popen_attributes'] + popen_mock.configure_mock(**attrs) + mocked_subprocess.Popen.return_value = popen_mock + + device_config = {} + device_config['DEVICE_METADATA'] = MockConfigDb.CONFIG_DB['DEVICE_METADATA'] + device_config.update(config_data['device_runtime_metadata']) + + feature_handler = hostcfgd.FeatureHandler(MockConfigDb(), feature_state_table_mock, device_config) + feature_table = MockConfigDb.CONFIG_DB['FEATURE'] + feature_handler.sync_state_field(feature_table) + + feature_systemd_name_map = {} + for feature_name in feature_table.keys(): + feature = hostcfgd.Feature(feature_name, feature_table[feature_name], device_config) + feature_names, _ = feature_handler.get_multiasic_feature_instances(feature) + feature_systemd_name_map[feature_name] = feature_names + + is_any_difference = self.checks_config_table(MockConfigDb.get_config_db()['FEATURE'], + config_data['expected_config_db']['FEATURE']) + assert is_any_difference, "'FEATURE' table in 'CONFIG_DB' is modified unexpectedly!" + + if 'num_npu' in config_data: + for ns in range(config_data['num_npu']): + namespace = "asic{}".format(ns) + is_any_difference = self.checks_config_table(feature_handler.ns_cfg_db[namespace].get_config_db()['FEATURE'], + config_data['expected_config_db']['FEATURE']) + assert is_any_difference, "'FEATURE' table in 'CONFIG_DB' in namespace {} is modified unexpectedly!".format(namespace) + + feature_table_state_db_calls = self.get_state_db_set_calls(feature_table) + + self.checks_systemd_config_file(config_data['config_db']['FEATURE'], feature_systemd_name_map) + mocked_subprocess.check_call.assert_has_calls(config_data['enable_feature_subprocess_calls'], + any_order=True) + mocked_subprocess.check_call.assert_has_calls(config_data['daemon_reload_subprocess_call'], + any_order=True) + feature_state_table_mock.set.assert_has_calls(feature_table_state_db_calls) + self.checks_systemd_config_file(config_data['config_db']['FEATURE'], feature_systemd_name_map) @parameterized.expand(HOSTCFGD_TEST_VECTOR) @patchfs diff --git a/tests/hostcfgd/test_vectors.py b/tests/hostcfgd/test_vectors.py index 4f6dca3056a6..0a39b48053d1 100644 --- a/tests/hostcfgd/test_vectors.py +++ b/tests/hostcfgd/test_vectors.py @@ -1030,6 +1030,141 @@ }, }, ], + [ + "Chassis_LineCard_VOQ_multinpu", + { + "num_npu": 2, + "device_runtime_metadata": { + "DEVICE_RUNTIME_METADATA": { + "CHASSIS_METADATA": { + "module_type": "linecard", + "chassis_type": "voq" + }, + "ETHERNET_PORTS_PRESENT":True, + "MACSEC_SUPPORTED":True + } + }, + "config_db": { + "DEVICE_METADATA": { + "localhost": { + "type": "SpineRouter", + } + }, + "KDUMP": { + "config": { + "enabled": "false", + "num_dumps": "3", + "memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M" + } + }, + "FEATURE": { + "bgp": { + "state": "{% if not DEVICE_RUNTIME_METADATA['ETHERNET_PORTS_PRESENT'] or ('CHASSIS_METADATA' in DEVICE_RUNTIME_METADATA and DEVICE_RUNTIME_METADATA['CHASSIS_METADATA']['module_type'] in ['supervisor']) %}disabled{% else %}enabled{% endif %}", + "has_timer": "False", + "has_global_scope": "False", + "has_per_asic_scope": "True", + "auto_restart": "enabled", + "high_mem_alert": "disabled" + }, + "teamd": { + "state": "{% if not DEVICE_RUNTIME_METADATA['ETHERNET_PORTS_PRESENT'] %}disabled{% else %}enabled{% endif %}", + "has_timer": "False", + "has_global_scope": "False", + "has_per_asic_scope": "True", + "auto_restart": "enabled", + "high_mem_alert": "disabled" + }, + "lldp": { + "state": "enabled", + "has_timer": "False", + "has_global_scope": "True", + "has_per_asic_scope": "{% if not DEVICE_RUNTIME_METADATA['ETHERNET_PORTS_PRESENT'] or ('CHASSIS_METADATA' in DEVICE_RUNTIME_METADATA and DEVICE_RUNTIME_METADATA['CHASSIS_METADATA']['module_type'] in ['supervisor']) %}False{% else %}True{% endif %}", + "auto_restart": "enabled", + "high_mem_alert": "disabled" + }, + "macsec": { + "state": "{% if 'type' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['type'] == 'SpineRouter' and DEVICE_RUNTIME_METADATA['MACSEC_SUPPORTED'] %}enabled{% else %}disabled{% endif %}", + "has_timer": "False", + "has_global_scope": "False", + "has_per_asic_scope": "True", + "auto_restart": "enabled", + "high_mem_alert": "disabled" + } + }, + }, + "expected_config_db": { + "FEATURE": { + "bgp": { + "auto_restart": "enabled", + "has_global_scope": "False", + "has_per_asic_scope": "True", + "has_timer": "False", + "high_mem_alert": "disabled", + "state": "enabled" + }, + "teamd": { + "auto_restart": "enabled", + "has_global_scope": "False", + "has_per_asic_scope": "True", + "has_timer": "False", + "high_mem_alert": "disabled", + "state": "enabled" + }, + "lldp": { + "auto_restart": "enabled", + "has_global_scope": "True", + "has_per_asic_scope": "True", + "has_timer": "False", + "high_mem_alert": "disabled", + "state": "enabled" + }, + "macsec": { + "auto_restart": "enabled", + "has_global_scope": "False", + "has_per_asic_scope": "True", + "has_timer": "False", + "high_mem_alert": "disabled", + "state": "enabled" + } + }, + }, + "enable_feature_subprocess_calls": [ + call('sudo systemctl unmask bgp@0.service', shell=True), + call('sudo systemctl enable bgp@0.service', shell=True), + call('sudo systemctl start bgp@0.service', shell=True), + call('sudo systemctl unmask bgp@1.service', shell=True), + call('sudo systemctl enable bgp@1.service', shell=True), + call('sudo systemctl start bgp@1.service', shell=True), + call('sudo systemctl unmask teamd@0.service', shell=True), + call('sudo systemctl enable teamd@0.service', shell=True), + call('sudo systemctl start teamd@0.service', shell=True), + call('sudo systemctl unmask teamd@1.service', shell=True), + call('sudo systemctl enable teamd@1.service', shell=True), + call('sudo systemctl start teamd@1.service', shell=True), + call('sudo systemctl unmask lldp.service', shell=True), + call('sudo systemctl enable lldp.service', shell=True), + call('sudo systemctl start lldp.service', shell=True), + call('sudo systemctl unmask lldp@0.service', shell=True), + call('sudo systemctl enable lldp@0.service', shell=True), + call('sudo systemctl start lldp@0.service', shell=True), + call('sudo systemctl unmask lldp@1.service', shell=True), + call('sudo systemctl enable lldp@1.service', shell=True), + call('sudo systemctl start lldp@1.service', shell=True), + call('sudo systemctl unmask macsec@0.service', shell=True), + call('sudo systemctl enable macsec@0.service', shell=True), + call('sudo systemctl start macsec@0.service', shell=True), + call('sudo systemctl unmask macsec@1.service', shell=True), + call('sudo systemctl enable macsec@1.service', shell=True), + call('sudo systemctl start macsec@1.service', shell=True) + ], + "daemon_reload_subprocess_call": [ + call("sudo systemctl daemon-reload", shell=True), + ], + "popen_attributes": { + 'communicate.return_value': ('output', 'error') + }, + }, + ] ]