Skip to content

Commit 9b24421

Browse files
authored
Add sfputil power enable/disable command (sonic-net#3418)
1 parent a813215 commit 9b24421

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

sfputil/main.py

+56
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,62 @@ def reset(port_name):
13201320

13211321
i += 1
13221322

1323+
1324+
# 'power' subgroup
1325+
@cli.group()
1326+
def power():
1327+
"""Enable or disable power of SFP transceiver"""
1328+
pass
1329+
1330+
1331+
# Helper method for setting low-power mode
1332+
def set_power(port_name, enable):
1333+
physical_port = logical_port_to_physical_port_index(port_name)
1334+
sfp = platform_chassis.get_sfp(physical_port)
1335+
1336+
if is_port_type_rj45(port_name):
1337+
click.echo("Power disable/enable is not available for RJ45 port {}.".format(port_name))
1338+
sys.exit(EXIT_FAIL)
1339+
1340+
try:
1341+
presence = sfp.get_presence()
1342+
except NotImplementedError:
1343+
click.echo("sfp get_presence() NOT implemented!")
1344+
sys.exit(EXIT_FAIL)
1345+
1346+
if not presence:
1347+
click.echo("{}: SFP EEPROM not detected\n".format(port_name))
1348+
sys.exit(EXIT_FAIL)
1349+
1350+
try:
1351+
result = platform_chassis.get_sfp(physical_port).set_power(enable)
1352+
except (NotImplementedError, AttributeError):
1353+
click.echo("This functionality is currently not implemented for this platform")
1354+
sys.exit(ERROR_NOT_IMPLEMENTED)
1355+
1356+
if result:
1357+
click.echo("OK")
1358+
else:
1359+
click.echo("Failed")
1360+
sys.exit(EXIT_FAIL)
1361+
1362+
1363+
# 'disable' subcommand
1364+
@power.command()
1365+
@click.argument('port_name', metavar='<port_name>')
1366+
def disable(port_name):
1367+
"""Disable power of SFP transceiver"""
1368+
set_power(port_name, False)
1369+
1370+
1371+
# 'enable' subcommand
1372+
@power.command()
1373+
@click.argument('port_name', metavar='<port_name>')
1374+
def enable(port_name):
1375+
"""Enable power of SFP transceiver"""
1376+
set_power(port_name, True)
1377+
1378+
13231379
def update_firmware_info_to_state_db(port_name):
13241380
physical_port = logical_port_to_physical_port_index(port_name)
13251381

tests/sfputil_test.py

+45
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,51 @@ def test_show_lpmode(self, mock_chassis):
610610
"""
611611
assert result.output == expected_output
612612

613+
@patch('sfputil.main.platform_chassis')
614+
@patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1))
615+
@patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=True))
616+
def test_power_RJ45(self, mock_chassis):
617+
mock_sfp = MagicMock()
618+
mock_api = MagicMock()
619+
mock_sfp.get_xcvr_api = MagicMock(return_value=mock_api)
620+
mock_sfp.get_presence.return_value = True
621+
mock_chassis.get_sfp = MagicMock(return_value=mock_sfp)
622+
runner = CliRunner()
623+
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
624+
assert result.output == 'Power disable/enable is not available for RJ45 port Ethernet0.\n'
625+
assert result.exit_code == EXIT_FAIL
626+
627+
@patch('sfputil.main.platform_chassis')
628+
@patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1))
629+
@patch('sfputil.main.platform_sfputil', MagicMock(is_logical_port=MagicMock(return_value=1)))
630+
@patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=False))
631+
def test_power(self, mock_chassis):
632+
mock_sfp = MagicMock()
633+
mock_api = MagicMock()
634+
mock_sfp.get_xcvr_api = MagicMock(return_value=mock_api)
635+
mock_chassis.get_sfp = MagicMock(return_value=mock_sfp)
636+
mock_sfp.get_presence.return_value = True
637+
runner = CliRunner()
638+
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
639+
assert result.exit_code == 0
640+
641+
mock_sfp.get_presence.return_value = False
642+
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
643+
assert result.output == 'Ethernet0: SFP EEPROM not detected\n\n'
644+
645+
mock_sfp.get_presence.return_value = True
646+
mock_sfp.set_power = MagicMock(side_effect=NotImplementedError)
647+
runner = CliRunner()
648+
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
649+
assert result.output == 'This functionality is currently not implemented for this platform\n'
650+
assert result.exit_code == ERROR_NOT_IMPLEMENTED
651+
652+
mock_sfp.set_power = MagicMock(return_value=False)
653+
runner = CliRunner()
654+
result = runner.invoke(sfputil.cli.commands['power'].commands['enable'], ["Ethernet0"])
655+
assert result.output == 'Failed\n'
656+
657+
613658
@patch('sfputil.main.platform_chassis')
614659
@patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1))
615660
@patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=[1]))

0 commit comments

Comments
 (0)