diff --git a/src/sonic-py-common/sonic_py_common/sonic_db_dump_load.py b/src/sonic-py-common/sonic_py_common/sonic_db_dump_load.py index 4c6f0fd3ffd..20a5c5a5db6 100755 --- a/src/sonic-py-common/sonic_py_common/sonic_db_dump_load.py +++ b/src/sonic-py-common/sonic_py_common/sonic_db_dump_load.py @@ -6,7 +6,8 @@ def sonic_db_dump_load(): import re import sys from redisdl import dump, load - from swsscommon.swsscommon import SonicDBConfig + from swsscommon.swsscommon import SonicDBConfig, SonicDBKey + from sonic_py_common import multi_asic DUMP = 1 LOAD = 2 @@ -30,22 +31,25 @@ def options_to_kwargs(options): if hasattr(options, 'backend') and options.backend: args['streaming_backend'] = options.backend if hasattr(options, 'dbname') and options.dbname: + key = SonicDBKey(options.netns) if options.conntype == 'tcp': - args['host'] = SonicDBConfig.getDbHostname(options.dbname) - args['port'] = SonicDBConfig.getDbPort(options.dbname) - args['db'] = SonicDBConfig.getDbId(options.dbname) + args['host'] = SonicDBConfig.getDbHostname(options.dbname, key) + args['port'] = SonicDBConfig.getDbPort(options.dbname, key) + args['db'] = SonicDBConfig.getDbId(options.dbname, key) args['unix_socket_path'] = None elif options.conntype == "unix_socket": args['host'] = None args['port'] = None - args['db'] = SonicDBConfig.getDbId(options.dbname) - args['unix_socket_path'] = SonicDBConfig.getDbSock(options.dbname) + args['db'] = SonicDBConfig.getDbId(options.dbname, key) + args['unix_socket_path'] = SonicDBConfig.getDbSock(options.dbname, key) else: raise TypeError('redis connection type is tcp or unix_socket') return args def do_dump(options): + if multi_asic.is_multi_asic(): + SonicDBConfig.initializeGlobalConfig() if options.output: output = open(options.output, 'w') else: @@ -58,6 +62,8 @@ def do_dump(options): output.close() def do_load(options, args): + if multi_asic.is_multi_asic(): + SonicDBConfig.initializeGlobalConfig() if len(args) > 0: input = open(args[0], 'rb') else: @@ -97,6 +103,7 @@ def do_load(options, args): usage += "\nfrom standard input." parser = optparse.OptionParser(usage=usage) parser.add_option('-w', '--password', help='connect with PASSWORD') + parser.add_option('--netns', help='Namespace string to use asic0/asic1.../asicn', default='') if help == DUMP: parser.add_option('-n', '--dbname', help='dump DATABASE (APPL_DB/ASIC_DB...)') parser.add_option('-t', '--conntype', help='indicate redis connection type (tcp[default] or unix_socket)', default='tcp') diff --git a/src/sonic-py-common/tests/test_sonic_db_dump_load.py b/src/sonic-py-common/tests/test_sonic_db_dump_load.py new file mode 100644 index 00000000000..804c4ca122e --- /dev/null +++ b/src/sonic-py-common/tests/test_sonic_db_dump_load.py @@ -0,0 +1,83 @@ +import sys +from sonic_py_common.sonic_db_dump_load import sonic_db_dump_load +from swsscommon.swsscommon import SonicDBKey +from unittest.mock import patch + +@patch("redisdl.dump") +@patch("swsscommon.swsscommon.SonicDBConfig.getDbHostname", return_value="127.0.0.1") +@patch("swsscommon.swsscommon.SonicDBConfig.getDbPort", return_value=6379) +@patch("swsscommon.swsscommon.SonicDBConfig.getDbId", return_value=0) +@patch("sys.argv", ["sonic-db-dump", "-n", "APPL_DB"]) +def test_sonic_db_dump(mock_getDbHostname, mock_getDbPort, mock_getDbId, mock_dump): + sonic_db_dump_load() + mock_dump.assert_called_once_with(sys.stdout, ** + { + "host": "127.0.0.1", + "port": 6379, + "unix_socket_path": None, + "db": 0, + "encoding": "utf-8", + } + ) + mock_getDbHostname.assert_called_once_with("APPL_DB", SonicDBKey()) + + +@patch("redisdl.dump") +@patch("sonic_py_common.multi_asic.is_multi_asic", return_value=True) +@patch("swsscommon.swsscommon.SonicDBConfig.getDbHostname", return_value="127.0.0.1") +@patch("swsscommon.swsscommon.SonicDBConfig.getDbPort", return_value=6379) +@patch("swsscommon.swsscommon.SonicDBConfig.getDbId", return_value=0) +@patch("sys.argv", ["sonic-db-dump", "--netns", "asic0", "-n", "APPL_DB"]) +def test_sonic_db_dump_multi_asic(mock_getDbHostname, mock_getDbPort, mock_getDbId, mock_is_multi_asic, mock_dump): + sonic_db_dump_load() + mock_dump.assert_called_once_with(sys.stdout, ** + { + "host": "127.0.0.1", + "port": 6379, + "unix_socket_path": None, + "db": 0, + "encoding": "utf-8", + } + ) + mock_getDbHostname.assert_called_once_with("APPL_DB", SonicDBKey("asic0")) + + +@patch("redisdl.load") +@patch("swsscommon.swsscommon.SonicDBConfig.getDbHostname", return_value="127.0.0.1") +@patch("swsscommon.swsscommon.SonicDBConfig.getDbPort", return_value=6379) +@patch("swsscommon.swsscommon.SonicDBConfig.getDbId", return_value=0) +@patch("sys.argv", ["sonic-db-load", "-n", "APPL_DB"]) +def test_sonic_db_load(mock_getDbHostname, mock_getDbPort, mock_getDbId, mock_load): + sonic_db_dump_load() + mock_load.assert_called_once_with(sys.stdin, ** + { + "host": "127.0.0.1", + "port": 6379, + "unix_socket_path": None, + "db": 0, + "encoding": "utf-8", + } + ) + args, kwargs = mock_getDbHostname.call_args + assert args[0] == "APPL_DB" + assert args[1].netns == "" + + +@patch("redisdl.load") +@patch("sonic_py_common.multi_asic.is_multi_asic", return_value=True) +@patch("swsscommon.swsscommon.SonicDBConfig.getDbHostname", return_value="127.0.0.1") +@patch("swsscommon.swsscommon.SonicDBConfig.getDbPort", return_value=6379) +@patch("swsscommon.swsscommon.SonicDBConfig.getDbId", return_value=0) +@patch("sys.argv", ["sonic-db-load", "--netns", "asic0", "-n", "APPL_DB"]) +def test_sonic_db_load_multi_asic(mock_getDbHostname, mock_getDbPort, mock_getDbId, mock_is_multi_asic, mock_load): + sonic_db_dump_load() + mock_load.assert_called_once_with(sys.stdin, ** + { + "host": "127.0.0.1", + "port": 6379, + "unix_socket_path": None, + "db": 0, + "encoding": "utf-8", + } + ) + mock_getDbHostname.assert_called_once_with("APPL_DB", SonicDBKey("asic0")) \ No newline at end of file