@@ -23,6 +23,8 @@ namespace rebootbackend {
23
23
#define TWO_SECONDS (2 )
24
24
#define TENTH_SECOND_MS (100 )
25
25
#define SELECT_TIMEOUT_250_MS (250 )
26
+ #define ONE_SECOND_MS (1000 )
27
+ #define TWO_SECONDS_MS (2000 )
26
28
27
29
namespace gpu = ::google::protobuf::util;
28
30
using namespace gnoi ::system;
@@ -59,6 +61,7 @@ class RebootBETestWithoutStop : public ::testing::Test {
59
61
m_rebootbeReponseChannel(&m_db, REBOOT_RESPONSE_NOTIFICATION_CHANNEL),
60
62
m_rebootbe(m_dbus_interface) {
61
63
sigterm_requested = false ;
64
+ // TestUtils::clear_tables(m_db);
62
65
63
66
m_s.addSelectable (&m_rebootbeReponseChannel);
64
67
@@ -69,6 +72,15 @@ class RebootBETestWithoutStop : public ::testing::Test {
69
72
}
70
73
virtual ~RebootBETestWithoutStop () = default ;
71
74
75
+ void force_warm_start_state (bool enabled) {
76
+ swss::Table enable_table (&m_db, STATE_WARM_RESTART_ENABLE_TABLE_NAME);
77
+ enable_table.hset (" system" , " enable" , enabled ? " true" : " false" );
78
+ enable_table.hset (" sonic-framework" , " enable" , enabled ? " true" : " false" );
79
+
80
+ swss::Table restart_table (&m_db, STATE_WARM_RESTART_TABLE_NAME);
81
+ restart_table.hset (" rebootbackend" , " restore_count" , enabled ? " 0" : " " );
82
+ }
83
+
72
84
void start_rebootbe () {
73
85
m_rebootbe_thread =
74
86
std::make_unique<std::thread>(&RebootBE::Start, &m_rebootbe);
@@ -194,6 +206,48 @@ class RebootBETest : public RebootBETestWithoutStop {
194
206
}
195
207
};
196
208
209
+ TEST_F (RebootBETest, WarmbootInProgressBlocksNewWarmboot) {
210
+ force_warm_start_state (true );
211
+
212
+ start_rebootbe ();
213
+ std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
214
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (),
215
+ RebootBE::RebManagerStatus::WARM_INIT_WAIT);
216
+
217
+ // Send a warmboot request, confirm it fails.
218
+ RebootRequest request;
219
+ request.set_method (RebootMethod::WARM);
220
+ start_reboot_via_rpc (request, swss::StatusCode::SWSS_RC_IN_USE);
221
+
222
+ std::this_thread::sleep_for (std::chrono::milliseconds (TENTH_SECOND_MS));
223
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (),
224
+ RebootBE::RebManagerStatus::WARM_INIT_WAIT);
225
+ force_warm_start_state (false );
226
+ }
227
+
228
+ TEST_F (RebootBETest, ColdbootWhileWarmbootInProgress) {
229
+ force_warm_start_state (true );
230
+ set_mock_defaults ();
231
+
232
+ start_rebootbe ();
233
+ std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
234
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (),
235
+ RebootBE::RebManagerStatus::WARM_INIT_WAIT);
236
+
237
+ // Send a coldboot request, confirm it starts.
238
+ RebootRequest request;
239
+ request.set_method (RebootMethod::COLD);
240
+ start_reboot_via_rpc (request);
241
+
242
+ std::this_thread::sleep_for (std::chrono::milliseconds (TENTH_SECOND_MS));
243
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (),
244
+ RebootBE::RebManagerStatus::COLD_REBOOT_IN_PROGRESS);
245
+
246
+ // Cleanup without going through the whole reboot.
247
+ send_stop_reboot_thread ();
248
+ force_warm_start_state (false );
249
+ }
250
+
197
251
// Test fixture to skip through the startup sequence into the main loop.
198
252
// Param indicates if RebootBE should be initialized into a state where the
199
253
// system came up in warmboot.
@@ -203,7 +257,8 @@ class RebootBEAutoStartTest : public RebootBETest,
203
257
RebootBEAutoStartTest () {
204
258
start_rebootbe ();
205
259
206
- std::this_thread::sleep_for (std::chrono::milliseconds (50 ));
260
+ // std::this_thread::sleep_for(std::chrono::milliseconds(50));
261
+ std::this_thread::sleep_for (std::chrono::milliseconds (ONE_SECOND_MS));
207
262
EXPECT_EQ (m_rebootbe.GetCurrentStatus (), RebootBE::RebManagerStatus::IDLE);
208
263
}
209
264
};
@@ -300,6 +355,30 @@ TEST_P(RebootBEAutoStartTest, TestColdRebootDbusToCompletion) {
300
355
" platform failed to reboot" ));
301
356
}
302
357
358
+ TEST_P (RebootBEAutoStartTest, TestWarmRebootDbusToCompletion) {
359
+ DbusInterface::DbusResponse dbus_response{
360
+ DbusInterface::DbusStatus::DBUS_SUCCESS, " " };
361
+ EXPECT_CALL (m_dbus_interface, Reboot (_))
362
+ .Times (1 )
363
+ .WillRepeatedly (Return (dbus_response));
364
+
365
+ overwrite_reboot_timeout (1 );
366
+ RebootRequest request;
367
+ request.set_method (RebootMethod::WARM);
368
+ start_reboot_via_rpc (request);
369
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (),
370
+ RebootBE::RebManagerStatus::WARM_REBOOT_IN_PROGRESS);
371
+
372
+ sleep (TWO_SECONDS);
373
+
374
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (), RebootBE::RebManagerStatus::IDLE);
375
+ gnoi::system ::RebootStatusResponse response = do_reboot_status_rpc ();
376
+ EXPECT_THAT (response, ActiveCountMethod (false , 1 , RebootMethod::WARM));
377
+ EXPECT_THAT (response,
378
+ IsStatus (RebootStatus_Status::RebootStatus_Status_STATUS_FAILURE,
379
+ " failed to warm reboot" ));
380
+ }
381
+
303
382
TEST_P (RebootBEAutoStartTest, TestColdBootSigterm) {
304
383
sigterm_requested = true ;
305
384
set_mock_defaults ();
@@ -319,6 +398,25 @@ TEST_P(RebootBEAutoStartTest, TestColdBootSigterm) {
319
398
IsStatus (RebootStatus_Status::RebootStatus_Status_STATUS_UNKNOWN, " " ));
320
399
}
321
400
401
+ TEST_P (RebootBEAutoStartTest, TestWarmBootSigterm) {
402
+ sigterm_requested = true ;
403
+ set_mock_defaults ();
404
+ overwrite_reboot_timeout (1 );
405
+
406
+ RebootRequest request;
407
+ request.set_method (RebootMethod::WARM);
408
+ start_reboot_via_rpc (request);
409
+
410
+ sleep (ONE_SECOND);
411
+
412
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (), RebootBE::RebManagerStatus::IDLE);
413
+ gnoi::system ::RebootStatusResponse second_resp = do_reboot_status_rpc ();
414
+ EXPECT_THAT (second_resp, ActiveCountMethod (false , 1 , RebootMethod::WARM));
415
+ EXPECT_THAT (
416
+ second_resp,
417
+ IsStatus (RebootStatus_Status::RebootStatus_Status_STATUS_UNKNOWN, " " ));
418
+ }
419
+
322
420
TEST_P (RebootBEAutoStartTest, TestColdBootDbusError) {
323
421
// Return FAIL from dbus reboot call.
324
422
DbusInterface::DbusResponse dbus_response{
@@ -341,6 +439,28 @@ TEST_P(RebootBEAutoStartTest, TestColdBootDbusError) {
341
439
" dbus reboot failed" ));
342
440
}
343
441
442
+ TEST_P (RebootBEAutoStartTest, TestWarmBootDbusError) {
443
+ // Return FAIL from dbus reboot call.
444
+ DbusInterface::DbusResponse dbus_response{
445
+ DbusInterface::DbusStatus::DBUS_FAIL, " dbus reboot failed" };
446
+ EXPECT_CALL (m_dbus_interface, Reboot (_))
447
+ .Times (1 )
448
+ .WillOnce (Return (dbus_response));
449
+
450
+ RebootRequest request;
451
+ request.set_method (RebootMethod::WARM);
452
+ start_reboot_via_rpc (request);
453
+
454
+ sleep (TWO_SECONDS);
455
+
456
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (), RebootBE::RebManagerStatus::IDLE);
457
+ gnoi::system ::RebootStatusResponse second_resp = do_reboot_status_rpc ();
458
+ EXPECT_THAT (second_resp, ActiveCountMethod (false , 1 , RebootMethod::WARM));
459
+ EXPECT_THAT (second_resp,
460
+ IsStatus (RebootStatus_Status::RebootStatus_Status_STATUS_FAILURE,
461
+ " dbus reboot failed" ));
462
+ }
463
+
344
464
TEST_P (RebootBEAutoStartTest, TestStopDuringColdBoot) {
345
465
set_mock_defaults ();
346
466
@@ -362,12 +482,64 @@ TEST_P(RebootBEAutoStartTest, TestStopDuringColdBoot) {
362
482
IsStatus (RebootStatus_Status::RebootStatus_Status_STATUS_UNKNOWN, " " ));
363
483
}
364
484
485
+ TEST_P (RebootBEAutoStartTest, TestStopDuringWarmBoot) {
486
+ set_mock_defaults ();
487
+
488
+ RebootRequest request;
489
+ request.set_method (RebootMethod::WARM);
490
+ start_reboot_via_rpc (request);
491
+ // std::this_thread::sleep_for(std::chrono::milliseconds(TENTH_SECOND_MS));
492
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (),
493
+ RebootBE::RebManagerStatus::WARM_REBOOT_IN_PROGRESS);
494
+
495
+ send_stop_reboot_thread ();
496
+ std::this_thread::sleep_for (std::chrono::milliseconds (TENTH_SECOND_MS));
497
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (), RebootBE::RebManagerStatus::IDLE);
498
+
499
+ gnoi::system ::RebootStatusResponse response = do_reboot_status_rpc ();
500
+ EXPECT_THAT (response, ActiveCountMethod (false , 1 , RebootMethod::WARM));
501
+ EXPECT_THAT (
502
+ response,
503
+ IsStatus (RebootStatus_Status::RebootStatus_Status_STATUS_UNKNOWN, " " ));
504
+ }
505
+
365
506
TEST_P (RebootBEAutoStartTest, TestInvalidJsonRebootRequest) {
366
507
std::string json_request = " abcd" ;
367
508
NotificationResponse response = handle_reboot_request (json_request);
368
509
EXPECT_EQ (swss::StatusCode::SWSS_RC_INTERNAL, response.status );
369
510
}
370
511
512
+ TEST_P (RebootBEAutoStartTest, TestWarmFailureFollowedByColdBoot) {
513
+ DbusInterface::DbusResponse dbus_response{
514
+ DbusInterface::DbusStatus::DBUS_SUCCESS, " " };
515
+ overwrite_reboot_timeout (1 );
516
+
517
+ RebootRequest request;
518
+ request.set_method (RebootMethod::WARM);
519
+ start_reboot_via_rpc (request);
520
+
521
+ std::this_thread::sleep_for (std::chrono::milliseconds (TENTH_SECOND_MS));
522
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (),
523
+ RebootBE::RebManagerStatus::WARM_REBOOT_IN_PROGRESS);
524
+
525
+ std::this_thread::sleep_for (std::chrono::milliseconds (TWO_SECONDS_MS));
526
+ gnoi::system ::RebootStatusResponse response = do_reboot_status_rpc ();
527
+ EXPECT_THAT (response, ActiveCountMethod (false , 1 , RebootMethod::WARM));
528
+
529
+ request.set_method (RebootMethod::COLD);
530
+ start_reboot_via_rpc (request);
531
+
532
+ // We have to wait for the 1 second reboot Timeout
533
+ std::this_thread::sleep_for (std::chrono::milliseconds (TWO_SECONDS_MS));
534
+
535
+ EXPECT_EQ (m_rebootbe.GetCurrentStatus (), RebootBE::RebManagerStatus::IDLE);
536
+ response = do_reboot_status_rpc ();
537
+ EXPECT_THAT (response, ActiveCountMethod (false , 2 , RebootMethod::COLD));
538
+ EXPECT_THAT (response,
539
+ IsStatus (RebootStatus_Status::RebootStatus_Status_STATUS_FAILURE,
540
+ " platform failed to reboot" ));
541
+ }
542
+
371
543
INSTANTIATE_TEST_SUITE_P (TestWithStartupWarmbootEnabledState,
372
544
RebootBEAutoStartTest, testing::Values(true , false ));
373
545
0 commit comments