diff --git a/show/main.py b/show/main.py index 8bd39fa1f6..f8e561c8b0 100755 --- a/show/main.py +++ b/show/main.py @@ -214,6 +214,11 @@ def run_command(command, display_cmd=False, return_cmd=False): sys.exit(rc) +def get_cmd_output(cmd): + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) + return proc.communicate()[0], proc.returncode + + def get_interface_mode(): mode = os.getenv('SONIC_CLI_IFACE_MODE') if mode is None: @@ -1653,8 +1658,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 ValueError 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/sonic-utilities-tests/show_test.py b/sonic-utilities-tests/show_test.py new file mode 100644 index 0000000000..46768c49fa --- /dev/null +++ b/sonic-utilities-tests/show_test.py @@ -0,0 +1,51 @@ +import os +import sys +import show.main as show +from click.testing import CliRunner +import mock +from 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"