Skip to content

Commit

Permalink
Handle RJ45 port when checking presence (sonic-net#5927)
Browse files Browse the repository at this point in the history
* Handle RJ45 port when checking presence

- Expose 'type' to show_interfaces
- Handle expected presence status differently between 'RJ45' and normal ports

Signed-off-by: Stephen Sun <stephens@nvidia.com>

* Leverage module "interface" to calculate number of RJ45 ports

Signed-off-by: Stephen Sun <stephens@nvidia.com>

Signed-off-by: Stephen Sun <stephens@nvidia.com>
  • Loading branch information
stephenxs authored and ms-junyi committed Oct 28, 2022
1 parent 3d2c18b commit 98c6702
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
22 changes: 20 additions & 2 deletions ansible/library/show_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"vlan": "routed"
"oper_state": "down"
"admin_state": "up"
"type": "QSFP28 or later"
}
}
ansible_facts:
Expand Down Expand Up @@ -97,6 +98,18 @@ def run(self):
self.collect_interface_counter(namespace, include_internal_intfs)
self.module.exit_json(ansible_facts=self.facts)

def _fetch_interface_type(self, line):
"""
Fetch the type from the line
There can be spaces in type field so we can not match it via using regular expression
The logic is to split the line into a list by spaces and the remove all the leading and tail elements, and then piece the rest together
Eg. for output "Ethernet48 192,193,194,195 100G 9100 N/A etp49 routed up up QSFP28 or later N/A"
the list is ['Ethernet48', '192,193,194,195', '100G', '9100', 'N/A', 'etp49', 'routed', 'up', 'up' 'QSFP28', 'or', 'later', 'N/A']
There is no space in the rest elements, so we can remove the first 9 and the last 1 elements, and piece 'QSFP28', 'or', 'later' together.
This function should be called on if regex_int_fec is matched.
"""
return ' '.join(line.split()[9:-1])

def collect_interface_status(self, namespace=None, include_internal_intfs=False):
regex_int_fec = re.compile(r'(\S+)\s+[\d,N\/A]+\s+(\w+)\s+(\d+)\s+(rs|fc|N\/A|none)\s+([\w\/]+)\s+(\w+)\s+(\w+)\s+(\w+)')
regex_int = re.compile(r'(\S+)\s+[\d,N\/A]+\s+(\w+)\s+(\d+)\s+([\w\/]+)\s+(\w+)\s+(\w+)\s+(\w+)')
Expand All @@ -120,6 +133,7 @@ def collect_interface_status(self, namespace=None, include_internal_intfs=False)
self.int_status[interface]['vlan'] = fec.group(6)
self.int_status[interface]['oper_state'] = fec.group(7)
self.int_status[interface]['admin_state'] = fec.group(8)
self.int_status[interface]['type'] = self._fetch_interface_type(line)
elif old and interface == old.group(1):
self.int_status[interface]['name'] = old.group(1)
self.int_status[interface]['speed'] = old.group(2)
Expand All @@ -128,7 +142,8 @@ def collect_interface_status(self, namespace=None, include_internal_intfs=False)
self.int_status[interface]['vlan'] = old.group(5)
self.int_status[interface]['oper_state'] = old.group(6)
self.int_status[interface]['admin_state'] = old.group(7)
self.facts['int_status'] = self.int_status
self.int_status[interface]['type'] = 'N/A'
self.facts['int_status'] = self.int_status
except Exception as e:
self.module.fail_json(msg=str(e))
if rc != 0:
Expand All @@ -155,6 +170,7 @@ def collect_interface_status(self, namespace=None, include_internal_intfs=False)
self.int_status[interface]['vlan'] = fec.group(6)
self.int_status[interface]['oper_state'] = fec.group(7)
self.int_status[interface]['admin_state'] = fec.group(8)
self.int_status[interface]['type'] = self._fetch_interface_type(line)
elif old:
interface = old.group(1)
self.int_status[interface] = {}
Expand All @@ -165,6 +181,7 @@ def collect_interface_status(self, namespace=None, include_internal_intfs=False)
self.int_status[interface]['vlan'] = old.group(5)
self.int_status[interface]['oper_state'] = old.group(6)
self.int_status[interface]['admin_state'] = old.group(7)
self.int_status[interface]['type'] = 'N/A'
elif internal and include_internal_intfs:
interface = internal.group(1)
self.int_status[interface] = {}
Expand All @@ -175,7 +192,8 @@ def collect_interface_status(self, namespace=None, include_internal_intfs=False)
self.int_status[interface]['vlan'] = internal.group(6)
self.int_status[interface]['oper_state'] = internal.group(7)
self.int_status[interface]['admin_state'] = internal.group(8)
self.facts['int_status'] = self.int_status
self.int_status[interface]['type'] = 'N/A'
self.facts['int_status'] = self.int_status
except Exception as e:
self.module.fail_json(msg=str(e))
if rc != 0:
Expand Down
5 changes: 4 additions & 1 deletion tests/platform_tests/api/test_chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,13 @@ def test_sfps(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platf

if duthost.facts.get("chassis"):
expected_num_sfps = len(duthost.facts.get("chassis").get('sfps'))
interface_facts = duthost.show_interface(command='status')['ansible_facts']['int_status']
if duthost.facts.get("platform") == 'x86_64-nvidia_sn2201-r0':
# On SN2201, there are 48 RJ45 ports which are also counted in SFP object lists
# So we need to adjust test case accordingly
expected_num_sfps += 48
for port,data in interface_facts.items():
if data['type'] == 'RJ45':
expected_num_sfps += 1
pytest_assert(num_sfps == expected_num_sfps,
"Number of sfps ({}) does not match expected number ({})"
.format(num_sfps, expected_num_sfps))
Expand Down

0 comments on commit 98c6702

Please sign in to comment.