From 276f47cab1768efd5a80da86904063b3ada5dd22 Mon Sep 17 00:00:00 2001 From: Hua Liu <58683130+liuh-80@users.noreply.github.com> Date: Mon, 31 Oct 2022 10:25:04 +0800 Subject: [PATCH] [sonic-db-cli] Fix sonic-db-cli crash when database config file not ready issue. (#701) #### Why I did it Fix sonic-db-cli PING/SAVE/FLUSHALL command crash when database config file not ready issue: https://github.com/sonic-net/sonic-buildimage/issues/12047 #### How I did it When run PING/SAVE/FLUSHALL command, catch database initialize failed exception and return 1. #### How to verify it Pass all existing UT and E2E test. Add new UT to cover changed code. Manually test, sonic-db-cli will return 1 when run PING command and can't find config file: azureuser@a7f66d2b794c:/sonic/src/sonic-swss-common$ ./sonic-db-cli/sonic-db-cli PING An exception of type Sonic database config file doesn't exist at /var/run/redis/sonic-db/database_config.json occurred. Arguments: /sonic/src/sonic-swss-common/sonic-db-cli/.libs/sonic-db-cli PING azureuser@a7f66d2b794c:/sonic/src/sonic-swss-common$ echo $? 1 #### Which release branch to backport (provide reason below if selected) - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [x] 202111 - [x] 202205 #### Description for the changelog Fix sonic-db-cli PING/SAVE/FLUSHALL command crash when database config file not ready issue. #### Link to config_db schema for YANG module changes #### A picture of a cute animal (not mandatory but encouraged) --- sonic-db-cli/sonic-db-cli.cpp | 14 ++++++++-- tests/cli_ut.cpp | 50 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/sonic-db-cli/sonic-db-cli.cpp b/sonic-db-cli/sonic-db-cli.cpp index 3e7003b8c..f0a22cde7 100755 --- a/sonic-db-cli/sonic-db-cli.cpp +++ b/sonic-db-cli/sonic-db-cli.cpp @@ -287,8 +287,6 @@ int sonic_db_cli( } else { - // SonicDBConfig may initialized when run cli with UT - initializeConfig(); // Use the tcp connectivity if namespace is local and unixsocket cmd_option is present. isTcpConn = true; netns = ""; @@ -297,6 +295,12 @@ int sonic_db_cli( if (options.m_cmd.size() != 0) { auto commands = options.m_cmd; + + if (netns.empty()) + { + initializeConfig(); + } + return executeCommands(dbOrOperation, commands, netns, isTcpConn); } else if (dbOrOperation == "PING" @@ -307,6 +311,12 @@ int sonic_db_cli( // sonic-db-cli catch all possible exceptions and handle it as a failure case which not return 'OK' or 'PONG' try { + if (netns.empty()) + { + // When database_config.json does not exist, sonic-db-cli will ignore exception and return 1. + initializeConfig(); + } + return handleAllInstances(netns, dbOrOperation, isTcpConn); } catch (const exception& e) diff --git a/tests/cli_ut.cpp b/tests/cli_ut.cpp index 3957cdeac..6782a95cc 100755 --- a/tests/cli_ut.cpp +++ b/tests/cli_ut.cpp @@ -11,6 +11,7 @@ using namespace swss; using namespace std; +const string not_exist_config_file = "./tests/redis_multi_db_ut_config/database_config_not_exist.json"; const string config_file = "./tests/redis_multi_db_ut_config/database_config.json"; const string global_config_file = "./tests/redis_multi_db_ut_config/database_global.json"; @@ -279,6 +280,55 @@ TEST(sonic_db_cli, test_cli_ping_cmd) EXPECT_EQ("True\n", output); } +TEST(sonic_db_cli, test_cli_ping_cmd_no_config) +{ + char *args[3]; + args[0] = "sonic-db-cli"; + args[1] = "PING"; + + // data base file does not exist, will throw exception + auto initializeGlobalConfig = []() + { + SonicDBConfig::initializeGlobalConfig(not_exist_config_file); + }; + + auto initializeConfig = []() + { + SonicDBConfig::initialize(not_exist_config_file); + }; + + optind = 0; + int exit_code = sonic_db_cli( + 2, + args, + initializeGlobalConfig, + initializeConfig); + + EXPECT_EQ(1, exit_code); + + // When ping with DB name, exception will happen + args[0] = "sonic-db-cli"; + args[1] = "TEST_DB"; + args[2] = "PING"; + + bool exception_happen = false; + try + { + optind = 0; + exit_code = sonic_db_cli( + 3, + args, + initializeGlobalConfig, + initializeConfig); + } + catch (const exception& e) + { + exception_happen = true; + } + + EXPECT_EQ(true, exception_happen); +} + TEST(sonic_db_cli, test_cli_save_cmd) { char *args[2];