Skip to content

Commit 239fd1e

Browse files
az-pzgshemesh2
authored andcommitted
Check DOM for only first subport for test_xcvr_info_in_db.py test. (sonic-net#19170)
* Check DOM for only first subport for test_xcvr_info_in_db.py test. * Get first subport for all logical ports. * Optimize the sonic db query. * Update assertion error message. * Xfail the failing test_retry_count test. Signed-off-by: Guy Shemesh <[email protected]>
1 parent c0cf136 commit 239fd1e

4 files changed

Lines changed: 96 additions & 28 deletions

File tree

tests/common/platform/interface_utils.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import re
88
import logging
99
import json
10+
from collections import defaultdict
1011
from natsort import natsorted
1112
from .transceiver_utils import all_transceivers_detected
1213

@@ -214,14 +215,19 @@ def get_physical_port_indices(duthost, logical_intfs=None):
214215
# Get interfaces of this asic
215216
interface_list = get_port_map(duthost, asic_index)
216217
interfaces_per_asic = {k: v for k, v in list(interface_list.items()) if k in logical_intfs}
217-
# logging.info("ASIC index={} interfaces = {}".format(asic_index, interfaces_per_asic))
218-
for intf in interfaces_per_asic:
219-
if asic_index is not None:
220-
cmd = 'sonic-db-cli -n asic{} CONFIG_DB HGET "PORT|{}" index'.format(asic_index, intf)
221-
else:
222-
cmd = 'sonic-db-cli CONFIG_DB HGET "PORT|{}" index'.format(intf)
223-
index = duthost.command(cmd)["stdout"]
224-
physical_port_index_dict[intf] = (int(index))
218+
logging.debug("ASIC index={} interfaces = {}".format(asic_index, interfaces_per_asic))
219+
asic_subcommand = f'-n asic{asic_index}' if asic_index is not None else ''
220+
cmd_keys = f'sonic-db-cli {asic_subcommand} CONFIG_DB KEYS "PORT|Ethernet*"'
221+
cmd_hget = f'sonic-db-cli {asic_subcommand} CONFIG_DB HGET $key index'
222+
cmd = f'for key in $({cmd_keys}); do echo "$key : $({cmd_hget})" ; done'
223+
cmd_out = duthost.command(cmd, _uses_shell=True)["stdout_lines"]
224+
cmd_out_dict = {}
225+
for line in cmd_out:
226+
key, index = line.split(':')
227+
intf_name = key.split('|')[1].strip()
228+
cmd_out_dict[intf_name] = int(index.strip())
229+
for logical_intf in logical_intfs:
230+
physical_port_index_dict[logical_intf] = cmd_out_dict.get(logical_intf, None)
225231

226232
return physical_port_index_dict
227233

@@ -282,3 +288,25 @@ def get_fec_eligible_interfaces(duthost, supported_speeds):
282288
logging.info(f"Skip for {intf_name}: oper_state:{oper} speed:{speed}")
283289

284290
return interfaces
291+
292+
293+
def get_physical_to_logical_port_mapping(physical_port_indices):
294+
"""
295+
@summary: Returns dictionary map of physical ports to corresponding logical port indices
296+
"""
297+
pport_to_lport_mapping = defaultdict(list)
298+
for k, v in physical_port_indices.items():
299+
pport_to_lport_mapping[v].append(k)
300+
logging.debug("Physical to Logical Port Mapping: {}".format(pport_to_lport_mapping))
301+
return pport_to_lport_mapping
302+
303+
304+
def get_lport_to_first_subport_mapping(duthost, logical_intfs=None):
305+
"""
306+
@summary: Returns the first subport of logical ports.
307+
"""
308+
physical_port_indices = get_physical_port_indices(duthost, logical_intfs)
309+
pport_to_lport_mapping = get_physical_to_logical_port_mapping(physical_port_indices)
310+
first_subport_dict = {k: pport_to_lport_mapping[v][0] for k, v in physical_port_indices.items()}
311+
logging.debug("First subports mapping: {}".format(first_subport_dict))
312+
return first_subport_dict

tests/common/platform/transceiver_utils.py

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,29 @@ def check_transceiver_details(dut, asic_index, interfaces, xcvr_skip_list):
8888
else:
8989
expected_fields = ["type", "vendor_rev", "serial", "manufacturer", "model"]
9090

91+
cmd_keys = 'sonic-db-cli STATE_DB KEYS "TRANSCEIVER_INFO|Ethernet*"'
92+
cmd_hgetall = 'sonic-db-cli STATE_DB HGETALL $key'
93+
docker_cmd_keys = asichost.get_docker_cmd(cmd_keys, "database")
94+
docker_cmd_hgetall = asichost.get_docker_cmd(cmd_hgetall, "database")
95+
96+
docker_cmd = f'for key in $({docker_cmd_keys}); do echo "$key : $({docker_cmd_hgetall})" ; done'
97+
port_xcvr_info = dut.command(docker_cmd, _uses_shell=True)
98+
port_xcvr_info_dict = {}
99+
for line in port_xcvr_info["stdout_lines"]:
100+
key, value = line.split(":", 1)
101+
intf_name = key.split('|')[1].strip()
102+
port_xcvr_info_dict[intf_name] = value.strip()
103+
91104
for intf in interfaces:
92105
if intf not in xcvr_skip_list[dut.hostname]:
93-
cmd = 'redis-cli -n 6 hgetall "TRANSCEIVER_INFO|%s"' % intf
94-
docker_cmd = asichost.get_docker_cmd(cmd, "database")
95-
port_xcvr_info = dut.command(docker_cmd)
106+
port_xcvr_info_value = port_xcvr_info_dict[intf]
96107
for field in expected_fields:
97-
assert port_xcvr_info["stdout"].find(field) >= 0, \
98-
"Expected field %s is not found in %s while checking %s" % (field, port_xcvr_info["stdout"], intf)
108+
assert port_xcvr_info_value.find(field) >= 0, \
109+
"Expected field %s is not found in %s while checking %s" % (field, port_xcvr_info_value, intf)
99110

100111

101-
def check_transceiver_dom_sensor_basic(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory):
112+
def check_transceiver_dom_sensor_basic(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory,
113+
lport_to_first_subport_mapping):
102114
"""
103115
@summary: Check whether all the specified interface are in TRANSCEIVER_DOM_SENSOR redis DB.
104116
@param dut: The AnsibleHost object of DUT. For interacting with DUT.
@@ -112,10 +124,13 @@ def check_transceiver_dom_sensor_basic(dut, asic_index, interfaces, xcvr_skip_li
112124
parsed_xcvr_dom_sensor = parse_transceiver_dom_sensor(xcvr_dom_sensor["stdout_lines"])
113125
for intf in interfaces:
114126
if intf not in xcvr_skip_list[dut.hostname] + port_list_with_flat_memory[dut.hostname]:
115-
assert intf in parsed_xcvr_dom_sensor, "TRANSCEIVER_DOM_SENSOR of %s is not found in DB" % intf
127+
assert lport_to_first_subport_mapping[intf] in parsed_xcvr_dom_sensor,\
128+
"TRANSCEIVER_DOM_SENSOR of subport %s of %s port is not found in DB" \
129+
% (lport_to_first_subport_mapping[intf], intf)
116130

117131

118-
def check_transceiver_dom_sensor_details(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory):
132+
def check_transceiver_dom_sensor_details(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory,
133+
lport_to_first_subport_mapping):
119134
"""
120135
@summary: Check the detailed TRANSCEIVER_DOM_SENSOR content of all the specified interfaces.
121136
@param dut: The AnsibleHost object of DUT. For interacting with DUT.
@@ -125,27 +140,44 @@ def check_transceiver_dom_sensor_details(dut, asic_index, interfaces, xcvr_skip_
125140
asichost = dut.asic_instance(asic_index)
126141
expected_fields = ["temperature", "voltage", "rx1power", "rx2power", "rx3power", "rx4power", "tx1bias",
127142
"tx2bias", "tx3bias", "tx4bias", "tx1power", "tx2power", "tx3power", "tx4power"]
143+
144+
cmd_keys = 'sonic-db-cli STATE_DB KEYS "TRANSCEIVER_DOM_SENSOR|Ethernet*"'
145+
cmd_hgetall = 'sonic-db-cli STATE_DB HGETALL $key'
146+
docker_cmd_keys = asichost.get_docker_cmd(cmd_keys, "database")
147+
docker_cmd_hgetall = asichost.get_docker_cmd(cmd_hgetall, "database")
148+
149+
docker_cmd = f'for key in $({docker_cmd_keys}); do echo "$key : $({docker_cmd_hgetall})" ; done'
150+
port_xcvr_dom_sensor = dut.command(docker_cmd, _uses_shell=True)
151+
152+
port_xcvr_dom_dict = {}
153+
for line in port_xcvr_dom_sensor["stdout_lines"]:
154+
key, value = line.split(":", 1)
155+
intf_name = key.split('|')[1].strip()
156+
port_xcvr_dom_dict[intf_name] = value.strip()
157+
128158
for intf in interfaces:
129159
if intf not in xcvr_skip_list[dut.hostname] + port_list_with_flat_memory[dut.hostname]:
130-
cmd = 'redis-cli -n 6 hgetall "TRANSCEIVER_DOM_SENSOR|%s"' % intf
131-
docker_cmd = asichost.get_docker_cmd(cmd, "database")
132-
port_xcvr_dom_sensor = dut.command(docker_cmd)
160+
first_subport = lport_to_first_subport_mapping[intf]
161+
port_xcvr_dom_value = port_xcvr_dom_dict[first_subport]
133162
for field in expected_fields:
134-
assert port_xcvr_dom_sensor["stdout"].find(field) >= 0, \
163+
assert port_xcvr_dom_value.find(field) >= 0, \
135164
"Expected field %s is not found in %s while checking %s" % (
136-
field, port_xcvr_dom_sensor["stdout"], intf)
165+
field, port_xcvr_dom_value, intf)
137166

138167

139-
def check_transceiver_status(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory):
168+
def check_transceiver_status(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory,
169+
lport_to_first_subport_mapping):
140170
"""
141171
@summary: Check transceiver information of all the specified interfaces in redis DB.
142172
@param dut: The AnsibleHost object of DUT. For interacting with DUT.
143173
@param interfaces: List of interfaces that need to be checked.
144174
"""
145175
check_transceiver_basic(dut, asic_index, interfaces, xcvr_skip_list)
146176
check_transceiver_details(dut, asic_index, interfaces, xcvr_skip_list)
147-
check_transceiver_dom_sensor_basic(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory)
148-
check_transceiver_dom_sensor_details(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory)
177+
check_transceiver_dom_sensor_basic(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory,
178+
lport_to_first_subport_mapping)
179+
check_transceiver_dom_sensor_details(dut, asic_index, interfaces, xcvr_skip_list, port_list_with_flat_memory,
180+
lport_to_first_subport_mapping)
149181

150182

151183
def get_sfp_eeprom_map_per_port(eeprom_infos):

tests/common/plugins/conditional_mark/tests_mark_conditions.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,6 +2155,12 @@ pc/test_po_voq.py:
21552155
conditions:
21562156
- "'t2' not in topo_name or num_asic == 0 or len(minigraph_portchannels[list(minigraph_portchannels.keys())[0]]['members']) == 0 or asic_type in ['cisco-8000']"
21572157

2158+
pc/test_retry_count.py::test_retry_count:
2159+
xfail:
2160+
reason: "Test set up is failing. Need owner to fix it."
2161+
conditions:
2162+
- "https://github.com/sonic-net/sonic-mgmt/issues/19400"
2163+
21582164
#######################################
21592165
##### pfc #####
21602166
#######################################

tests/platform_tests/test_xcvr_info_in_db.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import logging
88
import pytest
99
from tests.common.platform.transceiver_utils import check_transceiver_status
10-
from tests.common.platform.interface_utils import get_port_map
11-
from tests.common.fixtures.conn_graph_facts import conn_graph_facts # noqa: F401
10+
from tests.common.platform.interface_utils import get_port_map, get_lport_to_first_subport_mapping
11+
from tests.common.fixtures.conn_graph_facts import conn_graph_facts # noqa F401
1212

1313
pytestmark = [
1414
pytest.mark.topology('any')
@@ -35,5 +35,7 @@ def test_xcvr_info_in_db(duthosts, enum_rand_one_per_hwsku_frontend_hostname,
3535
logging.info("ASIC {} interface_list {}".format(
3636
enum_frontend_asic_index, all_interfaces))
3737

38-
check_transceiver_status(
39-
duthost, enum_frontend_asic_index, all_interfaces, xcvr_skip_list, port_list_with_flat_memory)
38+
# Get the first subport of the logical port since DOM is returned only for first subport.
39+
lport_to_first_subport_mapping = get_lport_to_first_subport_mapping(duthost, all_interfaces)
40+
check_transceiver_status(duthost, enum_frontend_asic_index, all_interfaces, xcvr_skip_list,
41+
port_list_with_flat_memory, lport_to_first_subport_mapping)

0 commit comments

Comments
 (0)