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

Add test cases for port auto negotiation feature #3376

Merged
merged 5 commits into from
May 30, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions tests/common/devices/fanout.py
Original file line number Diff line number Diff line change
@@ -107,3 +107,65 @@ def add_port_map(self, host_port, fanout_port):

def exec_template(self, ansible_root, ansible_playbook, inventory, **kwargs):
return self.host.exec_template(ansible_root, ansible_playbook, inventory, **kwargs)

def get_supported_speeds(self, interface_name):
"""Get supported speeds for a given interface

Args:
interface_name (str): Interface name

Returns:
list: A list of supported speed strings or None
"""
return self.host.get_supported_speeds(interface_name)

def set_auto_negotiation_mode(self, interface_name, mode):
"""Set auto negotiation mode for a given interface

Args:
interface_name (str): Interface name
mode (boolean): True to enable auto negotiation else disable

Returns:
boolean: False if the operation is not supported else True
"""
return self.host.set_auto_negotiation_mode(interface_name, mode)

def get_auto_negotiation_mode(self, interface_name):
"""Get auto negotiation mode for a given interface

Args:
interface_name (str): Interface name

Returns:
boolean: True if auto negotiation mode is enabled else False. Return None if
the auto negotiation mode is unknown or unsupported.
"""
return self.host.get_auto_negotiation_mode(interface_name)

def set_speed(self, interface_name, speed):
"""Set interface speed according to the auto negotiation mode. When auto negotiation mode
is enabled, set the advertised speeds; otherwise, set the force speed.

Args:
interface_name (str): Interface name
speed (str): SONiC style interface speed. E.g, 1G=1000, 10G=10000, 100G=100000. If the speed
is None and auto negotiation mode is enabled, it sets the advertised speeds to all supported
speeds.

Returns:
boolean: True if success. Usually, the method return False only if the operation
is not supported or failed.
"""
return self.host.set_speed(interface_name, speed)

def get_speed(self, interface_name):
"""Get interface speed

Args:
interface_name (str): Interface name

Returns:
str: SONiC style interface speed value. E.g, 1G=1000, 10G=10000, 100G=100000.
"""
return self.host.get_speed(interface_name)
140 changes: 139 additions & 1 deletion tests/common/devices/onyx.py
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ def command(self, cmd):
def set_interface_lacp_rate_mode(self, interface_name, mode):
out = self.host.onyx_config(
lines=['lacp rate %s' % mode],
parents='interface ethernet %s' % interface_name)
parents='interface %s' % interface_name)
logging.info("Set interface [%s] lacp rate to [%s]" % (interface_name, mode))
return out

@@ -68,3 +68,141 @@ def exec_template(self, ansible_root, ansible_playbook, inventory, **kwargs):

if res["localhost"]["rc"] != 0:
raise Exception("Unable to execute template\n{}".format(res["localhost"]["stdout"]))

def get_supported_speeds(self, interface_name):
"""Get supported speeds for a given interface

Args:
interface_name (str): Interface name

Returns:
list: A list of supported speed strings or None
"""
show_int_result = self.host.onyx_command(
commands=['show interfaces {} | include "Supported speeds"'.format(interface_name)])[self.hostname]

if 'failed' in show_int_result and show_int_result['failed']:
logger.error('Failed to get supported speed for {} - {}'.format(interface_name, show_int_result['msg']))
return None

out = show_int_result['stdout'][0].strip()
logger.debug('Get supported speeds for port {} from onyx: {}'.format(interface_name, out))
if not out:
return None

# The output should be something like: "Supported speeds:1G 10G 25G 50G"
speeds = out.split(':')[-1].split()
return [x[:-1] + '000' for x in speeds]

def set_auto_negotiation_mode(self, interface_name, mode):
"""Set auto negotiation mode for a given interface

Args:
interface_name (str): Interface name
mode (boolean): True to enable auto negotiation else disable

Returns:
boolean: False if the operation is not supported else True
"""
if mode:
return self.set_speed(interface_name, None)
else:
speed = self.get_speed(interface_name)
out = self.host.onyx_config(
lines=['shutdown', 'speed {}G no-autoneg'.format(speed[:-3]), 'no shutdown'],
parents='interface %s' % interface_name)[self.hostname]

if 'failed' in out and out['failed']:
logger.error('Failed to set auto neg to False for port {} - {}'.format(interface_name, out['msg']))
return False
logger.debug('Set auto neg to False for port {} from onyx: {}'.format(interface_name, out))
return True

def get_auto_negotiation_mode(self, interface_name):
"""Get auto negotiation mode for a given interface

Args:
interface_name (str): Interface name

Returns:
boolean: True if auto negotiation mode is enabled else False. Return None if
the auto negotiation mode is unknown or unsupported.
"""
show_int_result = self.host.onyx_command(
commands=['show interfaces {} | include "Auto-negotiation"'.format(interface_name)])[self.hostname]

if 'failed' in show_int_result and show_int_result['failed']:
logger.error('Failed to get auto neg mode for port {} - {}'.format(interface_name, show_int_result['msg']))
return None

out = show_int_result['stdout'][0].strip()
logger.debug('Get auto negotiation mode for port {} from onyx: {}'.format(interface_name, out))
if not out:
return None

# The output should be something like: "Auto-negotiation:Enabled"
return 'Enabled' in out

def set_speed(self, interface_name, speed):
"""Set interface speed according to the auto negotiation mode. When auto negotiation mode
is enabled, set the advertised speeds; otherwise, set the force speed.

Args:
interface_name (str): Interface name
speed (str): SONiC style interface speed. E.g, 1G=1000, 10G=10000, 100G=100000. If the speed
is None and auto negotiation mode is enabled, it sets the advertised speeds to all supported
speeds.

Returns:
boolean: True if success. Usually, the method return False only if the operation
is not supported or failed.
"""
autoneg_mode = self.get_auto_negotiation_mode(interface_name)
if not speed:
speed = 'auto'
else:
speed = speed[:-3] + 'G'
if autoneg_mode or speed == 'auto':
out = self.host.onyx_config(
lines=['shutdown', 'speed {}'.format(speed), 'no shutdown'],
parents='interface %s' % interface_name)[self.hostname]
if 'failed' in out and out['failed']:
logger.error('Failed to set speed for port {} - {}'.format(interface_name, out['msg']))
return False
logger.debug('Set auto speed for port {} from onyx: {}'.format(interface_name, out))
return True
else:
out = self.host.onyx_config(
lines=['shutdown', 'speed {} no-autoneg'.format(speed), 'no shutdown'],
parents='interface %s' % interface_name)[self.hostname]
if 'failed' in out and out['failed']:
logger.error('Failed to set speed for port {} - {}'.format(interface_name, out['msg']))
return False
logger.debug('Set force speed for port {} from onyx: {}'.format(interface_name, out))
return True

def get_speed(self, interface_name):
"""Get interface speed

Args:
interface_name (str): Interface name

Returns:
str: SONiC style interface speed value. E.g, 1G=1000, 10G=10000, 100G=100000.
"""
show_int_result = self.host.onyx_command(
commands=['show interfaces {} | include "Actual speed"'.format(interface_name)])[self.hostname]

if 'failed' in show_int_result and show_int_result['failed']:
logger.error('Failed to get speed for port {} - {}'.format(interface_name, show_int_result['msg']))
return False

out = show_int_result['stdout'][0].strip()
logger.debug('Get speed for port {} from onyx: {}'.format(interface_name, out))
if not out:
return None

# The output should be something like: "Actual speed:50G"
speed = out.split(':')[-1].strip()
pos = speed.find('G')
return speed[:pos] + '000'
78 changes: 78 additions & 0 deletions tests/common/devices/sonic.py
Original file line number Diff line number Diff line change
@@ -1361,6 +1361,84 @@ def get_up_ip_ports(self):
pass
return up_ip_ports

def get_supported_speeds(self, interface_name):
"""Get supported speeds for a given interface

Args:
interface_name (str): Interface name

Returns:
list: A list of supported speed strings or None
"""
cmd = 'sonic-db-cli STATE_DB HGET \"PORT_TABLE|{}\" \"{}\"'.format(interface_name, 'supported_speeds')
supported_speeds = self.shell(cmd)['stdout'].strip()
return None if not supported_speeds else supported_speeds.split(',')

def set_auto_negotiation_mode(self, interface_name, mode):
"""Set auto negotiation mode for a given interface

Args:
interface_name (str): Interface name
mode (boolean): True to enable auto negotiation else disable

Returns:
boolean: False if the operation is not supported else True
"""
cmd = 'config interface autoneg {} {}'.format(interface_name, 'enabled' if mode else 'disabled')
self.shell(cmd)
return True

def get_auto_negotiation_mode(self, interface_name):
"""Get auto negotiation mode for a given interface

Args:
interface_name (str): Interface name

Returns:
boolean: True if auto negotiation mode is enabled else False. Return None if
the auto negotiation mode is unknown or unsupported.
"""
cmd = 'sonic-db-cli APPL_DB HGET \"PORT_TABLE:{}\" \"{}\"'.format(interface_name, 'autoneg')
mode = self.shell(cmd)['stdout'].strip()
if not mode:
return None
return True if mode == 'on' else False

def set_speed(self, interface_name, speed):
"""Set interface speed according to the auto negotiation mode. When auto negotiation mode
is enabled, set the advertised speeds; otherwise, set the force speed.

Args:
interface_name (str): Interface name
speed (str): SONiC style interface speed. E.g, 1G=1000, 10G=10000, 100G=100000. If the speed
is None and auto negotiation mode is enabled, it sets the advertised speeds to all supported
speeds.

Returns:
boolean: True if success. Usually, the method return False only if the operation
is not supported or failed.
"""
auto_neg_mode = self.get_auto_negotiation_mode(interface_name)
if not auto_neg_mode:
cmd = 'config interface speed {} {}'.format(interface_name, speed)
else:
cmd = 'config interface advertised-speeds {} {}'.format(interface_name, speed)
self.shell(cmd)
return True

def get_speed(self, interface_name):
"""Get interface speed

Args:
interface_name (str): Interface name

Returns:
str: SONiC style interface speed value. E.g, 1G=1000, 10G=10000, 100G=100000.
"""
cmd = 'sonic-db-cli APPL_DB HGET \"PORT_TABLE:{}\" \"{}\"'.format(interface_name, 'speed')
speed = self.shell(cmd)['stdout'].strip()
return speed

def get_rsyslog_ipv4(self):
if not self.is_multi_asic:
return "127.0.0.1"
2 changes: 2 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -955,6 +955,8 @@ def pytest_generate_tests(metafunc):

if "enum_dut_portname" in metafunc.fixturenames:
metafunc.parametrize("enum_dut_portname", generate_port_lists(metafunc, "all_ports"))
if "enum_dut_portname_module_fixture" in metafunc.fixturenames:
metafunc.parametrize("enum_dut_portname_module_fixture", generate_port_lists(metafunc, "all_ports"), scope="module")
if "enum_dut_portname_oper_up" in metafunc.fixturenames:
metafunc.parametrize("enum_dut_portname_oper_up", generate_port_lists(metafunc, "oper_up_ports"))
if "enum_dut_portname_admin_up" in metafunc.fixturenames:
Loading