Skip to content

Commit 981f953

Browse files
authored
[chassis][voq] Add "show fabric reachability" command. (sonic-net#2528)
What I did Added "show fabric reachability" command. The output of this command : Local Link Remote Module Remote Link Status ------------ --------------- ------------- -------- 0 304 171 up 1 304 156 up 2 304 147 up Added test for the change at tests/fabricstat_test.py. The test is at sonic-net/sonic-mgmt#6620
1 parent fba87f4 commit 981f953

File tree

3 files changed

+93
-1
lines changed

3 files changed

+93
-1
lines changed

scripts/fabricstat

+37-1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,33 @@ class FabricQueueStat(FabricStat):
178178
print(tabulate(table, queuestat_header, tablefmt='simple', stralign='right'))
179179
print()
180180

181+
class FabricReachability(FabricStat):
182+
def reachability_print(self):
183+
# Connect to database
184+
self.db = multi_asic.connect_to_all_dbs_for_ns(self.namespace)
185+
# Get the set of all fabric port keys
186+
port_keys = self.db.keys(self.db.STATE_DB, FABRIC_PORT_STATUS_TABLE_PREFIX + '*')
187+
# Create a new dictionary. The key values are the local port values
188+
# in integer format. Only ports that have remote port data are added.
189+
# Only ports that are "up" will be connected to a remote peer.
190+
port_dict = {}
191+
for port_key in port_keys:
192+
port_data = self.db.get_all(self.db.STATE_DB, port_key)
193+
if "REMOTE_PORT" in port_data:
194+
port_number = int(port_key.replace("FABRIC_PORT_TABLE|PORT", ""))
195+
port_dict.update({port_number: port_data})
196+
# Create ordered table of port data
197+
header = ["Local Link", "Remote Module", "Remote Link", "Status"]
198+
body = []
199+
for port_number in sorted(port_dict.keys()):
200+
port_data = port_dict[port_number]
201+
body.append((port_number, port_data["REMOTE_MOD"], \
202+
port_data["REMOTE_PORT"], port_data["STATUS"]))
203+
if self.namespace:
204+
print(f"\n{self.namespace}")
205+
print(tabulate(body, header, tablefmt='simple', stralign='right'))
206+
return
207+
181208
def main():
182209
parser = argparse.ArgumentParser(description='Display the fabric port state and counters',
183210
formatter_class=argparse.RawTextHelpFormatter,
@@ -191,16 +218,25 @@ Examples:
191218
""")
192219

193220
parser.add_argument('-q','--queue', action='store_true', help='Display fabric queue stat, otherwise port stat')
221+
parser.add_argument('-r','--reachability', action='store_true', help='Display reachability, otherwise port stat')
194222
parser.add_argument('-n','--namespace', default=None, help='Display fabric ports counters for specific namespace')
195223
parser.add_argument('-e', '--errors', action='store_true', help='Display errors')
196224

197225
args = parser.parse_args()
198226
queue = args.queue
227+
reachability = args.reachability
199228
namespace = args.namespace
200229
errors_only = args.errors
201230

202231
def nsStat(ns, errors_only):
203-
stat = FabricQueueStat(ns) if queue else FabricPortStat(ns)
232+
if queue:
233+
stat = FabricQueueStat(ns)
234+
elif reachability:
235+
stat = FabricReachability(ns)
236+
stat.reachability_print()
237+
return
238+
else:
239+
stat = FabricPortStat(ns)
204240
cnstat_dict = stat.get_cnstat_dict()
205241
stat.cnstat_print(cnstat_dict, errors_only)
206242

show/fabric.py

+12
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ def counters():
1313
"""Show fabric port counters"""
1414
pass
1515

16+
@fabric.group(invoke_without_command=True)
17+
@multi_asic_util.multi_asic_click_option_namespace
18+
@click.option('-e', '--errors', is_flag=True)
19+
def reachability(namespace, errors):
20+
"""Show fabric reachability"""
21+
cmd = "fabricstat -r"
22+
if namespace is not None:
23+
cmd += " -n {}".format(namespace)
24+
if errors:
25+
cmd += " -e"
26+
clicommon.run_command(cmd)
27+
1628
@counters.command()
1729
@multi_asic_util.multi_asic_click_option_namespace
1830
@click.option('-e', '--errors', is_flag=True)

tests/fabricstat_test.py

+44
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,36 @@
9090
9191
"""
9292

93+
multi_asic_fabric_reachability = """\
94+
95+
asic0
96+
Local Link Remote Module Remote Link Status
97+
------------ --------------- ------------- --------
98+
0 0 79 up
99+
2 0 94 up
100+
4 0 85 up
101+
6 0 84 up
102+
7 0 93 up
103+
104+
asic1
105+
Local Link Remote Module Remote Link Status
106+
------------ --------------- ------------- --------
107+
0 0 69 up
108+
4 0 75 up
109+
"""
110+
111+
multi_asic_fabric_reachability_asic0 = """\
112+
113+
asic0
114+
Local Link Remote Module Remote Link Status
115+
------------ --------------- ------------- --------
116+
0 0 79 up
117+
2 0 94 up
118+
4 0 85 up
119+
6 0 84 up
120+
7 0 93 up
121+
"""
122+
93123
class TestMultiAsicFabricStat(object):
94124
@classmethod
95125
def setup_class(cls):
@@ -133,6 +163,20 @@ def test_multi_show_fabric_counters_queue_asic(self):
133163
assert return_code == 0
134164
assert result == multi_asic_fabric_counters_queue_asic0
135165

166+
def test_multi_show_fabric_reachability(self):
167+
return_code, result = get_result_and_return_code('fabricstat -r')
168+
print("return_code: {}".format(return_code))
169+
print("result = {}".format(result))
170+
assert return_code == 0
171+
assert result == multi_asic_fabric_reachability
172+
173+
def test_multi_show_fabric_reachability_asic(self):
174+
return_code, result = get_result_and_return_code('fabricstat -r -n asic0')
175+
print("return_code: {}".format(return_code))
176+
print("result = {}".format(result))
177+
assert return_code == 0
178+
assert result == multi_asic_fabric_reachability_asic0
179+
136180
@classmethod
137181
def teardown_class(cls):
138182
print("TEARDOWN")

0 commit comments

Comments
 (0)