diff --git a/tests/copp/copp_utils.py b/tests/copp/copp_utils.py index e5a7b12ef93..01779e014b0 100644 --- a/tests/copp/copp_utils.py +++ b/tests/copp/copp_utils.py @@ -11,8 +11,9 @@ _ADD_IP_SCRIPT = "scripts/add_ip.sh" _UPDATE_COPP_SCRIPT = "copp/scripts/update_copp_config.py" -_BASE_COPP_CONFIG = "/tmp/00-copp.config.json" -_SWSS_COPP_CONFIG = "swss:/etc/swss/config.d/00-copp.config.json" +_BASE_COPP_CONFIG = "/tmp/base_copp_config.json" +_APP_DB_COPP_CONFIG = "swss:/etc/swss/config.d/00-copp.config.json" +_CONFIG_DB_COPP_CONFIG = "/etc/sonic/copp_cfg.json" _TEMP_COPP_CONFIG = "/tmp/copp_config.json" _TEMP_COPP_TEMPLATE = "/tmp/copp.json.j2" _COPP_TEMPLATE_PATH = "/usr/share/sonic/templates/copp.json.j2" @@ -36,16 +37,31 @@ def limit_policer(dut, pps_limit): pps_limit (int): The rate limit for COPP to enforce on ALL trap groups. """ - dut.command("docker cp {} {}".format(_SWSS_COPP_CONFIG, _BASE_COPP_CONFIG)) - dut.script(cmd="{} {} {} {}".format(_UPDATE_COPP_SCRIPT, pps_limit, - _BASE_COPP_CONFIG, _TEMP_COPP_CONFIG)) - dut.command("docker cp {} {}".format(_TEMP_COPP_CONFIG, _SWSS_COPP_CONFIG)) - - # As copp config is regenerated each time swss starts need to replace the template with - # config updated above. But before doing that need store the original template in a temporary file - # for restore after test. - dut.command("docker cp {} {}".format(_SWSS_COPP_TEMPLATE, _TEMP_COPP_TEMPLATE)) - dut.command("docker cp {} {}".format(_TEMP_COPP_CONFIG, _SWSS_COPP_TEMPLATE)) + if "201811" in dut.os_version or "201911" in dut.os_version: + dut.command("docker cp {} {}".format(_APP_DB_COPP_CONFIG, _BASE_COPP_CONFIG)) + config_format = "app_db" + else: + dut.command("cp {} {}".format(_CONFIG_DB_COPP_CONFIG, _BASE_COPP_CONFIG)) + config_format = "config_db" + + dut.script( + cmd="{} {} {} {} {}".format(_UPDATE_COPP_SCRIPT, + pps_limit, + _BASE_COPP_CONFIG, + _TEMP_COPP_CONFIG, + config_format) + ) + + if config_format == "app_db": + dut.command("docker cp {} {}".format(_TEMP_COPP_CONFIG, _APP_DB_COPP_CONFIG)) + + # As copp config is regenerated each time swss starts need to replace the template with + # config updated above. But before doing that need store the original template in a + # temporary file for restore after test. + dut.command("docker cp {} {}".format(_SWSS_COPP_TEMPLATE, _TEMP_COPP_TEMPLATE)) + dut.command("docker cp {} {}".format(_TEMP_COPP_CONFIG, _SWSS_COPP_TEMPLATE)) + else: + dut.command("cp {} {}".format(_TEMP_COPP_CONFIG, _CONFIG_DB_COPP_CONFIG)) def restore_policer(dut): """ @@ -56,8 +72,12 @@ def restore_policer(dut): The SWSS container must be restarted for the config change to take effect. """ - # Restore the copp template in swss - dut.command("docker cp {} {}".format(_TEMP_COPP_TEMPLATE, _SWSS_COPP_TEMPLATE)) + # Restore the copp template in swss + if "201811" in dut.os_version or "201911" in dut.os_version: + dut.command("docker cp {} {}".format(_BASE_COPP_CONFIG, _APP_DB_COPP_CONFIG)) + dut.command("docker cp {} {}".format(_TEMP_COPP_TEMPLATE, _SWSS_COPP_TEMPLATE)) + else: + dut.command("cp {} {}".format(_BASE_COPP_CONFIG, _CONFIG_DB_COPP_CONFIG)) def configure_ptf(ptf, nn_target_port): """ diff --git a/tests/copp/scripts/update_copp_config.py b/tests/copp/scripts/update_copp_config.py index 007ac051985..e4d47080a84 100644 --- a/tests/copp/scripts/update_copp_config.py +++ b/tests/copp/scripts/update_copp_config.py @@ -1,36 +1,80 @@ #!/usr/bin/python -""" - Script to modify a COPP configuration to follow a specified rate limit. +"""Script to modify a COPP configuration to follow a specified rate limit. + +This is used by the COPP tests to reduce the rate limit below that of the +PTF host's sending rate. + +Example: + python update_copp_config.py + python update_copp_config.py 600 /tmp/copp_config.json /tmp/new_copp_config.json app_db + +Note: + Historically, there was a 00-copp.config.json file in the SWSS docker that specified + the parameters for each trap group like so: - This is used by the COPP tests to reduce the rate limit below that of the - PTF host's sending rate. + [ + "COPP_TABLE:default": { + "cir": "600", + "cbs": "600", + ... + }, + "COPP_TABLE:trap.group.bgp.lacp": { + ... + }, + ... + ] - Example:: + This is the "app_db" format used for 202006 images and earlier. - $ python update_copp_config.py - $ python update_copp_config.py 600 /tmp/copp_config.json /tmp/new_copp_config.json + In newer SONiC versions, there is a copp_cfg.json file on the host that specifies the parameters + for each trap group like so: + + { + "COPP_GROUP": { + "default": { + "cir":"600", + "cbs":"600", + ... + }, + "queue4_group1": { + ... + }, + ... + }, + ... + } + + This is the "config_db" format used for 202012 images and later (including the master branch). """ import json import sys -def generate_limited_pps_config(pps_limit, input_config_file, output_config_file): - """ - Modifies a COPP config to use the specified rate limit. - Notes: - This only affects COPP policies that enforce a rate limit. Other - policies are left alone. +def generate_limited_pps_config(pps_limit, input_config_file, output_config_file, config_format="app_db"): + """Modifies a COPP config to use the specified rate limit. - Args: - pps_limit (int): The rate limit to enforce expressed in PPS (packets-per-second) - input_config_file (str): The name of the file containing the initial config - output_config_file (str): The name of the file to output the modified config - """ + Notes: + This only affects COPP policies that enforce a rate limit. Other + policies are left alone. + + Args: + pps_limit (int): The rate limit to enforce expressed in PPS (packets-per-second) + input_config_file (str): The name of the file containing the initial config + output_config_file (str): The name of the file to output the modified config + config_format (str): The format of the input COPP config file + """ with open(input_config_file) as input_stream: copp_config = json.load(input_stream) - for trap_group in copp_config: + if config_format == "app_db": + trap_groups = copp_config + elif config_format == "config_db": + trap_groups = [{x: y} for x, y in copp_config["COPP_GROUP"].items()] + else: + raise ValueError("Invalid config format specified") + + for trap_group in trap_groups: for _, group_config in trap_group.items(): # Notes: # CIR (committed information rate) - bandwidth limit set by the policer @@ -48,6 +92,13 @@ def generate_limited_pps_config(pps_limit, input_config_file, output_config_file with open(output_config_file, "w+") as output_stream: json.dump(copp_config, output_stream) + if __name__ == "__main__": ARGS = sys.argv[1:] - generate_limited_pps_config(ARGS[0], ARGS[1], ARGS[2]) + + if len(ARGS) < 4: + config_format = "app_db" + else: + config_format = ARGS[3] + + generate_limited_pps_config(ARGS[0], ARGS[1], ARGS[2], config_format)