Skip to content

Commit

Permalink
Add sfputil power enable/disable command (#3418)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnoopKamath authored Jul 26, 2024
1 parent a813215 commit 9b24421
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
56 changes: 56 additions & 0 deletions sfputil/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,62 @@ def reset(port_name):

i += 1


# 'power' subgroup
@cli.group()
def power():
"""Enable or disable power of SFP transceiver"""
pass


# Helper method for setting low-power mode
def set_power(port_name, enable):
physical_port = logical_port_to_physical_port_index(port_name)
sfp = platform_chassis.get_sfp(physical_port)

if is_port_type_rj45(port_name):
click.echo("Power disable/enable is not available for RJ45 port {}.".format(port_name))
sys.exit(EXIT_FAIL)

try:
presence = sfp.get_presence()
except NotImplementedError:
click.echo("sfp get_presence() NOT implemented!")
sys.exit(EXIT_FAIL)

if not presence:
click.echo("{}: SFP EEPROM not detected\n".format(port_name))
sys.exit(EXIT_FAIL)

try:
result = platform_chassis.get_sfp(physical_port).set_power(enable)
except (NotImplementedError, AttributeError):
click.echo("This functionality is currently not implemented for this platform")
sys.exit(ERROR_NOT_IMPLEMENTED)

if result:
click.echo("OK")
else:
click.echo("Failed")
sys.exit(EXIT_FAIL)


# 'disable' subcommand
@power.command()
@click.argument('port_name', metavar='<port_name>')
def disable(port_name):
"""Disable power of SFP transceiver"""
set_power(port_name, False)


# 'enable' subcommand
@power.command()
@click.argument('port_name', metavar='<port_name>')
def enable(port_name):
"""Enable power of SFP transceiver"""
set_power(port_name, True)


def update_firmware_info_to_state_db(port_name):
physical_port = logical_port_to_physical_port_index(port_name)

Expand Down
45 changes: 45 additions & 0 deletions tests/sfputil_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,51 @@ def test_show_lpmode(self, mock_chassis):
"""
assert result.output == expected_output

@patch('sfputil.main.platform_chassis')
@patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1))
@patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=True))
def test_power_RJ45(self, mock_chassis):
mock_sfp = MagicMock()
mock_api = MagicMock()
mock_sfp.get_xcvr_api = MagicMock(return_value=mock_api)
mock_sfp.get_presence.return_value = True
mock_chassis.get_sfp = MagicMock(return_value=mock_sfp)
runner = CliRunner()
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
assert result.output == 'Power disable/enable is not available for RJ45 port Ethernet0.\n'
assert result.exit_code == EXIT_FAIL

@patch('sfputil.main.platform_chassis')
@patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1))
@patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1)))
@patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=False))
def test_power(self, mock_chassis):
mock_sfp = MagicMock()
mock_api = MagicMock()
mock_sfp.get_xcvr_api = MagicMock(return_value=mock_api)
mock_chassis.get_sfp = MagicMock(return_value=mock_sfp)
mock_sfp.get_presence.return_value = True
runner = CliRunner()
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
assert result.exit_code == 0

mock_sfp.get_presence.return_value = False
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
assert result.output == 'Ethernet0: SFP EEPROM not detected\n\n'

mock_sfp.get_presence.return_value = True
mock_sfp.set_power = MagicMock(side_effect=NotImplementedError)
runner = CliRunner()
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
assert result.output == 'This functionality is currently not implemented for this platform\n'
assert result.exit_code == ERROR_NOT_IMPLEMENTED

mock_sfp.set_power = MagicMock(return_value=False)
runner = CliRunner()
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
assert result.output == 'Failed\n'


@patch('sfputil.main.platform_chassis')
@patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1))
@patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=[1]))
Expand Down

0 comments on commit 9b24421

Please sign in to comment.