1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "test/rbd_mirror/test_mock_fixture.h"
5 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
6 #include "test/librados_test_stub/MockTestMemRadosClient.h"
7 #include "test/librbd/mock/MockImageCtx.h"
8 #include "test/rbd_mirror/mock/MockContextWQ.h"
9 #include "test/rbd_mirror/mock/MockSafeTimer.h"
10 #include "librbd/MirroringWatcher.h"
11 #include "tools/rbd_mirror/Threads.h"
12 #include "tools/rbd_mirror/PoolWatcher.h"
13 #include "tools/rbd_mirror/pool_watcher/RefreshImagesRequest.h"
14 #include "include/stringify.h"
19 struct MockTestImageCtx
: public librbd::MockImageCtx
{
20 MockTestImageCtx(librbd::ImageCtx
&image_ctx
)
21 : librbd::MockImageCtx(image_ctx
) {
25 } // anonymous namespace
27 struct MockMirroringWatcher
{
28 static MockMirroringWatcher
*s_instance
;
29 static MockMirroringWatcher
&get_instance() {
30 assert(s_instance
!= nullptr);
34 MockMirroringWatcher() {
38 MOCK_CONST_METHOD0(is_unregistered
, bool());
39 MOCK_METHOD1(register_watch
, void(Context
*));
40 MOCK_METHOD1(unregister_watch
, void(Context
*));
42 MOCK_CONST_METHOD0(get_oid
, std::string());
46 struct MirroringWatcher
<MockTestImageCtx
> {
47 static MirroringWatcher
*s_instance
;
49 MirroringWatcher(librados::IoCtx
&io_ctx
, ::MockContextWQ
*work_queue
) {
52 virtual ~MirroringWatcher() {
55 static MirroringWatcher
<MockTestImageCtx
> &get_instance() {
56 assert(s_instance
!= nullptr);
60 virtual void handle_rewatch_complete(int r
) = 0;
62 virtual void handle_mode_updated(cls::rbd::MirrorMode mirror_mode
) = 0;
63 virtual void handle_image_updated(cls::rbd::MirrorImageState state
,
64 const std::string
&remote_image_id
,
65 const std::string
&global_image_id
) = 0;
67 bool is_unregistered() const {
68 return MockMirroringWatcher::get_instance().is_unregistered();
70 void register_watch(Context
*ctx
) {
71 MockMirroringWatcher::get_instance().register_watch(ctx
);
73 void unregister_watch(Context
*ctx
) {
74 MockMirroringWatcher::get_instance().unregister_watch(ctx
);
76 std::string
get_oid() const {
77 return MockMirroringWatcher::get_instance().get_oid();
81 MockMirroringWatcher
*MockMirroringWatcher::s_instance
= nullptr;
82 MirroringWatcher
<MockTestImageCtx
> *MirroringWatcher
<MockTestImageCtx
>::s_instance
= nullptr;
90 struct Threads
<librbd::MockTestImageCtx
> {
94 MockContextWQ
*work_queue
;
96 Threads(Threads
<librbd::ImageCtx
> *threads
)
97 : timer(new MockSafeTimer()),
98 timer_lock(threads
->timer_lock
),
99 work_queue(new MockContextWQ()) {
107 namespace pool_watcher
{
110 struct RefreshImagesRequest
<librbd::MockTestImageCtx
> {
111 ImageIds
*image_ids
= nullptr;
112 Context
*on_finish
= nullptr;
113 static RefreshImagesRequest
*s_instance
;
114 static RefreshImagesRequest
*create(librados::IoCtx
&io_ctx
,
116 Context
*on_finish
) {
117 assert(s_instance
!= nullptr);
118 s_instance
->image_ids
= image_ids
;
119 s_instance
->on_finish
= on_finish
;
123 MOCK_METHOD0(send
, void());
125 RefreshImagesRequest() {
130 RefreshImagesRequest
<librbd::MockTestImageCtx
> *RefreshImagesRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
132 } // namespace pool_watcher
134 } // namespace mirror
137 // template definitions
138 #include "tools/rbd_mirror/PoolWatcher.cc"
144 using ::testing::DoAll
;
145 using ::testing::InSequence
;
146 using ::testing::Invoke
;
147 using ::testing::Return
;
148 using ::testing::StrEq
;
149 using ::testing::WithArg
;
150 using ::testing::WithoutArgs
;
152 class TestMockPoolWatcher
: public TestMockFixture
{
154 typedef PoolWatcher
<librbd::MockTestImageCtx
> MockPoolWatcher
;
155 typedef Threads
<librbd::MockTestImageCtx
> MockThreads
;
156 typedef pool_watcher::RefreshImagesRequest
<librbd::MockTestImageCtx
> MockRefreshImagesRequest
;
157 typedef librbd::MockMirroringWatcher MockMirroringWatcher
;
158 typedef librbd::MirroringWatcher
<librbd::MockTestImageCtx
> MirroringWatcher
;
160 struct MockListener
: MockPoolWatcher::Listener
{
161 TestMockPoolWatcher
*test
;
163 MockListener(TestMockPoolWatcher
*test
) : test(test
) {
166 MOCK_METHOD3(mock_handle_update
, void(const std::string
&, const ImageIds
&,
168 void handle_update(const std::string
&mirror_uuid
,
169 ImageIds
&&added_image_ids
,
170 ImageIds
&&removed_image_ids
) override
{
171 mock_handle_update(mirror_uuid
, added_image_ids
, removed_image_ids
);
175 TestMockPoolWatcher() : m_lock("TestMockPoolWatcher::m_lock") {
178 void expect_work_queue(MockThreads
&mock_threads
) {
179 EXPECT_CALL(*mock_threads
.work_queue
, queue(_
, _
))
180 .WillRepeatedly(Invoke([this](Context
*ctx
, int r
) {
181 m_threads
->work_queue
->queue(ctx
, r
);
185 void expect_mirroring_watcher_is_unregistered(MockMirroringWatcher
&mock_mirroring_watcher
,
187 EXPECT_CALL(mock_mirroring_watcher
, is_unregistered())
188 .WillOnce(Return(unregistered
));
191 void expect_mirroring_watcher_register(MockMirroringWatcher
&mock_mirroring_watcher
,
193 EXPECT_CALL(mock_mirroring_watcher
, register_watch(_
))
194 .WillOnce(CompleteContext(r
));
197 void expect_mirroring_watcher_unregister(MockMirroringWatcher
&mock_mirroring_watcher
,
199 EXPECT_CALL(mock_mirroring_watcher
, unregister_watch(_
))
200 .WillOnce(CompleteContext(r
));
203 void expect_refresh_images(MockRefreshImagesRequest
&request
,
204 const ImageIds
&image_ids
, int r
) {
205 EXPECT_CALL(request
, send())
206 .WillOnce(Invoke([&request
, image_ids
, r
]() {
207 *request
.image_ids
= image_ids
;
208 request
.on_finish
->complete(r
);
212 void expect_listener_handle_update(MockListener
&mock_listener
,
213 const std::string
&mirror_uuid
,
214 const ImageIds
&added_image_ids
,
215 const ImageIds
&removed_image_ids
) {
216 EXPECT_CALL(mock_listener
, mock_handle_update(mirror_uuid
, added_image_ids
,
218 .WillOnce(WithoutArgs(Invoke([this]() {
219 Mutex::Locker
locker(m_lock
);
225 void expect_mirror_uuid_get(librados::IoCtx
&io_ctx
,
226 const std::string
&uuid
, int r
) {
228 ::encode(uuid
, out_bl
);
230 EXPECT_CALL(get_mock_io_ctx(io_ctx
),
231 exec(RBD_MIRRORING
, _
, StrEq("rbd"), StrEq("mirror_uuid_get"),
233 .WillOnce(DoAll(WithArg
<5>(Invoke([this, out_bl
](bufferlist
*bl
) {
239 void expect_timer_add_event(MockThreads
&mock_threads
) {
240 EXPECT_CALL(*mock_threads
.timer
, add_event_after(_
, _
))
241 .WillOnce(WithArg
<1>(Invoke([this](Context
*ctx
) {
242 auto wrapped_ctx
= new FunctionContext([this, ctx
](int r
) {
243 Mutex::Locker
timer_locker(m_threads
->timer_lock
);
246 m_threads
->work_queue
->queue(wrapped_ctx
, 0);
250 int when_shut_down(MockPoolWatcher
&mock_pool_watcher
) {
252 mock_pool_watcher
.shut_down(&ctx
);
256 bool wait_for_update(uint32_t count
) {
257 Mutex::Locker
locker(m_lock
);
258 while (m_update_count
< count
) {
259 if (m_cond
.WaitInterval(m_lock
, utime_t(10, 0)) != 0) {
263 if (m_update_count
< count
) {
267 m_update_count
-= count
;
273 uint32_t m_update_count
= 0;
276 TEST_F(TestMockPoolWatcher
, EmptyPool
) {
277 MockThreads
mock_threads(m_threads
);
278 expect_work_queue(mock_threads
);
281 MockMirroringWatcher mock_mirroring_watcher
;
282 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
283 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
285 MockRefreshImagesRequest mock_refresh_images_request
;
286 expect_refresh_images(mock_refresh_images_request
, {}, 0);
287 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
289 MockListener
mock_listener(this);
290 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
292 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
295 mock_pool_watcher
.init(&ctx
);
296 ASSERT_EQ(0, ctx
.wait());
298 ASSERT_TRUE(wait_for_update(1));
299 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
300 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
303 TEST_F(TestMockPoolWatcher
, NonEmptyPool
) {
304 MockThreads
mock_threads(m_threads
);
305 expect_work_queue(mock_threads
);
308 MockMirroringWatcher mock_mirroring_watcher
;
309 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
310 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
313 {"global id 1", "remote id 1"},
314 {"global id 2", "remote id 2"}};
315 MockRefreshImagesRequest mock_refresh_images_request
;
316 expect_refresh_images(mock_refresh_images_request
, image_ids
, 0);
317 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
319 MockListener
mock_listener(this);
320 expect_listener_handle_update(mock_listener
, "remote uuid", image_ids
, {});
322 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
325 mock_pool_watcher
.init(&ctx
);
326 ASSERT_EQ(0, ctx
.wait());
328 ASSERT_TRUE(wait_for_update(1));
329 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
330 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
333 TEST_F(TestMockPoolWatcher
, NotifyDuringRefresh
) {
334 MockThreads
mock_threads(m_threads
);
335 expect_work_queue(mock_threads
);
338 MockMirroringWatcher mock_mirroring_watcher
;
339 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
340 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
343 {"global id 1", "remote id 1"},
344 {"global id 2", "remote id 2"}};
345 MockRefreshImagesRequest mock_refresh_images_request
;
346 bool refresh_sent
= false;
347 EXPECT_CALL(mock_refresh_images_request
, send())
348 .WillOnce(Invoke([this, &mock_refresh_images_request
, &image_ids
,
350 *mock_refresh_images_request
.image_ids
= image_ids
;
352 Mutex::Locker
locker(m_lock
);
357 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
359 MockListener
mock_listener(this);
361 {"global id 1", "remote id 1a"},
362 {"global id 3", "remote id 3"}};
363 expect_listener_handle_update(mock_listener
, "remote uuid", image_ids
, {});
365 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
367 mock_pool_watcher
.init(nullptr);
370 Mutex::Locker
locker(m_lock
);
371 while (!refresh_sent
) {
376 MirroringWatcher::get_instance().handle_image_updated(
377 cls::rbd::MIRROR_IMAGE_STATE_DISABLING
, "remote id 2", "global id 2");
378 MirroringWatcher::get_instance().handle_image_updated(
379 cls::rbd::MIRROR_IMAGE_STATE_ENABLED
, "remote id 1a", "global id 1");
380 MirroringWatcher::get_instance().handle_image_updated(
381 cls::rbd::MIRROR_IMAGE_STATE_ENABLED
, "remote id 3", "global id 3");
383 mock_refresh_images_request
.on_finish
->complete(0);
384 ASSERT_TRUE(wait_for_update(1));
386 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
387 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
390 TEST_F(TestMockPoolWatcher
, Notify
) {
391 MockThreads
mock_threads(m_threads
);
394 MockMirroringWatcher mock_mirroring_watcher
;
395 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
396 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
399 {"global id 1", "remote id 1"},
400 {"global id 2", "remote id 2"}};
401 MockRefreshImagesRequest mock_refresh_images_request
;
402 expect_refresh_images(mock_refresh_images_request
, image_ids
, 0);
403 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
405 EXPECT_CALL(*mock_threads
.work_queue
, queue(_
, _
))
406 .WillOnce(Invoke([this](Context
*ctx
, int r
) {
407 m_threads
->work_queue
->queue(ctx
, r
);
410 MockListener
mock_listener(this);
411 expect_listener_handle_update(mock_listener
, "remote uuid", image_ids
, {});
413 Context
*notify_ctx
= nullptr;
414 EXPECT_CALL(*mock_threads
.work_queue
, queue(_
, _
))
415 .WillOnce(Invoke([this, ¬ify_ctx
](Context
*ctx
, int r
) {
416 Mutex::Locker
locker(m_lock
);
417 ASSERT_EQ(nullptr, notify_ctx
);
421 expect_listener_handle_update(
422 mock_listener
, "remote uuid",
423 {{"global id 1", "remote id 1a"}, {"global id 3", "remote id 3"}},
424 {{"global id 1", "remote id 1"}, {"global id 2", "remote id 2"}});
426 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
429 mock_pool_watcher
.init(&ctx
);
430 ASSERT_EQ(0, ctx
.wait());
431 ASSERT_TRUE(wait_for_update(1));
433 C_SaferCond flush_ctx
;
434 m_threads
->work_queue
->queue(&flush_ctx
, 0);
435 ASSERT_EQ(0, flush_ctx
.wait());
437 MirroringWatcher::get_instance().handle_image_updated(
438 cls::rbd::MIRROR_IMAGE_STATE_DISABLING
, "remote id 2", "global id 2");
439 MirroringWatcher::get_instance().handle_image_updated(
440 cls::rbd::MIRROR_IMAGE_STATE_DISABLED
, "remote id 2", "global id 2");
441 MirroringWatcher::get_instance().handle_image_updated(
442 cls::rbd::MIRROR_IMAGE_STATE_ENABLED
, "remote id 1a", "global id 1");
443 MirroringWatcher::get_instance().handle_image_updated(
444 cls::rbd::MIRROR_IMAGE_STATE_ENABLED
, "remote id 3", "global id 3");
445 notify_ctx
->complete(0);
447 ASSERT_TRUE(wait_for_update(1));
449 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
450 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
453 TEST_F(TestMockPoolWatcher
, RegisterWatcherBlacklist
) {
454 MockThreads
mock_threads(m_threads
);
455 expect_work_queue(mock_threads
);
458 MockMirroringWatcher mock_mirroring_watcher
;
459 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
460 expect_mirroring_watcher_register(mock_mirroring_watcher
, -EBLACKLISTED
);
462 MockListener
mock_listener(this);
463 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
466 mock_pool_watcher
.init(&ctx
);
467 ASSERT_EQ(-EBLACKLISTED
, ctx
.wait());
468 ASSERT_TRUE(mock_pool_watcher
.is_blacklisted());
470 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
471 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
474 TEST_F(TestMockPoolWatcher
, RegisterWatcherMissing
) {
475 MockThreads
mock_threads(m_threads
);
476 expect_work_queue(mock_threads
);
479 MockMirroringWatcher mock_mirroring_watcher
;
480 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
481 expect_mirroring_watcher_register(mock_mirroring_watcher
, -ENOENT
);
482 expect_timer_add_event(mock_threads
);
484 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
485 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
487 MockRefreshImagesRequest mock_refresh_images_request
;
488 expect_refresh_images(mock_refresh_images_request
, {}, 0);
489 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
491 MockListener
mock_listener(this);
492 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
494 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
497 mock_pool_watcher
.init(&ctx
);
498 ASSERT_EQ(0, ctx
.wait());
500 ASSERT_TRUE(wait_for_update(1));
501 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
502 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
505 TEST_F(TestMockPoolWatcher
, RegisterWatcherError
) {
506 MockThreads
mock_threads(m_threads
);
507 expect_work_queue(mock_threads
);
510 MockMirroringWatcher mock_mirroring_watcher
;
511 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
512 expect_mirroring_watcher_register(mock_mirroring_watcher
, -EINVAL
);
513 expect_timer_add_event(mock_threads
);
515 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
516 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
518 MockRefreshImagesRequest mock_refresh_images_request
;
519 expect_refresh_images(mock_refresh_images_request
, {}, 0);
520 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
522 MockListener
mock_listener(this);
523 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
525 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
528 mock_pool_watcher
.init(&ctx
);
529 ASSERT_EQ(0, ctx
.wait());
531 ASSERT_TRUE(wait_for_update(1));
532 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
533 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
536 TEST_F(TestMockPoolWatcher
, RefreshBlacklist
) {
537 MockThreads
mock_threads(m_threads
);
538 expect_work_queue(mock_threads
);
541 MockMirroringWatcher mock_mirroring_watcher
;
542 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
543 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
545 MockRefreshImagesRequest mock_refresh_images_request
;
546 expect_refresh_images(mock_refresh_images_request
, {}, -EBLACKLISTED
);
548 MockListener
mock_listener(this);
549 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
552 mock_pool_watcher
.init(&ctx
);
553 ASSERT_EQ(-EBLACKLISTED
, ctx
.wait());
554 ASSERT_TRUE(mock_pool_watcher
.is_blacklisted());
556 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
557 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
560 TEST_F(TestMockPoolWatcher
, RefreshMissing
) {
561 MockThreads
mock_threads(m_threads
);
562 expect_work_queue(mock_threads
);
565 MockMirroringWatcher mock_mirroring_watcher
;
566 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
567 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
569 MockRefreshImagesRequest mock_refresh_images_request
;
570 expect_refresh_images(mock_refresh_images_request
, {}, -ENOENT
);
571 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
573 MockListener
mock_listener(this);
574 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
576 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
579 mock_pool_watcher
.init(&ctx
);
580 ASSERT_EQ(0, ctx
.wait());
582 ASSERT_TRUE(wait_for_update(1));
583 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
584 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
587 TEST_F(TestMockPoolWatcher
, RefreshError
) {
588 MockThreads
mock_threads(m_threads
);
589 expect_work_queue(mock_threads
);
592 MockMirroringWatcher mock_mirroring_watcher
;
593 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
594 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
596 MockRefreshImagesRequest mock_refresh_images_request
;
597 expect_refresh_images(mock_refresh_images_request
, {}, -EINVAL
);
598 expect_timer_add_event(mock_threads
);
600 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, false);
601 expect_refresh_images(mock_refresh_images_request
, {}, 0);
602 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
604 MockListener
mock_listener(this);
605 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
607 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
610 mock_pool_watcher
.init(&ctx
);
611 ASSERT_EQ(0, ctx
.wait());
613 ASSERT_TRUE(wait_for_update(1));
614 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
615 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
618 TEST_F(TestMockPoolWatcher
, GetMirrorUuidBlacklist
) {
619 MockThreads
mock_threads(m_threads
);
620 expect_work_queue(mock_threads
);
623 MockMirroringWatcher mock_mirroring_watcher
;
624 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
625 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
627 MockRefreshImagesRequest mock_refresh_images_request
;
628 expect_refresh_images(mock_refresh_images_request
, {}, 0);
629 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", -EBLACKLISTED
);
631 MockListener
mock_listener(this);
632 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
635 mock_pool_watcher
.init(&ctx
);
636 ASSERT_EQ(-EBLACKLISTED
, ctx
.wait());
637 ASSERT_TRUE(mock_pool_watcher
.is_blacklisted());
639 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
640 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
643 TEST_F(TestMockPoolWatcher
, GetMirrorUuidMissing
) {
644 MockThreads
mock_threads(m_threads
);
645 expect_work_queue(mock_threads
);
648 MockMirroringWatcher mock_mirroring_watcher
;
649 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
650 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
652 MockRefreshImagesRequest mock_refresh_images_request
;
653 expect_refresh_images(mock_refresh_images_request
, {}, 0);
654 expect_mirror_uuid_get(m_remote_io_ctx
, "", -ENOENT
);
655 expect_timer_add_event(mock_threads
);
657 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, false);
658 expect_refresh_images(mock_refresh_images_request
, {}, 0);
659 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
661 MockListener
mock_listener(this);
662 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
664 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
667 mock_pool_watcher
.init(&ctx
);
668 ASSERT_EQ(-ENOENT
, ctx
.wait());
670 ASSERT_TRUE(wait_for_update(1));
671 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
672 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
675 TEST_F(TestMockPoolWatcher
, GetMirrorUuidError
) {
676 MockThreads
mock_threads(m_threads
);
677 expect_work_queue(mock_threads
);
680 MockMirroringWatcher mock_mirroring_watcher
;
681 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
682 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
684 MockRefreshImagesRequest mock_refresh_images_request
;
685 expect_refresh_images(mock_refresh_images_request
, {}, 0);
686 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", -EINVAL
);
687 expect_timer_add_event(mock_threads
);
689 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, false);
690 expect_refresh_images(mock_refresh_images_request
, {}, 0);
691 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
693 MockListener
mock_listener(this);
694 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
696 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
699 mock_pool_watcher
.init(&ctx
);
700 ASSERT_EQ(0, ctx
.wait());
702 ASSERT_TRUE(wait_for_update(1));
703 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
704 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
707 TEST_F(TestMockPoolWatcher
, Rewatch
) {
708 MockThreads
mock_threads(m_threads
);
709 expect_work_queue(mock_threads
);
712 MockMirroringWatcher mock_mirroring_watcher
;
713 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
714 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
716 MockRefreshImagesRequest mock_refresh_images_request
;
717 expect_refresh_images(mock_refresh_images_request
, {}, 0);
718 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
720 MockListener
mock_listener(this);
721 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
723 expect_timer_add_event(mock_threads
);
724 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, false);
725 expect_refresh_images(mock_refresh_images_request
, {{"global id", "image id"}}, 0);
726 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
727 expect_listener_handle_update(mock_listener
, "remote uuid",
728 {{"global id", "image id"}}, {});
730 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
733 mock_pool_watcher
.init(&ctx
);
734 ASSERT_EQ(0, ctx
.wait());
735 ASSERT_TRUE(wait_for_update(1));
737 MirroringWatcher::get_instance().handle_rewatch_complete(0);
738 ASSERT_TRUE(wait_for_update(1));
740 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
741 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
744 TEST_F(TestMockPoolWatcher
, RewatchBlacklist
) {
745 MockThreads
mock_threads(m_threads
);
746 expect_work_queue(mock_threads
);
749 MockMirroringWatcher mock_mirroring_watcher
;
750 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
751 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
753 MockRefreshImagesRequest mock_refresh_images_request
;
754 expect_refresh_images(mock_refresh_images_request
, {}, 0);
755 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
757 MockListener
mock_listener(this);
758 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
760 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
763 mock_pool_watcher
.init(&ctx
);
764 ASSERT_EQ(0, ctx
.wait());
765 ASSERT_TRUE(wait_for_update(1));
767 MirroringWatcher::get_instance().handle_rewatch_complete(-EBLACKLISTED
);
768 ASSERT_TRUE(mock_pool_watcher
.is_blacklisted());
770 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
771 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
774 TEST_F(TestMockPoolWatcher
, RewatchError
) {
775 MockThreads
mock_threads(m_threads
);
776 expect_work_queue(mock_threads
);
779 MockMirroringWatcher mock_mirroring_watcher
;
780 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
781 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
783 MockRefreshImagesRequest mock_refresh_images_request
;
784 expect_refresh_images(mock_refresh_images_request
, {}, 0);
785 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
787 MockListener
mock_listener(this);
788 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
790 expect_timer_add_event(mock_threads
);
791 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, false);
792 expect_refresh_images(mock_refresh_images_request
, {{"global id", "image id"}}, 0);
793 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
794 expect_listener_handle_update(mock_listener
, "remote uuid",
795 {{"global id", "image id"}}, {});
797 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
800 mock_pool_watcher
.init(&ctx
);
801 ASSERT_EQ(0, ctx
.wait());
802 ASSERT_TRUE(wait_for_update(1));
804 MirroringWatcher::get_instance().handle_rewatch_complete(-EINVAL
);
805 ASSERT_TRUE(wait_for_update(1));
807 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
808 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
811 TEST_F(TestMockPoolWatcher
, DeferredRefresh
) {
812 MockThreads
mock_threads(m_threads
);
813 expect_work_queue(mock_threads
);
816 MockMirroringWatcher mock_mirroring_watcher
;
817 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
818 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
820 MockRefreshImagesRequest mock_refresh_images_request
;
822 EXPECT_CALL(mock_refresh_images_request
, send())
823 .WillOnce(Invoke([&mock_refresh_images_request
]() {
824 *mock_refresh_images_request
.image_ids
= {};
825 MirroringWatcher::get_instance().handle_rewatch_complete(0);
826 mock_refresh_images_request
.on_finish
->complete(0);
828 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
829 expect_timer_add_event(mock_threads
);
831 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, false);
832 expect_refresh_images(mock_refresh_images_request
, {}, 0);
833 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
835 MockListener
mock_listener(this);
836 expect_listener_handle_update(mock_listener
, "remote uuid", {}, {});
838 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
841 mock_pool_watcher
.init(&ctx
);
842 ASSERT_EQ(0, ctx
.wait());
843 ASSERT_TRUE(wait_for_update(1));
845 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
846 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
849 TEST_F(TestMockPoolWatcher
, MirrorUuidUpdated
) {
850 MockThreads
mock_threads(m_threads
);
851 expect_work_queue(mock_threads
);
854 MockMirroringWatcher mock_mirroring_watcher
;
855 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, true);
856 expect_mirroring_watcher_register(mock_mirroring_watcher
, 0);
859 {"global id 1", "remote id 1"},
860 {"global id 2", "remote id 2"}};
861 MockRefreshImagesRequest mock_refresh_images_request
;
862 expect_refresh_images(mock_refresh_images_request
, image_ids
, 0);
863 expect_mirror_uuid_get(m_remote_io_ctx
, "remote uuid", 0);
865 MockListener
mock_listener(this);
866 expect_listener_handle_update(mock_listener
, "remote uuid", image_ids
, {});
868 MockPoolWatcher
mock_pool_watcher(&mock_threads
, m_remote_io_ctx
,
871 mock_pool_watcher
.init(&ctx
);
872 ASSERT_EQ(0, ctx
.wait());
874 ASSERT_TRUE(wait_for_update(1));
876 expect_timer_add_event(mock_threads
);
877 ImageIds new_image_ids
{
878 {"global id 1", "remote id 1"}};
879 expect_mirroring_watcher_is_unregistered(mock_mirroring_watcher
, false);
880 expect_refresh_images(mock_refresh_images_request
, new_image_ids
, 0);
881 expect_mirror_uuid_get(m_remote_io_ctx
, "updated uuid", 0);
882 expect_listener_handle_update(mock_listener
, "remote uuid", {}, image_ids
);
883 expect_listener_handle_update(mock_listener
, "updated uuid", new_image_ids
,
886 MirroringWatcher::get_instance().handle_rewatch_complete(0);
887 ASSERT_TRUE(wait_for_update(2));
889 expect_mirroring_watcher_unregister(mock_mirroring_watcher
, 0);
890 ASSERT_EQ(0, when_shut_down(mock_pool_watcher
));
893 } // namespace mirror