Skip to content

Commit

Permalink
Apply GCU changes to the appropriate namespace scope for each suite (#…
Browse files Browse the repository at this point in the history
…16065)

Description of PR
For GCU test suites, configuration changes applied via patches sometimes target a specific ASIC namespace or apply globally to the card (localhost), depending on the feature functionality.

With the recent merged PR #14098, configuration changes are now applied to both localhost and all ASIC namespaces for all multi-ASIC platforms by default, which is incorrect.

Examples:

Configuration paths like /BGP_NEIGHBOR/ should apply only to the ASIC namespace.
Paths like /SYSLOG_SERVER/ should apply only to the localhost namespace.
This PR addresses the issue by introducing a missing flag for "asic_specific" configurations. It adapts the calls appropriately in each test suite based on the targeted configuration scope (ASIC namespace or localhost).

Approach
How did you verify/test it?
Ran vs-kvm tests.

Attaching sample results for test_portchannel.py and test_eth_interface.py:
  • Loading branch information
okaravasi authored Jan 27, 2025
1 parent e68b724 commit db2df14
Show file tree
Hide file tree
Showing 29 changed files with 389 additions and 211 deletions.
4 changes: 2 additions & 2 deletions tests/bgp/test_bgp_bbr.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def add_bbr_config_to_running_config(duthost, status):
}
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand All @@ -99,7 +99,7 @@ def config_bbr_by_gcu(duthost, status):
"value": "{}".format(status)
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down
4 changes: 2 additions & 2 deletions tests/bgp/test_bgp_dual_asn.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ def bgp_peer_range_add_config(
}
]

json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)
tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))

Expand Down Expand Up @@ -404,7 +404,7 @@ def bgp_peer_range_delete_config(
{"op": "remove", "path": "/BGP_PEER_RANGE/{}".format(ip_range_name)},
{"op": "remove", "path": "/BGP_PEER_RANGE/{}".format(ipv6_range_name)},
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down
79 changes: 61 additions & 18 deletions tests/common/gu_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
FILES_DIR = os.path.join(BASE_DIR, "files")
TMP_DIR = '/tmp'
HOST_NAME = "/localhost"
ASIC_PREFIX = "/asic"
HOST_NAME = "localhost"
ASIC_PREFIX = "asic"


def generate_tmpfile(duthost):
Expand All @@ -36,32 +36,75 @@ def delete_tmpfile(duthost, tmpfile):
duthost.file(path=tmpfile, state='absent')


def format_json_patch_for_multiasic(duthost, json_data, is_asic_specific=False):
if is_asic_specific:
return json_data
def format_json_patch_for_multiasic(duthost, json_data,
is_asic_specific=False,
is_host_specific=False,
asic_namespaces=None):
"""
Formats a JSON patch for multi-ASIC platforms based on the specified scope.
- Case 1: Apply changes only to /localhost namespace.
example: format_json_patch_for_multiasic(duthost, json_data, is_host_specific=True)
- Case 2: Apply changes only to all available ASIC namespaces (e.g., /asic0, /asic1).
example: format_json_patch_for_multiasic(duthost, json_data, is_asic_specific=True)
- Case 3: Apply changes to one specific ASIC namespace (e.g., /asic0).
example: format_json_patch_for_multiasic(duthost, json_data, is_asic_specific=True, asic_namespaces='asic0')
- Case 4: Apply changes to both /localhost and all ASIC namespaces.
example: format_json_patch_for_multiasic(duthost, json_data)
"""
json_patch = []
asic_namespaces = asic_namespaces or []

if duthost.is_multi_asic:
num_asic = duthost.facts.get('num_asic')

for operation in json_data:
path = operation["path"]
if path.startswith(HOST_NAME) and ASIC_PREFIX in path:
json_patch.append(operation)

# Case 1: Apply only to localhost
if is_host_specific:
if path.startswith(f"/{HOST_NAME}"):
json_patch.append(operation)
else:
template = operation.copy()
template["path"] = f"/{HOST_NAME}{path}"
json_patch.append(template)

# Case 2: Apply only to all ASIC namespaces
elif is_asic_specific and not asic_namespaces:
for asic_index in range(num_asic):
asic_ns = f"{ASIC_PREFIX}{asic_index}"
template = operation.copy()
template["path"] = f"/{asic_ns}{path}"
json_patch.append(template)

# Case 3: Apply to one specific ASIC namespace
elif asic_namespaces:
for asic_ns in asic_namespaces:
template = operation.copy()
template["path"] = f"/{asic_ns}{path}"
json_patch.append(template)

# Case 4: Apply to both localhost and all ASIC namespaces
else:
template = {
"op": operation["op"],
"path": "{}{}".format(HOST_NAME, path)
}

if operation["op"] in ["add", "replace", "test"]:
template["value"] = operation["value"]
json_patch.append(template.copy())
# Add for localhost
template = operation.copy()
template["path"] = f"/{HOST_NAME}{path}"
json_patch.append(template)

# Add for all ASIC namespaces
for asic_index in range(num_asic):
asic_ns = "{}{}".format(ASIC_PREFIX, asic_index)
template["path"] = "{}{}".format(asic_ns, path)
json_patch.append(template.copy())
asic_ns = f"{ASIC_PREFIX}{asic_index}"
template = operation.copy()
template["path"] = f"/{asic_ns}{path}"
json_patch.append(template)

json_data = json_patch
logger.debug("format_json_patch_for_multiasic: {}".format(json_data))

return json_data

Expand Down
17 changes: 13 additions & 4 deletions tests/common/helpers/dut_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,16 +312,25 @@ def verify_features_state(duthost):

def verify_orchagent_running_or_assert(duthost):
"""
Verifies that orchagent is running, asserts otherwise
Verifies that orchagent is running, asserts otherwise.
In case of multi-asic platforms verifies orchagent running for all the asic namespaces.
Args:
duthost: Device Under Test (DUT)
"""

def _orchagent_running():
cmds = 'docker exec swss supervisorctl status orchagent'
output = duthost.shell(cmds, module_ignore_errors=True)
pytest_assert(not output['rc'], "Unable to check orchagent status output")
if duthost.is_multi_asic:
num_asic = duthost.facts.get('num_asic')
for asic_index in range(num_asic):
cmd = 'docker exec swss{} supervisorctl status orchagent'.format(asic_index)
output = duthost.shell(cmd, module_ignore_errors=True)
pytest_assert(not output['rc'], "Unable to check orchagent status output for asic_id {}"
.format(asic_index))
else:
cmds = 'docker exec swss supervisorctl status orchagent'
output = duthost.shell(cmds, module_ignore_errors=True)
pytest_assert(not output['rc'], "Unable to check orchagent status output")
return 'RUNNING' in output['stdout']

pytest_assert(
Expand Down
6 changes: 4 additions & 2 deletions tests/generic_config_updater/gu_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ def format_and_apply_template(duthost, template_name, extra_vars, setup):
return outputs


def load_and_apply_json_patch(duthost, file_name, setup):
def load_and_apply_json_patch(duthost, file_name, setup, is_asic_specific=False, is_host_specific=False):
with open(os.path.join(TEMPLATES_DIR, file_name)) as file:
json_patch = json.load(file)

json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch,
is_asic_specific=is_asic_specific,
is_host_specific=is_host_specific)
duts_to_apply = [duthost]
outputs = []
if setup["is_dualtor"]:
Expand Down
26 changes: 13 additions & 13 deletions tests/generic_config_updater/test_aaa.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def aaa_tc1_add_config(duthost):
"value": aaa_config
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -208,7 +208,7 @@ def aaa_tc1_replace(duthost):
"value": "tacacs+"
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -246,7 +246,7 @@ def aaa_tc1_add_duplicate(duthost):
"value": "tacacs+"
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand All @@ -273,7 +273,7 @@ def aaa_tc1_remove(duthost):
"path": "/AAA"
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -318,7 +318,7 @@ def tacacs_global_tc2_add_config(duthost):
}
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)
tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))

Expand Down Expand Up @@ -358,7 +358,7 @@ def tacacs_global_tc2_invalid_input(duthost):
}
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)
tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))

Expand All @@ -382,7 +382,7 @@ def tacacs_global_tc2_duplicate_input(duthost):
}
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)
tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))

Expand All @@ -408,7 +408,7 @@ def tacacs_global_tc2_remove(duthost):
"path": "/TACPLUS"
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)
tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))

Expand Down Expand Up @@ -452,7 +452,7 @@ def tacacs_server_tc3_add_init(duthost):
}
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -491,7 +491,7 @@ def tacacs_server_tc3_add_max(duthost):
}
json_patch.append(patch)

json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)
tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))

Expand Down Expand Up @@ -532,7 +532,7 @@ def tacacs_server_tc3_replace_invalid(duthost):
}
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)
tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))

Expand All @@ -554,7 +554,7 @@ def tacacs_server_tc3_add_duplicate(duthost):
"value": TACACS_SERVER_OPTION
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand All @@ -579,7 +579,7 @@ def tacacs_server_tc3_remove(duthost):
"path": "/TACPLUS_SERVER"
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_host_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down
9 changes: 5 additions & 4 deletions tests/generic_config_updater/test_bgp_prefix.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ def bgp_prefix_tc1_add_config(duthost, community, community_table):
}
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)

json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -157,7 +158,7 @@ def bgp_prefix_tc1_xfail(duthost, community_table):
"value": prefixes_v4
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -185,7 +186,7 @@ def bgp_prefix_tc1_replace(duthost, community, community_table):
"value": PREFIXES_V4_DUMMY
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -219,7 +220,7 @@ def bgp_prefix_tc1_remove(duthost, community):
"path": "/BGP_ALLOWED_PREFIXES"
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down
8 changes: 4 additions & 4 deletions tests/generic_config_updater/test_bgp_sentinel.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def bgp_sentinel_tc1_add_config(duthost, lo_intf_ips):
}
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -170,7 +170,7 @@ def bgp_sentinel_tc1_add_dummy_ip_range(duthost):
"value": "{}".format(DUMMY_IP_RANGE_V6)
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -204,7 +204,7 @@ def bgp_sentinel_tc1_rm_dummy_ip_range(duthost):
"path": "/BGP_SENTINELS/{}/ip_range/1".format(BGPSENTINEL_V6)
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down Expand Up @@ -239,7 +239,7 @@ def bgp_sentinel_tc1_replace_src_address(duthost):
"value": "{}".format(DUMMY_SRC_ADDRESS_V6)
}
]
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch)
json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch, is_asic_specific=True)

tmpfile = generate_tmpfile(duthost)
logger.info("tmpfile {}".format(tmpfile))
Expand Down
Loading

0 comments on commit db2df14

Please sign in to comment.