From 2a8957d56d57d34ad328a4c1160e88784544ceff Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Tue, 14 Sep 2021 23:03:58 -0700 Subject: [PATCH] [202012][sonic-utilities] CLI support for port auto negotiation (#1817) * [sonic-utilities] CLI support for port auto negotiation (#1568) 1. Add CLI support for port auto negotiation feature. 2. Add db_migrator change for auto negotiation feature 2. Add unit test cases for all changes 1. Add new subcommands to "config interface" command group to allow user configuring port auto negotiation 2. Add new subcommands to "show interfaces" command group to allow user show auto negotiation status 3. In db_migrator.py, change auto negotiation related DB field to latest one Signed-off-by: vaibhav-dahiya Co-authored-by: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> --- config/main.py | 30 ++++++++ doc/Command-Reference.md | 51 +++++++++++++ scripts/db_migrator.py | 20 +++++- scripts/intfutil | 72 ++++++++++++++++++- scripts/portconfig | 32 ++++++++- show/interfaces/__init__.py | 35 +++++++++ tests/config_an_test.py | 42 +++++++++++ .../non-default-config-expected.json | 2 +- .../config_db/port-an-expected.json | 39 ++++++++++ .../config_db/port-an-input.json | 39 ++++++++++ tests/db_migrator_test.py | 13 +++- tests/intfutil_test.py | 48 +++++++++++++ tests/mock_tables/appl_db.json | 6 +- 13 files changed, 420 insertions(+), 9 deletions(-) create mode 100644 tests/config_an_test.py create mode 100644 tests/db_migrator_input/config_db/port-an-expected.json create mode 100644 tests/db_migrator_input/config_db/port-an-input.json diff --git a/config/main.py b/config/main.py index a5bf55bcf1..a87267fc18 100644 --- a/config/main.py +++ b/config/main.py @@ -2505,6 +2505,36 @@ def speed(ctx, interface_name, interface_speed, verbose): command += " -vv" clicommon.run_command(command, display_cmd=verbose) +# +# 'autoneg' subcommand +# + +@interface.command() +@click.pass_context +@click.argument('interface_name', metavar='', required=True) +@click.argument('mode', metavar='', required=True, type=click.Choice(["enabled", "disabled"])) +@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output") +def autoneg(ctx, interface_name, mode, verbose): + """Set interface auto negotiation mode""" + # Get the config_db connector + config_db = ctx.obj['config_db'] + + if clicommon.get_interface_naming_mode() == "alias": + interface_name = interface_alias_to_name(config_db, interface_name) + if interface_name is None: + ctx.fail("'interface_name' is None!") + + log.log_info("'interface autoneg {} {}' executing...".format(interface_name, mode)) + + if ctx.obj['namespace'] is DEFAULT_NAMESPACE: + command = "portconfig -p {} -an {}".format(interface_name, mode) + else: + command = "portconfig -p {} -an {} -n {}".format(interface_name, mode, ctx.obj['namespace']) + + if verbose: + command += " -vv" + clicommon.run_command(command, display_cmd=verbose) + # # 'breakout' subcommand # diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index f216fc5068..d0dbe16ebd 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -3037,6 +3037,7 @@ Subsequent pages explain each of these commands in detail. -?, -h, --help Show this message and exit. Commands: + autoneg Show interface autoneg information breakout Show Breakout Mode information by interfaces counters Show interface counters description Show interface status, protocol and... @@ -3047,6 +3048,30 @@ Subsequent pages explain each of these commands in detail. transceiver Show SFP Transceiver information ``` +**show interfaces autoneg** + +This show command displays the port auto negotiation status for all interfaces i.e. interface name, auto negotiation mode, speed, advertised speeds, interface type, advertised interface types, operational status, admin status. For a single interface, provide the interface name with the sub-command. + +- Usage: + ``` + show interfaces autoneg status + show interfaces autoneg status + ``` + +- Example: + ``` + admin@sonic:~$ show interfaces autoneg status + Interface Auto-Neg Mode Speed Adv Speeds Type Adv Types Oper Admin + ----------- --------------- ------- ------------ ------ ----------- ------ ------- + Ethernet0 enabled 25G 10G,25G CR CR,CR4 up up + Ethernet4 disabled 100G all CR4 all up up + + admin@sonic:~$ show interfaces autoneg status Ethernet8 + Interface Auto-Neg Mode Speed Adv Speeds Type Adv Types Oper Admin + ----------- --------------- ------- ------------ ------ ----------- ------ ------- + Ethernet8 disabled 100G N/A CR4 N/A up up + ``` + **show interfaces breakout** This show command displays the port capability for all interfaces i.e. index, lanes, default_brkout_mode, breakout_modes(i.e. all the available breakout modes) and brkout_mode (i.e. current breakout mode). To display current breakout mode, "current-mode" subcommand can be used.For a single interface, provide the interface name with the sub-command. @@ -3353,6 +3378,7 @@ This sub-section explains the following list of configuration on the interfaces. 4) speed - to set the interface speed 5) startup - to bring up the administratively shutdown interface 6) breakout - to set interface breakout mode +7) autoneg - to set interface auto negotiation mode From 201904 release onwards, the “config interface” command syntax is changed and the format is as follows: @@ -3687,6 +3713,31 @@ kindly use, double tab i.e. to see the available breakout option cust Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces) +**config interface autoneg (Versions >= 202012)** + +This command is used to set port auto negotiation mode. + +- Usage: + ``` + sudo config interface autoneg --help + Usage: config interface autoneg [OPTIONS] + + Set interface auto negotiation mode + + Options: + -v, --verbose Enable verbose output + -h, -?, --help Show this message and exit. + ``` + +- Example: + ``` + admin@sonic:~$ sudo config interface autoneg Ethernet0 enabled + + admin@sonic:~$ sudo config interface autoneg Ethernet0 disabled + ``` + +Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces) + **config interface cable_length (Versions >= 202006)** This command is used to configure the length of the cable connected to a port. The cable_length is in unit of meters and must be suffixed with "m". diff --git a/scripts/db_migrator.py b/scripts/db_migrator.py index da9969ff44..0fef783e65 100755 --- a/scripts/db_migrator.py +++ b/scripts/db_migrator.py @@ -371,6 +371,16 @@ def prepare_dynamic_buffer_for_warm_reboot(self, buffer_pools=None, buffer_profi return True + def migrate_config_db_port_table_for_auto_neg(self): + table_name = 'PORT' + port_table = self.configDB.get_table(table_name) + for key, value in port_table.items(): + if 'autoneg' in value: + if value['autoneg'] == '1': + self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, key), 'autoneg', 'on') + elif value['autoneg'] == '0': + self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, key), 'autoneg', 'off') + def version_unknown(self): """ version_unknown tracks all SONiC versions that doesn't have a version @@ -507,10 +517,18 @@ def version_1_0_6(self): def version_2_0_0(self): """ - Current latest version. Nothing to do here. + Version 2_0_0. """ log.log_info('Handling version_2_0_0') + self.migrate_config_db_port_table_for_auto_neg() + self.set_version('version_2_0_1') + return 'version_2_0_1' + def version_2_0_1(self): + """ + Current latest version. Nothing to do here. + """ + log.log_info('Handling version_2_0_1') return None def get_version(self): diff --git a/scripts/intfutil b/scripts/intfutil index 3a77338b39..e4da1e13d2 100755 --- a/scripts/intfutil +++ b/scripts/intfutil @@ -41,6 +41,7 @@ PORT_FEC = "fec" PORT_DESCRIPTION = "description" PORT_OPTICS_TYPE = "type" PORT_PFC_ASYM_STATUS = "pfc_asym" +PORT_AUTONEG = 'autoneg' VLAN_SUB_INTERFACE_SEPARATOR = "." VLAN_SUB_INTERFACE_TYPE = "802.1q-encapsulation" @@ -133,7 +134,7 @@ def appl_db_port_status_get(appl_db, intf_name, status_type): if status is None: return "N/A" if status_type == PORT_SPEED and status != "N/A": - status = '{}G'.format(status[:-3]) + status = '{}G'.format(status[:-3]) return status def state_db_port_optics_get(state_db, intf_name, type): @@ -506,10 +507,74 @@ class IntfDescription(object): if self.appl_db_keys: self.table += self.generate_intf_description() + +# ========================== interface-autoneg logic ========================== +header_autoneg = ['Interface', 'Auto-Neg Mode', 'Speed', 'Oper', 'Admin'] + + +class IntfAutoNegStatus(object): + + def __init__(self, intf_name, namespace_option, display_option): + self.db = None + self.config_db = None + self.table = [] + self.multi_asic = multi_asic_util.MultiAsic( + display_option, namespace_option) + + if intf_name is not None and intf_name == SUB_PORT: + self.intf_name = None + else: + self.intf_name = intf_name + + def display_autoneg_status(self): + + self.get_intf_autoneg_status() + + # Sorting and tabulating the result table. + sorted_table = natsorted(self.table) + print(tabulate(sorted_table, header_autoneg, tablefmt="simple", stralign='right')) + + def generate_autoneg_status(self): + """ + Generate interface-autoneg output + """ + + i = {} + table = [] + key = [] + + # + # Iterate through all the keys and append port's associated state to + # the result table. + # + for i in self.appl_db_keys: + key = re.split(':', i, maxsplit=1)[-1].strip() + if key in self.front_panel_ports_list: + if self.multi_asic.skip_display(constants.PORT_OBJ, key): + continue + autoneg_mode = appl_db_port_status_get(self.db, key, PORT_AUTONEG) + if autoneg_mode != 'N/A': + autoneg_mode = 'enabled' if autoneg_mode == '1' else 'disabled' + table.append((key, + autoneg_mode, + appl_db_port_status_get(self.db, key, PORT_SPEED), + appl_db_port_status_get(self.db, key, PORT_OPER_STATUS), + appl_db_port_status_get(self.db, key, PORT_ADMIN_STATUS), + )) + return table + + @multi_asic_util.run_on_multi_asic + def get_intf_autoneg_status(self): + self.front_panel_ports_list = get_frontpanel_port_list(self.config_db) + self.appl_db_keys = appl_db_keys_get(self.db, self.front_panel_ports_list, self.intf_name) + if self.appl_db_keys: + self.table += self.generate_autoneg_status() + + def main(): parser = argparse.ArgumentParser(description='Display Interface information', formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument('-c', '--command', type=str, help='get interface status or description', default=None) + parser.add_argument('-c', '--command', type=str, help='get interface status or description or auto negotiation status', default=None) parser.add_argument('-i', '--interface', type=str, help='interface information for specific port: Ethernet0', default=None) parser = multi_asic_util.multi_asic_args(parser) args = parser.parse_args() @@ -520,6 +585,9 @@ def main(): elif args.command == "description": interface_desc = IntfDescription(args.interface, args.namespace, args.display) interface_desc.display_intf_description() + elif args.command == "autoneg": + interface_autoneg_status = IntfAutoNegStatus(args.interface, args.namespace, args.display) + interface_autoneg_status.display_autoneg_status() sys.exit(0) diff --git a/scripts/portconfig b/scripts/portconfig index c850cbe2fe..5c07b3e2a4 100755 --- a/scripts/portconfig +++ b/scripts/portconfig @@ -16,15 +16,32 @@ optional arguments: -f --fec port fec mode -m --mtu port mtu in bytes -n --namesapce Namespace name + -an --autoneg port auto negotiation mode """ +import os import sys import argparse import swsssdk +# mock the redis for unit test purposes # +try: + if os.environ["UTILITIES_UNIT_TESTING"] == "1": + modules_path = os.path.join(os.path.dirname(__file__), "..") + test_path = os.path.join(modules_path, "tests") + sys.path.insert(0, modules_path) + sys.path.insert(0, test_path) + import mock_tables.dbconnector +except KeyError: + pass + +from swsscommon.swsscommon import ConfigDBConnector, SonicDBConfig, SonicV2Connector + +# APPL_DB constants PORT_TABLE_NAME = "PORT" PORT_SPEED_CONFIG_FIELD_NAME = "speed" PORT_FEC_CONFIG_FIELD_NAME = "fec" PORT_MTU_CONFIG_FIELD_NAME = "mtu" +PORT_AUTONEG_CONFIG_FIELD_NAME = "autoneg" class portconfig(object): """ @@ -32,7 +49,7 @@ class portconfig(object): """ def __init__(self, verbose, port, namespace): self.verbose = verbose - + self.namespace = namespace # Set up db connections if namespace is None: self.db = swsssdk.ConfigDBConnector() @@ -66,6 +83,13 @@ class portconfig(object): print("Setting mtu %s on port %s" % (mtu, port)) self.db.mod_entry(PORT_TABLE_NAME, port, {PORT_MTU_CONFIG_FIELD_NAME: mtu}) + def set_autoneg(self, port, mode): + if self.verbose: + print("Setting autoneg %s on port %s" % (mode, port)) + mode = 1 if mode == 'enabled' else 0 + self.db.mod_entry(PORT_TABLE_NAME, port, {PORT_AUTONEG_CONFIG_FIELD_NAME: mode}) + + def main(): parser = argparse.ArgumentParser(description='Set SONiC port parameters', formatter_class=argparse.RawTextHelpFormatter) @@ -78,6 +102,8 @@ def main(): parser.add_argument('-vv', '--verbose', action='store_true', help='Verbose output', default=False) parser.add_argument('-n', '--namespace', metavar='namespace details', type = str, required = False, help = 'The asic namespace whose DB instance we need to connect', default=None) + parser.add_argument('-an', '--autoneg', type = str, required = False, + help = 'port auto negotiation mode', default=None) args = parser.parse_args() if args.namespace is not None: @@ -87,13 +113,15 @@ def main(): port = portconfig(args.verbose, args.port, args.namespace) if args.list: port.list_params(args.port) - elif args.speed or args.fec or args.mtu: + elif args.speed or args.fec or args.mtu or args.autoneg: if args.speed: port.set_speed(args.port, args.speed) if args.fec: port.set_fec(args.port, args.fec) if args.mtu: port.set_mtu(args.port, args.mtu) + if args.autoneg: + port.set_autoneg(args.port, args.autoneg) else: parser.print_help() sys.exit(1) diff --git a/show/interfaces/__init__.py b/show/interfaces/__init__.py index a588a1e6c5..6d31890b22 100644 --- a/show/interfaces/__init__.py +++ b/show/interfaces/__init__.py @@ -465,3 +465,38 @@ def detailed(interface, period, verbose): cmd += " -i {}".format(interface) clicommon.run_command(cmd, display_cmd=verbose) + + +# +# autoneg group (show interfaces autoneg ...) +# +@interfaces.group(name='autoneg', cls=clicommon.AliasedGroup) +def autoneg(): + """Show interface autoneg information""" + pass + + +# 'autoneg status' subcommand ("show interfaces autoneg status") +@autoneg.command(name='status') +@click.argument('interfacename', required=False) +@multi_asic_util.multi_asic_click_options +@click.option('--verbose', is_flag=True, help="Enable verbose output") +def autoneg_status(interfacename, namespace, display, verbose): + """Show interface autoneg status""" + + ctx = click.get_current_context() + + cmd = "intfutil -c autoneg" + + #ignore the display option when interface name is passed + if interfacename is not None: + interfacename = try_convert_interfacename_from_alias(ctx, interfacename) + + cmd += " -i {}".format(interfacename) + else: + cmd += " -d {}".format(display) + + if namespace is not None: + cmd += " -n {}".format(namespace) + + clicommon.run_command(cmd, display_cmd=verbose) diff --git a/tests/config_an_test.py b/tests/config_an_test.py new file mode 100644 index 0000000000..37d2165f6f --- /dev/null +++ b/tests/config_an_test.py @@ -0,0 +1,42 @@ +import click +import config.main as config +import operator +import os +import pytest +import sys + +from click.testing import CliRunner +from utilities_common.db import Db + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +scripts_path = os.path.join(modules_path, "scripts") +sys.path.insert(0, modules_path) + + +@pytest.fixture(scope='module') +def ctx(scope='module'): + db = Db() + obj = {'config_db':db.cfgdb, 'namespace': ''} + yield obj + + +class TestConfigInterface(object): + @classmethod + def setup_class(cls): + print("SETUP") + os.environ["PATH"] += os.pathsep + scripts_path + os.environ["UTILITIES_UNIT_TESTING"] = "1" + + def test_config_autoneg(self, ctx): + self.basic_check("autoneg", ["Ethernet0", "enabled"], ctx) + self.basic_check("autoneg", ["Ethernet0", "disabled"], ctx) + self.basic_check("autoneg", ["Invalid", "enabled"], ctx, operator.ne) + self.basic_check("autoneg", ["Ethernet0", "invalid"], ctx, operator.ne) + + def basic_check(self, command_name, para_list, ctx, op=operator.eq, expect_result=0): + runner = CliRunner() + result = runner.invoke(config.config.commands["interface"].commands[command_name], para_list, obj = ctx) + print(result.output) + assert op(result.exit_code, expect_result) + return result diff --git a/tests/db_migrator_input/config_db/non-default-config-expected.json b/tests/db_migrator_input/config_db/non-default-config-expected.json index a31a50b45e..46e75f26f7 100644 --- a/tests/db_migrator_input/config_db/non-default-config-expected.json +++ b/tests/db_migrator_input/config_db/non-default-config-expected.json @@ -1115,6 +1115,6 @@ "speed": "50000" }, "VERSIONS|DATABASE": { - "VERSION": "version_2_0_0" + "VERSION": "version_2_0_1" } } diff --git a/tests/db_migrator_input/config_db/port-an-expected.json b/tests/db_migrator_input/config_db/port-an-expected.json new file mode 100644 index 0000000000..fa3b6019db --- /dev/null +++ b/tests/db_migrator_input/config_db/port-an-expected.json @@ -0,0 +1,39 @@ +{ + "PORT|Ethernet0": { + "index": "0", + "lanes": "0,1", + "description": "etp1a", + "mtu": "9100", + "alias": "etp1a", + "pfc_asym": "off", + "speed": "10000", + "fec": "none", + "autoneg": "on" + }, + "PORT|Ethernet2": { + "index": "0", + "lanes": "2,3", + "description": "Servers0:eth0", + "admin_status": "up", + "mtu": "9100", + "alias": "etp1b", + "pfc_asym": "off", + "speed": "25000", + "fec": "none", + "autoneg": "off" + }, + "PORT|Ethernet4": { + "index": "1", + "lanes": "4,5", + "description": "Servers1:eth0", + "admin_status": "up", + "mtu": "9100", + "alias": "etp2a", + "pfc_asym": "off", + "speed": "50000", + "fec": "none" + }, + "VERSIONS|DATABASE": { + "VERSION": "version_2_0_1" + } +} diff --git a/tests/db_migrator_input/config_db/port-an-input.json b/tests/db_migrator_input/config_db/port-an-input.json new file mode 100644 index 0000000000..373c9ae989 --- /dev/null +++ b/tests/db_migrator_input/config_db/port-an-input.json @@ -0,0 +1,39 @@ +{ + "PORT|Ethernet0": { + "index": "0", + "lanes": "0,1", + "description": "etp1a", + "mtu": "9100", + "alias": "etp1a", + "pfc_asym": "off", + "speed": "10000", + "fec": "none", + "autoneg": "1" + }, + "PORT|Ethernet2": { + "index": "0", + "lanes": "2,3", + "description": "Servers0:eth0", + "admin_status": "up", + "mtu": "9100", + "alias": "etp1b", + "pfc_asym": "off", + "speed": "25000", + "fec": "none", + "autoneg": "0" + }, + "PORT|Ethernet4": { + "index": "1", + "lanes": "4,5", + "description": "Servers1:eth0", + "admin_status": "up", + "mtu": "9100", + "alias": "etp2a", + "pfc_asym": "off", + "speed": "50000", + "fec": "none" + }, + "VERSIONS|DATABASE": { + "VERSION": "version_2_0_0" + } +} \ No newline at end of file diff --git a/tests/db_migrator_test.py b/tests/db_migrator_test.py index ba2fd2b516..20df58bb55 100644 --- a/tests/db_migrator_test.py +++ b/tests/db_migrator_test.py @@ -141,6 +141,7 @@ def test_mellanox_buffer_migrator_for_cold_reboot(self, sku_version, topo): import db_migrator dbmgtr = db_migrator.DBMigrator(None) dbmgtr.migrate() + # Eventually, the config db should be migrated to the latest version expected_db = self.mock_dedicated_config_db(self.make_db_name_by_sku_topo_version(sku, topo, self.version_list[-1])) self.advance_version_for_expected_database(dbmgtr.configDB, expected_db.cfgdb) @@ -196,7 +197,7 @@ def test_mellanox_buffer_migrator_negative_nondefault_for_warm_reboot(self): self.mellanox_buffer_migrator_warm_reboot_runner(input_config_db, input_appl_db, expected_config_db, expected_appl_db, False) -class TestInitConfigMigrator(object): +class TestAutoNegMigrator(object): @classmethod def setup_class(cls): os.environ['UTILITIES_UNIT_TESTING'] = "2" @@ -221,3 +222,13 @@ def test_init_config_feature_migration(self): assert not diff assert not expected_db.cfgdb.get_table('CONTAINER_FEATURE') + def test_port_autoneg_migrator(self): + dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'port-an-input') + import db_migrator + dbmgtr = db_migrator.DBMigrator(None) + dbmgtr.migrate() + dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'port-an-expected') + expected_db = Db() + + assert dbmgtr.configDB.get_table('PORT') == expected_db.cfgdb.get_table('PORT') + assert dbmgtr.configDB.get_table('VERSIONS') == expected_db.cfgdb.get_table('VERSIONS') diff --git a/tests/intfutil_test.py b/tests/intfutil_test.py index c350c57e50..e3cb9f501b 100644 --- a/tests/intfutil_test.py +++ b/tests/intfutil_test.py @@ -62,6 +62,31 @@ Ethernet32 up up etp9 Servers7:eth0 """ +show_interface_auto_neg_status_output = """\ + Interface Auto-Neg Mode Speed Oper Admin +----------- --------------- ------- ------ ------- + Ethernet0 enabled 25G down up + Ethernet32 disabled 40G up up +Ethernet112 N/A 40G up up +Ethernet116 N/A 40G up up +Ethernet120 N/A 40G up up +Ethernet124 N/A 40G up up +""" + +show_interface_auto_neg_status_Ethernet0_output = """\ + Interface Auto-Neg Mode Speed Oper Admin +----------- --------------- ------- ------ ------- + Ethernet0 enabled 25G down up +""" + +show_interface_auto_neg_status_eth9_output = """\ + Interface Auto-Neg Mode Speed Oper Admin +----------- --------------- ------- ------ ------- + Ethernet32 disabled 40G up up +""" + + + class TestIntfutil(TestCase): @classmethod def setup_class(cls): @@ -227,6 +252,29 @@ def test_single_subintf_status_alias_mode_verbose(self): os.environ["SONIC_CLI_IFACE_MODE"] = "default" + def test_show_interfaces_autoneg_status(self): + result = self.runner.invoke(show.cli.commands["interfaces"].commands["autoneg"].commands["status"], []) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_interface_auto_neg_status_output + + def test_show_interfaces_autoneg_status_Ethernet0(self): + result = self.runner.invoke(show.cli.commands["interfaces"].commands["autoneg"].commands["status"], ["Ethernet0"]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_interface_auto_neg_status_Ethernet0_output + + def test_show_interfaces_autoneg_status_etp9_in_alias_mode(self): + os.environ["SONIC_CLI_IFACE_MODE"] = "alias" + result = self.runner.invoke(show.cli.commands["interfaces"].commands["autoneg"].commands["status"], ["etp9"]) + os.environ["SONIC_CLI_IFACE_MODE"] = "default" + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_interface_auto_neg_status_eth9_output + @classmethod def teardown_class(cls): print("TEARDOWN") diff --git a/tests/mock_tables/appl_db.json b/tests/mock_tables/appl_db.json index 803473b9c4..14a331930a 100644 --- a/tests/mock_tables/appl_db.json +++ b/tests/mock_tables/appl_db.json @@ -34,7 +34,8 @@ "pfc_asym": "off", "mtu": "9100", "fec": "rs", - "admin_status": "up" + "admin_status": "up", + "autoneg": "1" }, "PORT_TABLE:Ethernet32": { "index": "8", @@ -46,7 +47,8 @@ "pfc_asym": "off", "mtu": "9100", "fec": "rs", - "admin_status": "up" + "admin_status": "up", + "autoneg": "0" }, "PORT_TABLE:Ethernet112": { "index": "28",