Skip to content

Commit 04a9f79

Browse files
mint570divyagayathri-hcl
authored andcommitted
Upstream SONiC getWarmStartState() API and Create returnWarmStartState as a wrapper.
1 parent fe4304a commit 04a9f79

File tree

3 files changed

+113
-12
lines changed

3 files changed

+113
-12
lines changed

common/warm_restart.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,6 @@ void WarmStart::getWarmStartState(const std::string &app_name, WarmStartState &s
300300

301301
auto& warmStart = getInstance();
302302

303-
state = RECONCILED;
304-
305-
if (!isWarmStart())
306-
{
307-
return;
308-
}
309-
310303
if (app_name == warmStart.m_appName &&
311304
warmStart.m_warmbootState != WSUNKNOWN) {
312305
/* Cache is up-to-date. Read state from cache. */
@@ -316,9 +309,6 @@ void WarmStart::getWarmStartState(const std::string &app_name, WarmStartState &s
316309

317310
warmStart.m_stateWarmRestartTable->hget(app_name, "state", statestr);
318311

319-
/* If warm-start is enabled, state cannot be assumed as Reconciled
320-
* It should be set to unknown
321-
*/
322312
state = WSUNKNOWN;
323313

324314
for (auto it = warmStartStateNameMap()->begin(); it != warmStartStateNameMap()->end(); it++)
@@ -341,6 +331,15 @@ void WarmStart::getWarmStartState(const std::string &app_name, WarmStartState &s
341331
return;
342332
}
343333

334+
// Wrap getWarmStartState to return state vs passing a state variable by
335+
// reference. SWIG (for python) does not handle passing enum by reference
336+
// cleanly.
337+
WarmStart::WarmStartState WarmStart::returnWarmStartState(const std::string &app_name)
338+
{
339+
WarmStartState state;
340+
getWarmStartState(app_name, state);
341+
return state;
342+
}
344343
// Set the WarmStart FSM state for a particular application.
345344
void WarmStart::setWarmStartState(const std::string &app_name, WarmStartState state)
346345
{
@@ -416,4 +415,24 @@ WarmStart::DataCheckState WarmStart::getDataCheckState(const std::string &app_na
416415
return state;
417416
}
418417

418+
bool WarmStart::isStateVerificationEnabled()
419+
{
420+
auto& warmStart = getInstance();
421+
422+
std::string value;
423+
warmStart.m_stateWarmRestartEnableTable->hget("system",
424+
"state_verification", value);
425+
if (value == "true")
426+
{
427+
return true;
428+
}
429+
return false;
430+
}
431+
432+
bool WarmStart::waitForUnfreeze()
433+
{
434+
// Wait for unfreeze notification only if state verification is enabled.
435+
return isStateVerificationEnabled();
436+
}
437+
419438
} // namespace swss

common/warm_restart.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class WarmStart
6666

6767
static WarmStart &getInstance(void);
6868

69+
static void updateStateOnColdBoot(const std::string& app_name);
70+
6971
static void initialize(const std::string &app_name,
7072
const std::string &docker_name,
7173
unsigned int db_timeout = 0,
@@ -86,6 +88,10 @@ class WarmStart
8688
static void getWarmStartState(const std::string &app_name,
8789
WarmStartState &state);
8890

91+
// For python via SWIG: return state instead of passing state
92+
// variable by reference as a parameter.
93+
static WarmStartState returnWarmStartState(const std::string &app_name);
94+
8995
static void setWarmStartState(const std::string &app_name,
9096
WarmStartState state);
9197

@@ -98,6 +104,8 @@ class WarmStart
98104

99105
static DataCheckState getDataCheckState(const std::string &app_name,
100106
DataCheckStage stage);
107+
static bool isStateVerificationEnabled();
108+
static bool waitForUnfreeze();
101109
private:
102110
std::shared_ptr<swss::DBConnector> m_stateDb;
103111
std::shared_ptr<swss::DBConnector> m_cfgDb;

tests/warm_restart_ut.cpp

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,28 @@ using namespace swss;
1111
static const string testAppName = "TestApp";
1212
static const string testDockerName = "TestDocker";
1313

14+
void verifyWarmbootState(std::string app,
15+
WarmStart::WarmStartState expected_state)
16+
{
17+
WarmStart::WarmStartState state;
18+
WarmStart::getWarmStartState(app, state);
19+
EXPECT_EQ(state, expected_state);
20+
21+
DBConnector stateDb("STATE_DB", 0, true);
22+
Table stateWarmRestartTable(&stateDb, STATE_WARM_RESTART_TABLE_NAME);
23+
std::string state_str;
24+
stateWarmRestartTable.hget(app, "state", state_str);
25+
EXPECT_EQ(state_str, WarmStart::warmStartStateNameMap()->at(state).c_str());
26+
}
27+
28+
void configureStateVerification(std::string value)
29+
{
30+
DBConnector stateDb("STATE_DB", 0, true);
31+
Table stateWarmRestartEnableTable(&stateDb,
32+
STATE_WARM_RESTART_ENABLE_TABLE_NAME);
33+
stateWarmRestartEnableTable.hset("system", "state_verification", value);
34+
}
35+
1436
// This test must be executed before first successful call to initialize()
1537
// The static elements of this class can only be initialized once.
1638
TEST(WarmRestart, testRegisterWarmBootInfoNotInitialized)
@@ -144,8 +166,6 @@ TEST(WarmRestart, checkWarmStart_and_State)
144166
EXPECT_FALSE(system_enabled);
145167
}
146168

147-
148-
149169
TEST(WarmRestart, getWarmStartTimer)
150170
{
151171
DBConnector configDb("CONFIG_DB", 0, true);
@@ -362,3 +382,57 @@ TEST(WarmRestart, testRegisterWarmBootInfo)
362382
EXPECT_TRUE(ret);
363383
EXPECT_EQ(value, "true");
364384
}
385+
386+
TEST(WarmRestart, testOptionalStateVerification)
387+
{
388+
DBConnector stateDb("STATE_DB", 0, true);
389+
Table stateWarmRestartTable(&stateDb, STATE_WARM_RESTART_TABLE_NAME);
390+
Table stateWarmRestartEnableTable(&stateDb,
391+
STATE_WARM_RESTART_ENABLE_TABLE_NAME);
392+
393+
DBConnector configDb("CONFIG_DB", 0, true);
394+
Table cfgWarmRestartTable(&configDb, CFG_WARM_RESTART_TABLE_NAME);
395+
396+
// Clean up warm restart state for testAppName and warm restart config for
397+
// testDockerName
398+
stateWarmRestartTable.del(testAppName);
399+
cfgWarmRestartTable.del(testDockerName);
400+
stateWarmRestartEnableTable.del("system");
401+
stateWarmRestartEnableTable.del(testDockerName);
402+
403+
// Initialize WarmStart class for TestApp
404+
WarmStart::initialize(testAppName, testDockerName, 0, true);
405+
406+
// perform checkWarmStart for TestApp running in TestDocker. This updates
407+
// warmboot state in the DB.
408+
EXPECT_FALSE(WarmStart::checkWarmStart(testAppName, testDockerName));
409+
410+
// State verification is disabled by default.
411+
EXPECT_FALSE(WarmStart::isStateVerificationEnabled());
412+
EXPECT_FALSE(WarmStart::waitForUnfreeze());
413+
// Since state verification is disabled by default, warmboot state should be
414+
// RECONCILED.
415+
verifyWarmbootState(testAppName, WarmStart::RECONCILED);
416+
417+
// Disable system level warm restart. Verify that checkWarmStart() still
418+
// updates warmboot state to RECONCILED since state verification is disabled
419+
// by default.
420+
stateWarmRestartEnableTable.hset("system", "enable", "false");
421+
EXPECT_FALSE(WarmStart::isStateVerificationEnabled());
422+
EXPECT_FALSE(WarmStart::waitForUnfreeze());
423+
EXPECT_FALSE(WarmStart::checkWarmStart(testAppName, testDockerName));
424+
verifyWarmbootState(testAppName, WarmStart::RECONCILED);
425+
426+
// Set warmboot state and enable system level warm restart. Verify that
427+
// warmboot state reflects the configured state and doesn't get updated by
428+
// checkWarmStart().
429+
WarmStart::setWarmStartState(testAppName, WarmStart::INITIALIZED);
430+
stateWarmRestartEnableTable.hset("system", "enable", "true");
431+
EXPECT_TRUE(WarmStart::checkWarmStart(testAppName, testDockerName));
432+
verifyWarmbootState(testAppName, WarmStart::INITIALIZED);
433+
434+
// Disable state verification.
435+
configureStateVerification("false");
436+
EXPECT_FALSE(WarmStart::isStateVerificationEnabled());
437+
EXPECT_FALSE(WarmStart::waitForUnfreeze());
438+
}

0 commit comments

Comments
 (0)