diff --git a/config/main.py b/config/main.py index b919ed7dde..aa9e9e595b 100644 --- a/config/main.py +++ b/config/main.py @@ -3437,7 +3437,7 @@ def speed(ctx, interface_name, interface_speed, verbose): @click.argument('mode', metavar='', required=True, type=click.Choice(["on", "off"])) @click.option('-v', '--verbose', is_flag=True, help="Enable verbose output") def link_training(ctx, interface_name, mode, verbose): - """Set interface auto negotiation mode""" + """Set interface link training mode""" # Get the config_db connector config_db = ctx.obj['config_db'] diff --git a/scripts/intfutil b/scripts/intfutil index dc2a27cbbe..e65d576017 100755 --- a/scripts/intfutil +++ b/scripts/intfutil @@ -33,7 +33,6 @@ except KeyError: PORT_STATUS_TABLE_PREFIX = "PORT_TABLE:" PORT_STATE_TABLE_PREFIX = "PORT_TABLE|" PORT_TRANSCEIVER_TABLE_PREFIX = "TRANSCEIVER_INFO|" -PORT_LINK_TRAINING_STATUS_TABLE_PREFIX = "LINK_TRAINING|" PORT_LANES_STATUS = "lanes" PORT_ALIAS = "alias" PORT_OPER_STATUS = "oper_status" @@ -50,7 +49,7 @@ PORT_INTERFACE_TYPE = 'interface_type' PORT_ADV_INTERFACE_TYPES = 'adv_interface_types' PORT_TPID = "tpid" PORT_LINK_TRAINING = 'link_training' -PORT_LINK_TRAINING_STATUS = 'status' +PORT_LINK_TRAINING_STATUS = 'link_training_status' VLAN_SUB_INTERFACE_SEPARATOR = "." VLAN_SUB_INTERFACE_TYPE = "802.1q-encapsulation" @@ -152,6 +151,32 @@ def appl_db_port_status_get(appl_db, intf_name, status_type): status = ','.join(new_speed_list) return status +def state_db_port_status_get(db, intf_name, field): + """ + Get the port status + """ + full_table_id = PORT_STATE_TABLE_PREFIX + intf_name + status = db.get(db.STATE_DB, full_table_id, field) + if not status: + return "N/A" + if field == PORT_SPEED and status != "N/A": + speed = int(status) + if speed >= 1000: + status = '{}G'.format(int(speed / 1000)) + else: + status = '{}M'.format(speed) + elif field == PORT_ADV_SPEEDS and status not in ["N/A", "all"]: + speed_list = status.split(',') + new_speed_list = [] + for s in natsorted(speed_list): + speed = int(s) + if speed >= 1000: + new_speed_list.append('{}G'.format(int(speed / 1000))) + else: + new_speed_list.append('{}M'.format(speed)) + status = ','.join(new_speed_list) + return status + def port_oper_speed_get(db, intf_name): """ Get port oper speed @@ -181,14 +206,6 @@ def state_db_port_optics_get(state_db, intf_name, type): return "N/A" return optics_type -def state_db_port_link_training_status_get(state_db, intf_name, type): - """ - Get link training status for port - """ - full_table_id = PORT_LINK_TRAINING_STATUS_TABLE_PREFIX + intf_name - status = state_db.get(state_db.STATE_DB, full_table_id, type) - return "N/A" if status is None else status - def merge_dicts(x,y): # store a copy of x, but overwrite with y's values where applicable merged = dict(x,**y) @@ -757,9 +774,9 @@ class IntfLinkTrainingStatus(object): lt_admin = appl_db_port_status_get(self.db, key, PORT_LINK_TRAINING) if lt_admin not in ['on', 'off']: lt_admin = '-' - lt_status = state_db_port_link_training_status_get(self.db, key, PORT_LINK_TRAINING_STATUS) - if lt_status in ['N/A', '']: - lt_status = '-' + lt_status = state_db_port_status_get(self.db, key, PORT_LINK_TRAINING_STATUS) + if lt_status in ['N/A', '', None]: + lt_status = 'off' table.append((key, lt_status.replace('_', ' '), lt_admin, diff --git a/tests/dump_tests/dump_state_test.py b/tests/dump_tests/dump_state_test.py index 4eb948ad72..e5b4d68e02 100644 --- a/tests/dump_tests/dump_state_test.py +++ b/tests/dump_tests/dump_state_test.py @@ -25,19 +25,20 @@ def compare_json_output(exp_json, rec, exclude_paths=None): table_display_output = '''\ -+-------------+-----------+----------------------------------------------------------------------------+ -| port_name | DB_NAME | DUMP | -+=============+===========+============================================================================+ -| Ethernet0 | STATE_DB | +----------------------+-------------------------------------------------+ | -| | | | Keys | field-value pairs | | -| | | +======================+=================================================+ | -| | | | PORT_TABLE|Ethernet0 | +------------------+--------------------------+ | | -| | | | | | field | value | | | -| | | | | |------------------+--------------------------| | | -| | | | | | supported_speeds | 10000,25000,40000,100000 | | | -| | | | | +------------------+--------------------------+ | | -| | | +----------------------+-------------------------------------------------+ | -+-------------+-----------+----------------------------------------------------------------------------+ ++-------------+-----------+--------------------------------------------------------------------------------+ +| port_name | DB_NAME | DUMP | ++=============+===========+================================================================================+ +| Ethernet0 | STATE_DB | +----------------------+-----------------------------------------------------+ | +| | | | Keys | field-value pairs | | +| | | +======================+=====================================================+ | +| | | | PORT_TABLE|Ethernet0 | +----------------------+--------------------------+ | | +| | | | | | field | value | | | +| | | | | |----------------------+--------------------------| | | +| | | | | | supported_speeds | 10000,25000,40000,100000 | | | +| | | | | | link_training_status | not_trained | | | +| | | | | +----------------------+--------------------------+ | | +| | | +----------------------+-----------------------------------------------------+ | ++-------------+-----------+--------------------------------------------------------------------------------+ ''' @@ -119,7 +120,7 @@ def test_identifier_single(self): expected = {'Ethernet0': {'CONFIG_DB': {'keys': [{'PORT|Ethernet0': {'alias': 'etp1', 'description': 'etp1', 'index': '0', 'lanes': '25,26,27,28', 'mtu': '9100', 'pfc_asym': 'off', 'speed': '40000'}}], 'tables_not_found': []}, 'APPL_DB': {'keys': [{'PORT_TABLE:Ethernet0': {'index': '0', 'lanes': '0', 'alias': 'Ethernet0', 'description': 'ARISTA01T2:Ethernet1', 'speed': '25000', 'oper_status': 'down', 'pfc_asym': 'off', 'mtu': '9100', 'fec': 'rs', 'admin_status': 'up'}}], 'tables_not_found': []}, 'ASIC_DB': {'keys': [{'ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF:oid:0xd00000000056d': {'SAI_HOSTIF_ATTR_NAME': 'Ethernet0', 'SAI_HOSTIF_ATTR_OBJ_ID': 'oid:0x10000000004a4', 'SAI_HOSTIF_ATTR_OPER_STATUS': 'true', 'SAI_HOSTIF_ATTR_TYPE': 'SAI_HOSTIF_TYPE_NETDEV', 'SAI_HOSTIF_ATTR_VLAN_TAG': 'SAI_HOSTIF_VLAN_TAG_STRIP'}}, {'ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000004a4': {'NULL': 'NULL', 'SAI_PORT_ATTR_ADMIN_STATE': 'true', 'SAI_PORT_ATTR_MTU': '9122', 'SAI_PORT_ATTR_SPEED': '100000'}}], 'tables_not_found': [], 'vidtorid': {'oid:0xd00000000056d': 'oid:0xd', 'oid:0x10000000004a4': 'oid:0x1690000000001'}}, - 'STATE_DB': {'keys': [{'PORT_TABLE|Ethernet0': {'supported_speeds': '10000,25000,40000,100000'}}], 'tables_not_found': []}}} + 'STATE_DB': {'keys': [{'PORT_TABLE|Ethernet0': {'supported_speeds': '10000,25000,40000,100000', 'link_training_status': 'not_trained'}}], 'tables_not_found': []}}} assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info) # Cause other tests depend and change these paths in the mock_db, this test would fail everytime when a field or a value in changed in this path, creating noise @@ -136,7 +137,7 @@ def test_identifier_multiple(self): {"CONFIG_DB": {"keys": [{"PORT|Ethernet0": {"alias": "etp1", "description": "etp1", "index": "0", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "speed": "40000"}}], "tables_not_found": []}, "APPL_DB": {"keys": [{"PORT_TABLE:Ethernet0": {"index": "0", "lanes": "0", "alias": "Ethernet0", "description": "ARISTA01T2:Ethernet1", "speed": "25000", "oper_status": "down", "pfc_asym": "off", "mtu": "9100", "fec": "rs", "admin_status": "up"}}], "tables_not_found": []}, "ASIC_DB": {"keys": [{"ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF:oid:0xd00000000056d": {"SAI_HOSTIF_ATTR_NAME": "Ethernet0", "SAI_HOSTIF_ATTR_OBJ_ID": "oid:0x10000000004a4", "SAI_HOSTIF_ATTR_OPER_STATUS": "true", "SAI_HOSTIF_ATTR_TYPE": "SAI_HOSTIF_TYPE_NETDEV", "SAI_HOSTIF_ATTR_VLAN_TAG": "SAI_HOSTIF_VLAN_TAG_STRIP"}}, {"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000004a4": {"NULL": "NULL", "SAI_PORT_ATTR_ADMIN_STATE": "true", "SAI_PORT_ATTR_MTU": "9122", "SAI_PORT_ATTR_SPEED": "100000"}}], "tables_not_found": [], "vidtorid": {"oid:0xd00000000056d": "oid:0xd", "oid:0x10000000004a4": "oid:0x1690000000001"}}, - "STATE_DB": {"keys": [{"PORT_TABLE|Ethernet0": {"supported_speeds": "10000,25000,40000,100000"}}], "tables_not_found": []}}, + "STATE_DB": {"keys": [{"PORT_TABLE|Ethernet0": {"supported_speeds": "10000,25000,40000,100000", "link_training_status": "not_trained"}}], "tables_not_found": []}}, "Ethernet4": {"CONFIG_DB": {"keys": [{"PORT|Ethernet4": {"admin_status": "up", "alias": "etp2", "description": "Servers0:eth0", "index": "1", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "speed": "40000"}}], "tables_not_found": []}, "APPL_DB": {"keys": [], "tables_not_found": ["PORT_TABLE"]}, @@ -165,7 +166,7 @@ def test_option_db_filtering(self): result = runner.invoke(dump.state, ["port", "Ethernet0", "--db", "ASIC_DB", "--db", "STATE_DB"]) print(result.output) expected = {"Ethernet0": {"ASIC_DB": {"keys": [{"ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF:oid:0xd00000000056d": {"SAI_HOSTIF_ATTR_NAME": "Ethernet0", "SAI_HOSTIF_ATTR_OBJ_ID": "oid:0x10000000004a4", "SAI_HOSTIF_ATTR_OPER_STATUS": "true", "SAI_HOSTIF_ATTR_TYPE": "SAI_HOSTIF_TYPE_NETDEV", "SAI_HOSTIF_ATTR_VLAN_TAG": "SAI_HOSTIF_VLAN_TAG_STRIP"}}, {"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000004a4": {"NULL": "NULL", "SAI_PORT_ATTR_ADMIN_STATE": "true", "SAI_PORT_ATTR_MTU": "9122", "SAI_PORT_ATTR_SPEED": "100000"}}], "tables_not_found": [], "vidtorid": {"oid:0xd00000000056d": "oid:0xd", "oid:0x10000000004a4": "oid:0x1690000000001"}}, - "STATE_DB": {"keys": [{"PORT_TABLE|Ethernet0": {"supported_speeds": "10000,25000,40000,100000"}}], "tables_not_found": []}}} + "STATE_DB": {"keys": [{"PORT_TABLE|Ethernet0": {"supported_speeds": "10000,25000,40000,100000", 'link_training_status': 'not_trained'}}], "tables_not_found": []}}} assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info) ddiff = compare_json_output(expected, result.output) assert not ddiff, ddiff diff --git a/tests/intfutil_test.py b/tests/intfutil_test.py index fe69811e0c..7dc3309d6e 100644 --- a/tests/intfutil_test.py +++ b/tests/intfutil_test.py @@ -91,9 +91,9 @@ Ethernet0 not trained on down up Ethernet32 trained on up up Ethernet112 off off up up -Ethernet116 - - up up -Ethernet120 - - up up -Ethernet124 - - up up +Ethernet116 off - up up +Ethernet120 off - up up +Ethernet124 off - up up """ class TestIntfutil(TestCase): diff --git a/tests/mock_tables/state_db.json b/tests/mock_tables/state_db.json index ee2505448a..097e1c6a5c 100644 --- a/tests/mock_tables/state_db.json +++ b/tests/mock_tables/state_db.json @@ -643,10 +643,15 @@ "access": "False" }, "PORT_TABLE|Ethernet0": { - "supported_speeds": "10000,25000,40000,100000" + "supported_speeds": "10000,25000,40000,100000", + "link_training_status": "not_trained" + }, + "PORT_TABLE|Ethernet32": { + "link_training_status": "trained" }, "PORT_TABLE|Ethernet112": { - "speed": "40000" + "speed": "40000", + "link_training_status": "off" }, "PCIE_DEVICE|00:01.0": { "correctable|BadDLLP": "0", @@ -757,14 +762,5 @@ "pck_expected_count": "840", "link_prober_unknown_start": "2022-Jan-26 03:13:05.366900", "link_prober_unknown_end": "2022-Jan-26 03:17:35.446580" - }, - "LINK_TRAINING|Ethernet0": { - "status": "not_trained" - }, - "LINK_TRAINING|Ethernet32": { - "status": "trained" - }, - "LINK_TRAINING|Ethernet112": { - "status": "off" } }