diff --git a/common/restart_waiter.cpp b/common/restart_waiter.cpp index 2fea3b5e0..77436cb75 100644 --- a/common/restart_waiter.cpp +++ b/common/restart_waiter.cpp @@ -23,6 +23,17 @@ bool RestartWaiter::waitAdvancedBootDone( return isAdvancedBootInProgress(stateDb) ? doWait(stateDb, maxWaitSec) : true; } +bool RestartWaiter::waitWarmBootStarted( + unsigned int maxWaitSec, + unsigned int dbTimeout, + bool isTcpConn) +{ + DBConnector stateDb(STATE_DB_NAME, dbTimeout, isTcpConn); + // bootEnabledTarget = "true" means wait for RESTART_ENABLE_FIELD to be set to "true", + // which indicates warm reboot has started. + return doWait(stateDb, maxWaitSec, "true"); +} + bool RestartWaiter::waitWarmBootDone( unsigned int maxWaitSec, unsigned int dbTimeout, @@ -54,12 +65,15 @@ bool RestartWaiter::waitFastBootDone( } bool RestartWaiter::doWait(DBConnector &stateDb, - unsigned int maxWaitSec) + unsigned int maxWaitSec, + const std::string &bootEnabledTarget) { - RedisTableWaiter::ConditionFunc condFunc = [](const std::string &value) -> bool { + RedisTableWaiter::ConditionFunc condFunc = [&bootEnabledTarget](const std::string &value) -> bool { std::string copy = value; boost::to_lower(copy); - return copy == "false"; + std::string target = bootEnabledTarget; + boost::to_lower(target); + return copy == target; }; return RedisTableWaiter::waitUntilFieldSet(stateDb, STATE_WARM_RESTART_ENABLE_TABLE_NAME, diff --git a/common/restart_waiter.h b/common/restart_waiter.h index 79268bfbc..12e94e7d4 100644 --- a/common/restart_waiter.h +++ b/common/restart_waiter.h @@ -13,6 +13,10 @@ class RestartWaiter unsigned int dbTimeout = 0, bool isTcpConn = false); + static bool waitWarmBootStarted(unsigned int maxWaitSec = 86400, + unsigned int dbTimeout = 0, + bool isTcpConn = false); + static bool waitWarmBootDone(unsigned int maxWaitSec = 180, unsigned int dbTimeout = 0, bool isTcpConn = false); @@ -29,7 +33,8 @@ class RestartWaiter private: static bool doWait(swss::DBConnector &stateDb, - unsigned int maxWaitSec); + unsigned int maxWaitSec, + const std::string &bootEnabledTarget = "false"); }; } diff --git a/tests/restart_waiter_ut.cpp b/tests/restart_waiter_ut.cpp index 111ecb5b7..14db665a4 100644 --- a/tests/restart_waiter_ut.cpp +++ b/tests/restart_waiter_ut.cpp @@ -67,6 +67,14 @@ TEST(RestartWaiter, successFastReboot) t.join(); } +TEST(RestartWaiter, successWarmRebootStarted) +{ + set_reboot_status("false"); + thread t(set_reboot_status, "true", 3); + EXPECT_TRUE(RestartWaiter::waitWarmBootStarted()); + t.join(); +} + TEST(RestartWaiter, timeout) { set_reboot_status("true"); @@ -77,6 +85,7 @@ TEST(RestartWaiter, timeout) EXPECT_FALSE(RestartWaiter::waitFastBootDone(1)); set_reboot_status("false"); + EXPECT_FALSE(RestartWaiter::waitWarmBootStarted(1)); } TEST(RestartWaiter, successNoDelay) @@ -87,6 +96,9 @@ TEST(RestartWaiter, successNoDelay) FastBootHelper helper; EXPECT_TRUE(RestartWaiter::waitFastBootDone()); + + set_reboot_status("true"); + EXPECT_TRUE(RestartWaiter::waitWarmBootStarted()); } TEST(RestartWaiter, successNoKey) @@ -101,6 +113,14 @@ TEST(RestartWaiter, successNoKey) EXPECT_TRUE(RestartWaiter::waitFastBootDone()); } +TEST(RestartWaiter, waitWarmBootStartedNoKeyTimesOut) +{ + DBConnector db("STATE_DB", 0); + string key = string(STATE_WARM_RESTART_ENABLE_TABLE_NAME) + string("|system"); + db.del({key}); + EXPECT_FALSE(RestartWaiter::waitWarmBootStarted(1)); +} + TEST(RestartWaiter, waitWarmButFastInProgress) { FastBootHelper helper;