Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[show][muxcable] add support for show mux firmware version all #2441

Merged
merged 14 commits into from
Oct 21, 2022
110 changes: 108 additions & 2 deletions show/muxcable.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

import json
import sys
import time
Expand Down Expand Up @@ -97,6 +98,51 @@ def check_port_in_mux_cable_table(port):
return False



def get_per_port_firmware(port):

state_db = {}
mux_info_dict = {}
mux_info_full_dict = {}

# Getting all front asic namespace and correspding config and state DB connector

namespaces = multi_asic.get_front_end_namespaces()
for namespace in namespaces:
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
state_db[asic_id] = swsscommon.SonicV2Connector(use_unix_socket_path=False, namespace=namespace)
state_db[asic_id].connect(state_db[asic_id].STATE_DB)

if platform_sfputil is not None:
asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)

if asic_index is None:
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
# is fully mocked
import sonic_platform_base.sonic_sfp.sfputilhelper
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
if asic_index is None:
click.echo("Got invalid asic index for port {}, cant retrieve mux cable table entries".format(port))
return False


mux_info_full_dict[asic_index] = state_db[asic_index].get_all(
state_db[asic_index].STATE_DB, 'MUX_CABLE_INFO|{}'.format(port))

res_dir = {}
res_dir = mux_info_full_dict[asic_index]
mux_info_dict["version_nic_active"] = res_dir.get("version_nic_active", None)
mux_info_dict["version_nic_inactive"] = res_dir.get("version_nic_inactive", None)
mux_info_dict["version_nic_next"] = res_dir.get("version_nic_next", None)
mux_info_dict["version_peer_active"] = res_dir.get("version_peer_active", None)
mux_info_dict["version_peer_inactive"] = res_dir.get("version_peer_inactive", None)
mux_info_dict["version_peer_next"] = res_dir.get("version_peer_next", None)
mux_info_dict["version_self_active"] = res_dir.get("version_self_active", None)
mux_info_dict["version_self_inactive"] = res_dir.get("version_self_inactive", None)
mux_info_dict["version_self_next"] = res_dir.get("version_self_next", None)

return mux_info_dict

def get_response_for_version(port, mux_info_dict):
state_db = {}
xcvrd_show_fw_res_tbl = {}
Expand Down Expand Up @@ -1528,7 +1574,7 @@ def version(db, port, active):
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_FW_RSP")
delete_all_keys_in_db_table("STATE_DB", "XCVRD_SHOW_FW_RES")

if port is not None:
if port is not None and port != "all":

res_dict = {}
mux_info_dict, mux_info_active_dict = {}, {}
Expand Down Expand Up @@ -1561,6 +1607,65 @@ def version(db, port, active):
click.echo("{}".format(json.dumps(mux_info_active_dict, indent=4)))
else:
click.echo("{}".format(json.dumps(mux_info_dict, indent=4)))

elif port == "all" and port is not None:

logical_port_list = platform_sfputil_helper.get_logical_list()

rc_exit = True

for port in logical_port_list:

if platform_sfputil is not None:
physical_port_list = platform_sfputil_helper.logical_port_name_to_physical_port_list(port)

if not isinstance(physical_port_list, list):
continue
if len(physical_port_list) != 1:
continue

if not check_port_in_mux_cable_table(port):
continue

physical_port = physical_port_list[0]

logical_port_list_for_physical_port = platform_sfputil_helper.get_physical_to_logical()

logical_port_list_per_port = logical_port_list_for_physical_port.get(physical_port, None)

""" This check is required for checking whether or not this logical port is the one which is
actually mapped to physical port and by convention it is always the first port.
TODO: this should be removed with more logic to check which logical port maps to actual physical port
being used"""

if port != logical_port_list_per_port[0]:
continue


port = platform_sfputil_helper.get_interface_alias(port, db)

mux_info_dict = get_per_port_firmware(port)
if not isinstance(mux_info_dict, dict):
mux_info_dict = {}
rc_exit = False

mux_info = {}
mux_info_active_dict = {}
if active is True:
for key in mux_info_dict:
if key.endswith("_active"):
mux_info_active_dict[key] = mux_info_dict[key]
mux_info[port] = mux_info_active_dict
click.echo("{}".format(json.dumps(mux_info, indent=4)))
else:
mux_info[port] = mux_info_dict
click.echo("{}".format(json.dumps(mux_info, indent=4)))

if rc_exit == False:
sys.exit(EXIT_FAIL)

sys.exit(CONFIG_SUCCESSFUL)

else:
port_name = platform_sfputil_helper.get_interface_name(port, db)
click.echo("Did not get a valid Port for mux firmware version".format(port_name))
Expand Down Expand Up @@ -1640,6 +1745,7 @@ def metrics(db, port, json_output):
def event_log(db, port, json_output):
"""Show muxcable event log <port>"""

click.confirm(('Muxcable at port {} will retreive cable logs from MCU, Caution: approx wait time could be ~2 minutes Continue?'.format(port)), abort=True)
port = platform_sfputil_helper.get_interface_name(port, db)
delete_all_keys_in_db_table("APPL_DB", "XCVRD_EVENT_LOG_CMD")
delete_all_keys_in_db_table("STATE_DB", "XCVRD_EVENT_LOG_RSP")
Expand Down Expand Up @@ -1735,7 +1841,7 @@ def packetloss(db, port, json_output):
for namespace in namespaces:
asic_id = multi_asic.get_asic_index_from_namespace(namespace)

per_npu_statedb[asic_id] = swsscommon.SonicV2Connector(use_unix_socket_path=True, namespace=namespace)
per_npu_statedb[asic_id] = swsscommon.SonicV2Connector(use_unix_socket_path=False, namespace=namespace)
per_npu_statedb[asic_id].connect(per_npu_statedb[asic_id].STATE_DB)

pckloss_table_keys[asic_id] = per_npu_statedb[asic_id].keys(
Expand Down
24 changes: 24 additions & 0 deletions tests/mock_tables/state_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,30 @@
"Name": "CRC-32",
"Value": "0xAC518FB3"
},
"MUX_CABLE_INFO|Ethernet0": {
"version_peer_next": "0.2MS",
"version_peer_active": "0.2MS",
"version_peer_inactive": "0.2MS",
"version_nic_next": "0.2MS",
"version_nic_active": "0.2MS",
"version_nic_inactive": "0.2MS",
"version_self_next": "0.2MS",
"version_self_active": "0.2MS",
"version_self_inactive": "0.2MS",
"Value": "AABB"
},
"MUX_CABLE_INFO|Ethernet12": {
"version_peer_next": "0.1MS",
"version_peer_active": "0.1MS",
"version_peer_inactive": "0.1MS",
"version_nic_next": "0.1MS",
"version_nic_active": "0.1MS",
"version_nic_inactive": "0.1MS",
"version_self_next": "0.1MS",
"version_self_active": "0.1MS",
"version_self_inactive": "0.1MS",
"Value": "AABB"
},
"SWITCH_CAPABILITY|switch": {
"MIRROR": "true",
"MIRRORV6": "true",
Expand Down
89 changes: 89 additions & 0 deletions tests/muxcable_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,34 @@
}
"""

show_muxcable_firmware_version_all_expected_output = """\
{
"Ethernet12": {
"version_nic_active": "0.1MS",
"version_nic_inactive": "0.1MS",
"version_nic_next": "0.1MS",
"version_peer_active": "0.1MS",
"version_peer_inactive": "0.1MS",
"version_peer_next": "0.1MS",
"version_self_active": "0.1MS",
"version_self_inactive": "0.1MS",
"version_self_next": "0.1MS"
}
}
"""

show_muxcable_firmware_version_all_active_expected_output = """\
{
"Ethernet12": {
"version_nic_active": "0.1MS",
"version_peer_active": "0.1MS",
"version_self_active": "0.1MS"
}
}
"""



show_muxcable_firmware_version_active_expected_output = """\
{
"version_self_active": "0.6MS",
Expand Down Expand Up @@ -980,6 +1008,7 @@ def test_show_mux_fecstatistics(self):
assert result.exit_code == 0


@mock.patch('click.confirm', mock.MagicMock(return_value=("y")))
@mock.patch('show.muxcable.delete_all_keys_in_db_table', mock.MagicMock(return_value=0))
@mock.patch('show.muxcable.update_and_get_response_for_xcvr_cmd', mock.MagicMock(return_value={0: 0,
1: "True"}))
Expand Down Expand Up @@ -1428,6 +1457,66 @@ def test_show_muxcable_firmware_version(self):
assert result.exit_code == 0
assert result.output == show_muxcable_firmware_version_expected_output


@mock.patch('show.muxcable.delete_all_keys_in_db_table', mock.MagicMock(return_value=0))
@mock.patch('show.muxcable.update_and_get_response_for_xcvr_cmd', mock.MagicMock(return_value={0: 0,
1: "True"}))
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
@mock.patch('utilities_common.platform_sfputil_helper.get_asic_id_for_logical_port', mock.MagicMock(return_value=0))
@mock.patch('show.muxcable.platform_sfputil', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
@mock.patch('utilities_common.platform_sfputil_helper.get_physical_to_logical', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
@mock.patch('utilities_common.platform_sfputil_helper.logical_port_name_to_physical_port_list', mock.MagicMock(return_value=[0]))
def test_show_muxcable_firmware_version_all(self):
runner = CliRunner()
db = Db()

result = runner.invoke(show.cli.commands["muxcable"].commands["firmware"].commands["version"], [
"all"], obj=db)
assert result.exit_code == 0
f = open("newfile", "w")
f.write(result.output)
assert result.output == show_muxcable_firmware_version_all_expected_output


@mock.patch('show.muxcable.delete_all_keys_in_db_table', mock.MagicMock(return_value=0))
@mock.patch('show.muxcable.update_and_get_response_for_xcvr_cmd', mock.MagicMock(return_value={0: 0,
1: "True"}))
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
@mock.patch('utilities_common.platform_sfputil_helper.get_asic_id_for_logical_port', mock.MagicMock(return_value=0))
@mock.patch('show.muxcable.platform_sfputil', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
@mock.patch('utilities_common.platform_sfputil_helper.get_physical_to_logical', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
@mock.patch('utilities_common.platform_sfputil_helper.logical_port_name_to_physical_port_list', mock.MagicMock(return_value=[0]))
def test_show_muxcable_firmware_version_all_active(self):
runner = CliRunner()
db = Db()

result = runner.invoke(show.cli.commands["muxcable"].commands["firmware"].commands["version"], [
"all", "--active"], obj=db)
assert result.exit_code == 0
f = open("newfile", "w")
f.write(result.output)
assert result.output == show_muxcable_firmware_version_all_active_expected_output

@mock.patch('show.muxcable.delete_all_keys_in_db_table', mock.MagicMock(return_value=0))
@mock.patch('show.muxcable.update_and_get_response_for_xcvr_cmd', mock.MagicMock(return_value={0: 0,
1: "True"}))
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
@mock.patch('utilities_common.platform_sfputil_helper.get_asic_id_for_logical_port', mock.MagicMock(return_value=1))
@mock.patch('show.muxcable.platform_sfputil', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
@mock.patch('utilities_common.platform_sfputil_helper.get_physical_to_logical', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
@mock.patch('utilities_common.platform_sfputil_helper.logical_port_name_to_physical_port_list', mock.MagicMock(return_value=[0]))
def test_show_muxcable_firmware_version_all_bad_asic_index(self):
runner = CliRunner()
db = Db()

result = runner.invoke(show.cli.commands["muxcable"].commands["firmware"].commands["version"], [
"all"], obj=db)
assert result.exit_code == 1


@mock.patch('config.muxcable.delete_all_keys_in_db_table', mock.MagicMock(return_value=0))
@mock.patch('config.muxcable.update_and_get_response_for_xcvr_cmd', mock.MagicMock(return_value={0: 0,
1: "sucess"}))
Expand Down