Skip to content

Commit

Permalink
[show] Add subcommand to show midplane status for modular chassis (#1267
Browse files Browse the repository at this point in the history
)

Add subcommand to show midplane status for modular chassis and related unit tests
  • Loading branch information
mprabhu-nokia authored Jan 12, 2021
1 parent dba8fcb commit be7cac5
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 3 deletions.
47 changes: 44 additions & 3 deletions show/chassis_modules.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import click
from natsort import natsorted
from tabulate import tabulate
from swsssdk import SonicV2Connector
from swsscommon.swsscommon import SonicV2Connector

import utilities_common.cli as clicommon

Expand All @@ -12,6 +12,10 @@
CHASSIS_MODULE_INFO_OPERSTATUS_FIELD = 'oper_status'
CHASSIS_MODULE_INFO_ADMINSTATUS_FIELD = 'admin_status'

CHASSIS_MIDPLANE_INFO_TABLE = 'CHASSIS_MIDPLANE_TABLE'
CHASSIS_MIDPLANE_INFO_IP_FIELD = 'ip_address'
CHASSIS_MIDPLANE_INFO_ACCESS_FIELD = 'access'

@click.group(cls=clicommon.AliasedGroup)
def chassis_modules():
"""Show chassis-modules information"""
Expand All @@ -31,7 +35,7 @@ def status(db, chassis_module_name):

key_pattern = '*'
if chassis_module_name:
key_pattern = '|'+chassis_module_name
key_pattern = '|' + chassis_module_name

keys = state_db.keys(state_db.STATE_DB, CHASSIS_MODULE_INFO_TABLE + key_pattern)
if not keys:
Expand All @@ -41,7 +45,7 @@ def status(db, chassis_module_name):
table = []
for key in natsorted(keys):
key_list = key.split('|')
if len(key_list) != 2: # error data in DB, log it and ignore
if len(key_list) != 2: # error data in DB, log it and ignore
print('Warn: Invalid Key {} in {} table'.format(key, CHASSIS_MODULE_INFO_TABLE))
continue

Expand All @@ -61,3 +65,40 @@ def status(db, chassis_module_name):
click.echo(tabulate(table, header, tablefmt='simple', stralign='right'))
else:
click.echo('No data available in CHASSIS_MODULE_TABLE\n')

@chassis_modules.command()
@click.argument('chassis_module_name', metavar='<module_name>', required=False)
def midplane_status(chassis_module_name):
"""Show chassis-modules midplane-status"""

header = ['Name', 'IP-Address', 'Reachability']

state_db = SonicV2Connector(host="127.0.0.1")
state_db.connect(state_db.STATE_DB)

key_pattern = '*'
if chassis_module_name:
key_pattern = '|' + chassis_module_name

keys = state_db.keys(state_db.STATE_DB, CHASSIS_MIDPLANE_INFO_TABLE + key_pattern)
if not keys:
print('Key {} not found in {} table'.format(key_pattern, CHASSIS_MIDPLANE_INFO_TABLE))
return

table = []
for key in natsorted(keys):
key_list = key.split('|')
if len(key_list) != 2: # error data in DB, log it and ignore
print('Warn: Invalid Key {} in {} table'.format(key, CHASSIS_MIDPLANE_INFO_TABLE))
continue

data_dict = state_db.get_all(state_db.STATE_DB, key)
ip = data_dict[CHASSIS_MIDPLANE_INFO_IP_FIELD]
access = data_dict[CHASSIS_MIDPLANE_INFO_ACCESS_FIELD]

table.append((key_list[1], ip, access))

if table:
click.echo(tabulate(table, header, tablefmt='simple', stralign='right'))
else:
click.echo('No data available in CHASSIS_MIDPLANE_TABLE\n')
67 changes: 67 additions & 0 deletions tests/chassis_modules_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,36 @@
header_lines = 2
warning_lines = 0

show_chassis_modules_output="""\
Name Description Physical-Slot Oper-Status Admin-Status
------------ --------------- --------------- ------------- --------------
FABRIC-CARD0 fabric-card 17 Online up
FABRIC-CARD1 fabric-card 18 Offline up
LINE-CARD0 line-card 1 Empty up
LINE-CARD1 line-card 2 Online down
SUPERVISOR0 supervisor-card 16 Online up
"""

show_chassis_midplane_output="""\
Name IP-Address Reachability
----------- ------------- --------------
LINE-CARD0 192.168.1.1 True
LINE-CARD1 192.168.1.2 False
SUPERVISOR0 192.168.1.100 True
"""

class TestChassisModules(object):
@classmethod
def setup_class(cls):
print("SETUP")
os.environ["UTILITIES_UNIT_TESTING"] = "1"

def test_show_and_verify_output(self):
runner = CliRunner()
result = runner.invoke(show.cli.commands["chassis-modules"].commands["status"], [])
print(result.output)
assert(result.output == show_chassis_modules_output)

def test_show_all_count_lines(self):
runner = CliRunner()
result = runner.invoke(show.cli.commands["chassis-modules"].commands["status"], [])
Expand Down Expand Up @@ -112,6 +136,49 @@ def test_config_incorrect_module(self):
print(result.output)
assert result.exit_code != 0

def test_show_and_verify_midplane_output(self):
runner = CliRunner()
result = runner.invoke(show.cli.commands["chassis-modules"].commands["midplane-status"], [])
print(result.output)
assert(result.output == show_chassis_midplane_output)

def test_midplane_show_all_count_lines(self):
runner = CliRunner()
result = runner.invoke(show.cli.commands["chassis-modules"].commands["midplane-status"], [])
print(result.output)
result_lines = result.output.strip('\n').split('\n')
modules = ["LINE-CARD0", "LINE-CARD1", "SUPERVISOR0"]
for i, module in enumerate(modules):
assert module in result_lines[i + warning_lines + header_lines]
assert len(result_lines) == warning_lines + header_lines + len(modules)

def test_midplane_show_single_count_lines(self):
runner = CliRunner()
result = runner.invoke(show.cli.commands["chassis-modules"].commands["midplane-status"], ["LINE-CARD0"])
print(result.output)
result_lines = result.output.strip('\n').split('\n')
modules = ["LINE-CARD0"]
for i, module in enumerate(modules):
assert module in result_lines[i+header_lines]
assert len(result_lines) == header_lines + len(modules)

def test_midplane_show_module_down(self):
runner = CliRunner()
result = runner.invoke(show.cli.commands["chassis-modules"].commands["midplane-status"], ["LINE-CARD1"])
print(result.output)
result_lines = result.output.strip('\n').split('\n')
assert result.exit_code == 0
result_out = (result_lines[header_lines]).split()
print(result_out)
assert result_out[2] == 'False'

def test_midplane_show_incorrect_module(self):
runner = CliRunner()
result = runner.invoke(show.cli.commands["chassis-modules"].commands["midplane-status"], ["TEST-CARD1"])
print(result.output)
print(result.exit_code)
assert result.exit_code == 0

@classmethod
def teardown_class(cls):
print("TEARDOWN")
Expand Down
12 changes: 12 additions & 0 deletions tests/mock_tables/state_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -377,5 +377,17 @@
"xon": "18432",
"xoff": "32768",
"size": "51200"
},
"CHASSIS_MIDPLANE_TABLE|SUPERVISOR0": {
"ip_address": "192.168.1.100",
"access": "True"
},
"CHASSIS_MIDPLANE_TABLE|LINE-CARD0": {
"ip_address": "192.168.1.1",
"access": "True"
},
"CHASSIS_MIDPLANE_TABLE|LINE-CARD1": {
"ip_address": "192.168.1.2",
"access": "False"
}
}

0 comments on commit be7cac5

Please sign in to comment.