diff --git a/config/main.py b/config/main.py index c8ec8bc86b..6641328c36 100644 --- a/config/main.py +++ b/config/main.py @@ -1894,14 +1894,24 @@ def override_config_table(db, input_config_db, dry_run): current_config = config_db.get_config() # Serialize to the same format as json input sonic_cfggen.FormatConverter.to_serialized(current_config) - - if multi_asic.is_multi_asic(): + ns_config_input = None + if multi_asic.is_multi_asic() and len(config_input): # Golden Config will use "localhost" to represent host name if ns == DEFAULT_NAMESPACE: - ns_config_input = config_input["localhost"] + if "localhost" in config_input.keys(): + ns_config_input = config_input["localhost"] + else: + click.secho("Wrong config format! 'localhost' not found in host config! cannot override.. abort") + sys.exit(1) else: - ns_config_input = config_input[ns] - else: + if ns in config_input.keys(): + ns_config_input = config_input[ns] + else: + click.secho("Wrong config format! {} not found in asic config! cannot override.. abort".format(ns)) + sys.exit(1) + if not ns_config_input: + # if ns_config_input is not defined, define it + # it could be single-asic dut, or config_input is empty ns_config_input = config_input # Generate sysinfo if missing in ns_config_input generate_sysinfo(current_config, ns_config_input, ns) diff --git a/tests/config_override_input/multi_asic_missing_asic.json b/tests/config_override_input/multi_asic_missing_asic.json new file mode 100644 index 0000000000..4399bfb32e --- /dev/null +++ b/tests/config_override_input/multi_asic_missing_asic.json @@ -0,0 +1,5 @@ +{ + "localhost": { + "DEVICE_METADATA": {} + } +} diff --git a/tests/config_override_input/multi_asic_missing_localhost.json b/tests/config_override_input/multi_asic_missing_localhost.json new file mode 100644 index 0000000000..861c89717e --- /dev/null +++ b/tests/config_override_input/multi_asic_missing_localhost.json @@ -0,0 +1,11 @@ +{ + "host": { + "DEVICE_METADATA": {} + }, + "asic0": { + "DEVICE_METADATA": {} + }, + "asic1": { + "DEVICE_METADATA": {} + } +} diff --git a/tests/config_override_test.py b/tests/config_override_test.py index 3df8cea562..beeafaa82b 100644 --- a/tests/config_override_test.py +++ b/tests/config_override_test.py @@ -24,6 +24,8 @@ MULTI_ASIC_MACSEC_OV = os.path.join(DATA_DIR, "multi_asic_macsec_ov.json") MULTI_ASIC_DEVICE_METADATA_RM = os.path.join(DATA_DIR, "multi_asic_dm_rm.json") MULTI_ASIC_DEVICE_METADATA_GEN_SYSINFO = os.path.join(DATA_DIR, "multi_asic_dm_gen_sysinfo.json") +MULTI_ASIC_MISSING_LOCALHOST_OV = os.path.join(DATA_DIR, "multi_asic_missing_localhost.json") +MULTI_ASIC_MISSING_ASIC_OV = os.path.join(DATA_DIR, "multi_asic_missing_asic.json") # Load sonic-cfggen from source since /usr/local/bin/sonic-cfggen does not have .py extension. sonic_cfggen = load_module_from_source('sonic_cfggen', '/usr/local/bin/sonic-cfggen') @@ -381,6 +383,39 @@ def read_json_file_side_effect(filename): assert platform == "multi_asic" assert mac == "11:22:33:44:55:66" + def test_masic_missig_localhost_override(self): + def read_json_file_side_effect(filename): + with open(MULTI_ASIC_MISSING_LOCALHOST_OV, "r") as f: + wrong_format = json.load(f) + return wrong_format + db = Db() + cfgdb_clients = db.cfgdb_clients + + with mock.patch('config.main.read_json_file', + mock.MagicMock(side_effect=read_json_file_side_effect)): + runner = CliRunner() + result = runner.invoke(config.config.commands["override-config-table"], + ['golden_config_db.json'], obj=db) + assert "'localhost' not found in host config" in result.output + # make sure program aborted with return code 1 + assert result.exit_code == 1 + + def test_masic_missig_asic_override(self): + def read_json_file_side_effect(filename): + with open(MULTI_ASIC_MISSING_ASIC_OV, "r") as f: + wrong_format = json.load(f) + return wrong_format + db = Db() + cfgdb_clients = db.cfgdb_clients + + with mock.patch('config.main.read_json_file', + mock.MagicMock(side_effect=read_json_file_side_effect)): + runner = CliRunner() + result = runner.invoke(config.config.commands["override-config-table"], + ['golden_config_db.json'], obj=db) + assert "not found in asic config" in result.output + # make sure program aborted with return code 1 + assert result.exit_code == 1 @classmethod def teardown_class(cls):