forked from sonic-net/sonic-swss-common
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwarm_restart_ut.cpp
237 lines (175 loc) · 8.96 KB
/
warm_restart_ut.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#include <iostream>
#include "gtest/gtest.h"
#include "common/dbconnector.h"
#include "common/table.h"
#include "common/schema.h"
#include "common/warm_restart.h"
using namespace std;
using namespace swss;
static const string testAppName = "TestApp";
static const string testDockerName = "TestDocker";
TEST(WarmRestart, checkWarmStart_and_State)
{
DBConnector stateDb("STATE_DB", 0, true);
Table stateWarmRestartTable(&stateDb, STATE_WARM_RESTART_TABLE_NAME);
Table stateWarmRestartEnableTable(&stateDb, STATE_WARM_RESTART_ENABLE_TABLE_NAME);
DBConnector configDb("CONFIG_DB", 0, true);
Table cfgWarmRestartTable(&configDb, CFG_WARM_RESTART_TABLE_NAME);
//Clean up warm restart state for testAppName and warm restart config for testDockerName
stateWarmRestartTable.del(testAppName);
cfgWarmRestartTable.del(testDockerName);
//Initialize WarmStart class for TestApp
WarmStart::initialize(testAppName, testDockerName, 0, true);
// Application is supposed to set the warm start state explicitly based on
// its progress of state restore.
WarmStart::setWarmStartState(testAppName, WarmStart::INITIALIZED);
// state check is for external observation.
string state;
stateWarmRestartTable.hget(testAppName, "state", state);
EXPECT_EQ(state, "initialized");
// perform checkWarmStart for TestAPP running in TestDocker
WarmStart::checkWarmStart(testAppName, testDockerName);
// The "restore_count" for TestApp in stateDB should be 0 since
// warm restart has not been enabled for "system" or "TestDocker"
string value;
stateWarmRestartTable.hget(testAppName, "restore_count", value);
EXPECT_EQ(value, "0");
// warm restart is disabled by default.
bool enabled = WarmStart::isWarmStart();
EXPECT_FALSE(enabled);
// system warmreboot is disabled
bool system_enabled = WarmStart::isSystemWarmRebootEnabled();
EXPECT_FALSE(system_enabled);
// enable system level warm restart.
stateWarmRestartEnableTable.hset("system", "enable", "true");
// Do checkWarmStart for TestAPP running in TestDocker again.
// Note, this is for unit testing only. checkWarmStart() is supposed to be
// called only at the very start of a process, or when the re-initialization of
// a process is to be performed.
WarmStart::checkWarmStart(testAppName, testDockerName);
// After restoring data from DB, application reaches RESTORED state.
WarmStart::setWarmStartState(testAppName, WarmStart::RESTORED);
// Restore count should have incremented by 1.
stateWarmRestartTable.hget(testAppName, "restore_count", value);
EXPECT_EQ(value, "1");
// state check is for external observation.
stateWarmRestartTable.hget(testAppName, "state", state);
EXPECT_EQ(state, "restored");
enabled = WarmStart::isWarmStart();
EXPECT_TRUE(enabled);
system_enabled = WarmStart::isSystemWarmRebootEnabled();
EXPECT_TRUE(system_enabled);
// Usually application will sync up with latest external env as to data state,
// after that it should set the state to RECONCILED for the observation of external tools.
WarmStart::setWarmStartState(testAppName, WarmStart::RECONCILED);
// state check is for external observation.
stateWarmRestartTable.hget(testAppName, "state", state);
EXPECT_EQ(state, "reconciled");
// If the restore_count of STATE_WARM_RESTART_TABLE_NAME table has been flushed from stateDB
// for the specific application, we assume
// that all the warm restore data are not available either, the application should not
// perform warm restart, even though it is configured to do so.
stateWarmRestartTable.del(testAppName);
// This is to simulate application restart, upon restart checkWarmStart() is to called at the beginning.
WarmStart::checkWarmStart(testAppName, testDockerName);
// restore_count for the application is set to 0 again.
stateWarmRestartTable.hget(testAppName, "restore_count", value);
EXPECT_EQ(value, "0");
enabled = WarmStart::isWarmStart();
EXPECT_FALSE(enabled);
// disable system level warm restart.
stateWarmRestartEnableTable.hset("system", "enable", "false");
// Enable docker level warm restart.
stateWarmRestartEnableTable.hset(testDockerName, "enable", "true");
// Note, this is for unit testing only. checkWarmStart() is supposed to be
// called only at the very start of a process, or when the re-initialization of
// a process is to be performed.
WarmStart::checkWarmStart(testAppName, testDockerName);
// Restore count should have incremented by 1.
stateWarmRestartTable.hget(testAppName, "restore_count", value);
EXPECT_EQ(value, "1");
// Test checkWarmStart function without increment restore count
WarmStart::checkWarmStart(testAppName, testDockerName, false);
// Restore count should still be 1.
stateWarmRestartTable.hget(testAppName, "restore_count", value);
EXPECT_EQ(value, "1");
enabled = WarmStart::isWarmStart();
EXPECT_TRUE(enabled);
system_enabled = WarmStart::isSystemWarmRebootEnabled();
EXPECT_FALSE(system_enabled);
}
TEST(WarmRestart, getWarmStartTimer)
{
DBConnector configDb("CONFIG_DB", 0, true);
Table cfgWarmRestartTable(&configDb, CFG_WARM_RESTART_TABLE_NAME);
//Initialize WarmStart class for TestApp
WarmStart::initialize(testAppName, testDockerName, 0, true);
uint32_t timer;
// By default, no default warm start timer exists in configDB for any application
// value 0 is returned for empty configuration.
timer = WarmStart::getWarmStartTimer(testAppName, testDockerName);
EXPECT_EQ(timer, 0u);
// config manager is supposed to make the setting.
cfgWarmRestartTable.hset(testDockerName, testAppName + "_timer", "5000");
timer = WarmStart::getWarmStartTimer(testAppName, testDockerName);
EXPECT_EQ(timer, 5000u);
}
TEST(WarmRestart, set_get_DataCheckState)
{
DBConnector stateDb("STATE_DB", 0, true);
Table stateWarmRestartTable(&stateDb, STATE_WARM_RESTART_TABLE_NAME);
//Clean up warm restart state for testAppName
stateWarmRestartTable.del(testAppName);
//Initialize WarmStart class for TestApp
WarmStart::initialize(testAppName, testDockerName, 0, true);
WarmStart::DataCheckState state;
// basic state set check for shutdown stage
string value;
bool ret = stateWarmRestartTable.hget(testAppName, "shutdown_check", value);
EXPECT_FALSE(ret);
EXPECT_EQ(value, "");
state = WarmStart::getDataCheckState(testAppName, WarmStart::STAGE_SHUTDOWN);
EXPECT_EQ(state, WarmStart::CHECK_IGNORED);
WarmStart::setDataCheckState(testAppName, WarmStart::STAGE_SHUTDOWN, WarmStart::CHECK_IGNORED);
ret = stateWarmRestartTable.hget(testAppName, "shutdown_check", value);
EXPECT_TRUE(ret);
EXPECT_EQ(value, "ignored");
state = WarmStart::getDataCheckState(testAppName, WarmStart::STAGE_SHUTDOWN);
EXPECT_EQ(state, WarmStart::CHECK_IGNORED);
WarmStart::setDataCheckState(testAppName, WarmStart::STAGE_SHUTDOWN, WarmStart::CHECK_PASSED);
ret = stateWarmRestartTable.hget(testAppName, "shutdown_check", value);
EXPECT_TRUE(ret);
EXPECT_EQ(value, "passed");
state = WarmStart::getDataCheckState(testAppName, WarmStart::STAGE_SHUTDOWN);
EXPECT_EQ(state, WarmStart::CHECK_PASSED);
WarmStart::setDataCheckState(testAppName, WarmStart::STAGE_SHUTDOWN, WarmStart::CHECK_FAILED);
ret = stateWarmRestartTable.hget(testAppName, "shutdown_check", value);
EXPECT_TRUE(ret);
EXPECT_EQ(value, "failed");
state = WarmStart::getDataCheckState(testAppName, WarmStart::STAGE_SHUTDOWN);
EXPECT_EQ(state, WarmStart::CHECK_FAILED);
// basic state set check for restore stage
ret = stateWarmRestartTable.hget(testAppName, "restore_check", value);
EXPECT_FALSE(ret);
EXPECT_EQ(value, "");
state = WarmStart::getDataCheckState(testAppName, WarmStart::STAGE_RESTORE);
EXPECT_EQ(state, WarmStart::CHECK_IGNORED);
WarmStart::setDataCheckState(testAppName, WarmStart::STAGE_RESTORE, WarmStart::CHECK_IGNORED);
ret = stateWarmRestartTable.hget(testAppName, "restore_check", value);
EXPECT_TRUE(ret);
EXPECT_EQ(value, "ignored");
state = WarmStart::getDataCheckState(testAppName, WarmStart::STAGE_RESTORE);
EXPECT_EQ(state, WarmStart::CHECK_IGNORED);
WarmStart::setDataCheckState(testAppName, WarmStart::STAGE_RESTORE, WarmStart::CHECK_PASSED);
ret = stateWarmRestartTable.hget(testAppName, "restore_check", value);
EXPECT_TRUE(ret);
EXPECT_EQ(value, "passed");
state = WarmStart::getDataCheckState(testAppName, WarmStart::STAGE_RESTORE);
EXPECT_EQ(state, WarmStart::CHECK_PASSED);
WarmStart::setDataCheckState(testAppName, WarmStart::STAGE_RESTORE, WarmStart::CHECK_FAILED);
ret = stateWarmRestartTable.hget(testAppName, "restore_check", value);
EXPECT_TRUE(ret);
EXPECT_EQ(value, "failed");
state = WarmStart::getDataCheckState(testAppName, WarmStart::STAGE_RESTORE);
EXPECT_EQ(state, WarmStart::CHECK_FAILED);
}