From 6f075df75a0c32a1a2d361eb3ead7d91576fe06e Mon Sep 17 00:00:00 2001 From: Jingwen Xie Date: Fri, 20 Jan 2023 07:07:27 +0000 Subject: [PATCH] [202205][show] Add bgpraw to show run all --- show/main.py | 28 ++++++++++++++++++++++--- tests/show_test.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 tests/show_test.py diff --git a/show/main.py b/show/main.py index fc453ab899..74c5c9d899 100755 --- a/show/main.py +++ b/show/main.py @@ -10,7 +10,7 @@ import utilities_common.multi_asic as multi_asic_util from importlib import reload from natsort import natsorted -from sonic_py_common import device_info +from sonic_py_common import device_info, multi_asic from swsscommon.swsscommon import SonicV2Connector, ConfigDBConnector from tabulate import tabulate from utilities_common import util_base @@ -18,6 +18,7 @@ from datetime import datetime import utilities_common.constants as constants from utilities_common.general import load_db_config +from json.decoder import JSONDecodeError # mock the redis for unit test purposes # try: @@ -127,6 +128,10 @@ def run_command(command, display_cmd=False, return_cmd=False): if rc != 0: sys.exit(rc) +def get_cmd_output(cmd): + proc = subprocess.Popen(cmd, text=True, stdout=subprocess.PIPE) + return proc.communicate()[0], proc.returncode + # Lazy global class instance for SONiC interface name to alias conversion iface_alias_converter = lazy_object_proxy.Proxy(lambda: clicommon.InterfaceAliasConverter()) @@ -1229,8 +1234,25 @@ def runningconfiguration(): @click.option('--verbose', is_flag=True, help="Enable verbose output") def all(verbose): """Show full running configuration""" - cmd = "sonic-cfggen -d --print-data" - run_command(cmd, display_cmd=verbose) + cmd = ['sonic-cfggen', '-d', '--print-data'] + stdout, rc = get_cmd_output(cmd) + if rc: + click.echo("Failed to get cmd output '{}':rc {}".format(cmd, rc)) + raise click.Abort() + + try: + output = json.loads(stdout) + except JSONDecodeError as e: + click.echo("Failed to load output '{}':{}".format(cmd, e)) + raise click.Abort() + + if not multi_asic.is_multi_asic(): + bgpraw_cmd = [constants.RVTYSH_COMMAND, '-c', 'show running-config'] + bgpraw, rc = get_cmd_output(bgpraw_cmd) + if rc: + bgpraw = "" + output['bgpraw'] = bgpraw + click.echo(json.dumps(output, indent=4)) # 'acl' subcommand ("show runningconfiguration acl") diff --git a/tests/show_test.py b/tests/show_test.py new file mode 100644 index 0000000000..87c1b5a17e --- /dev/null +++ b/tests/show_test.py @@ -0,0 +1,51 @@ +import os +import sys +import show.main as show +from click.testing import CliRunner +from unittest import mock +from unittest.mock import call, MagicMock + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +sys.path.insert(0, test_path) +sys.path.insert(0, modules_path) + + +class TestShowRunAllCommands(object): + @classmethod + def setup_class(cls): + print("SETUP") + os.environ["UTILITIES_UNIT_TESTING"] = "1" + + def test_show_runningconfiguration_all_json_loads_failure(self): + def get_cmd_output_side_effect(*args, **kwargs): + return "", 0 + with mock.patch('show.main.get_cmd_output', + mock.MagicMock(side_effect=get_cmd_output_side_effect)) as mock_get_cmd_output: + result = CliRunner().invoke(show.cli.commands['runningconfiguration'].commands['all'], []) + assert result.exit_code != 0 + + def test_show_runningconfiguration_all_get_cmd_ouput_failure(self): + def get_cmd_output_side_effect(*args, **kwargs): + return "{}", 2 + with mock.patch('show.main.get_cmd_output', + mock.MagicMock(side_effect=get_cmd_output_side_effect)) as mock_get_cmd_output: + result = CliRunner().invoke(show.cli.commands['runningconfiguration'].commands['all'], []) + assert result.exit_code != 0 + + def test_show_runningconfiguration_all(self): + def get_cmd_output_side_effect(*args, **kwargs): + return "{}", 0 + with mock.patch('show.main.get_cmd_output', + mock.MagicMock(side_effect=get_cmd_output_side_effect)) as mock_get_cmd_output: + result = CliRunner().invoke(show.cli.commands['runningconfiguration'].commands['all'], []) + assert mock_get_cmd_output.call_count == 2 + assert mock_get_cmd_output.call_args_list == [ + call(['sonic-cfggen', '-d', '--print-data']), + call(['rvtysh', '-c', 'show running-config'])] + + @classmethod + def teardown_class(cls): + print("TEARDOWN") + os.environ["PATH"] = os.pathsep.join(os.environ["PATH"].split(os.pathsep)[:-1]) + os.environ["UTILITIES_UNIT_TESTING"] = "0"