Skip to content

Commit

Permalink
Add test cases for port auto negotiation feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Junchao-Mellanox committed Apr 21, 2021
1 parent eb9f2d1 commit b3f1f1f
Show file tree
Hide file tree
Showing 5 changed files with 641 additions and 1 deletion.
62 changes: 62 additions & 0 deletions tests/common/devices/fanout.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
143 changes: 142 additions & 1 deletion tests/common/devices/onyx.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -68,3 +68,144 @@ 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
elif not autoneg_mode:
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

logger.debug('Failed to set speed {} for port {} from onyx'.format(speed, interface_name))
return False

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'
77 changes: 77 additions & 0 deletions tests/common/devices/sonic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,83 @@ 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"
Expand Down
2 changes: 2 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading

0 comments on commit b3f1f1f

Please sign in to comment.