Skip to content

Commit

Permalink
[202205][show] Add bgpraw to show run all (#2624)
Browse files Browse the repository at this point in the history
What I did
#2537
#2623
#2628

202205 branch doesn't have from sonic_py_common import multi_asic, which results in test failure and build error.
The only difference between this PR and original PR is just one line of import.

How to verify it
Tested locally on 202205 build and pass the build process.
Test to make sure it pass GCU tests.
  • Loading branch information
wen587 authored Jan 30, 2023
1 parent c63a62b commit 5e84f25
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 5 deletions.
4 changes: 3 additions & 1 deletion generic_config_updater/gu_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ def __init__(self, yang_dir = YANG_DIR):

def get_config_db_as_json(self):
text = self._get_config_db_as_text()
return json.loads(text)
config_db_json = json.loads(text)
config_db_json.pop("bgpraw", None)
return config_db_json

def _get_config_db_as_text(self):
# TODO: Getting configs from CLI is very slow, need to get it from sonic-cffgen directly
Expand Down
28 changes: 25 additions & 3 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
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
from utilities_common.db import Db
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:
Expand Down Expand Up @@ -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())

Expand Down Expand Up @@ -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")
Expand Down
14 changes: 13 additions & 1 deletion tests/generic_config_updater/gu_common_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,24 @@
import jsonpatch
import sonic_yang
import unittest
from unittest.mock import MagicMock, Mock
from unittest.mock import MagicMock, Mock, patch

from .gutest_helpers import create_side_effect_dict, Files
import generic_config_updater.gu_common as gu_common

class TestDryRunConfigWrapper(unittest.TestCase):
@patch('generic_config_updater.gu_common.subprocess.Popen')
def test_get_config_db_as_json(self, mock_popen):
config_wrapper = gu_common.DryRunConfigWrapper()
mock_proc = MagicMock()
mock_proc.communicate = MagicMock(
return_value=('{"PORT": {}, "bgpraw": ""}', None))
mock_proc.returncode = 0
mock_popen.return_value = mock_proc
actual = config_wrapper.get_config_db_as_json()
expected = {"PORT": {}}
self.assertDictEqual(actual, expected)

def test_get_config_db_as_json__returns_imitated_config_db(self):
# Arrange
config_wrapper = gu_common.DryRunConfigWrapper(Files.CONFIG_DB_AS_JSON)
Expand Down
51 changes: 51 additions & 0 deletions tests/show_test.py
Original file line number Diff line number Diff line change
@@ -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"

0 comments on commit 5e84f25

Please sign in to comment.