Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / rbd_mirror / test_mock_LeaderWatcher.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "librbd/Utils.h"
5 #include "test/librbd/mock/MockImageCtx.h"
6 #include "test/rbd_mirror/test_mock_fixture.h"
7 #include "tools/rbd_mirror/LeaderWatcher.h"
8 #include "tools/rbd_mirror/Threads.h"
9
10 using librbd::util::create_async_context_callback;
11
12 namespace librbd {
13
14 namespace {
15
16 struct MockTestImageCtx : public MockImageCtx {
17   MockTestImageCtx(librbd::ImageCtx &image_ctx)
18     : librbd::MockImageCtx(image_ctx) {
19   }
20 };
21
22 } // anonymous namespace
23
24 struct MockManagedLock {
25   static MockManagedLock *s_instance;
26   static MockManagedLock &get_instance() {
27     assert(s_instance != nullptr);
28     return *s_instance;
29   }
30
31   MockManagedLock() {
32     s_instance = this;
33   }
34
35   bool m_release_lock_on_shutdown = false;
36
37   MOCK_METHOD0(construct, void());
38   MOCK_METHOD0(destroy, void());
39
40   MOCK_CONST_METHOD0(is_lock_owner, bool());
41
42   MOCK_METHOD1(shut_down, void(Context *));
43   MOCK_METHOD1(try_acquire_lock, void(Context *));
44   MOCK_METHOD1(release_lock, void(Context *));
45   MOCK_METHOD3(break_lock, void(const managed_lock::Locker &, bool, Context *));
46   MOCK_METHOD2(get_locker, void(managed_lock::Locker *, Context *));
47
48   MOCK_METHOD0(set_state_post_acquiring, void());
49
50   MOCK_CONST_METHOD0(is_shutdown, bool());
51
52   MOCK_CONST_METHOD0(is_state_post_acquiring, bool());
53   MOCK_CONST_METHOD0(is_state_pre_releasing, bool());
54   MOCK_CONST_METHOD0(is_state_locked, bool());
55 };
56
57 MockManagedLock *MockManagedLock::s_instance = nullptr;
58
59 template <>
60 struct ManagedLock<MockTestImageCtx> {
61   ManagedLock(librados::IoCtx& ioctx, ContextWQ *work_queue,
62               const std::string& oid, librbd::Watcher *watcher,
63               managed_lock::Mode  mode, bool blacklist_on_break_lock,
64               uint32_t blacklist_expire_seconds)
65     : m_work_queue(work_queue), m_lock("ManagedLock::m_lock") {
66     MockManagedLock::get_instance().construct();
67   }
68
69   virtual ~ManagedLock() {
70     MockManagedLock::get_instance().destroy();
71   }
72
73   ContextWQ *m_work_queue;
74
75   mutable Mutex m_lock;
76
77   bool is_lock_owner() const {
78     return MockManagedLock::get_instance().is_lock_owner();
79   }
80
81   void shut_down(Context *on_shutdown) {
82     if (MockManagedLock::get_instance().m_release_lock_on_shutdown) {
83       on_shutdown = new FunctionContext(
84         [this, on_shutdown](int r) {
85           MockManagedLock::get_instance().m_release_lock_on_shutdown = false;
86           shut_down(on_shutdown);
87         });
88       release_lock(on_shutdown);
89       return;
90     }
91
92     MockManagedLock::get_instance().shut_down(on_shutdown);
93   }
94
95   void try_acquire_lock(Context *on_acquired) {
96     Context *post_acquire_ctx = create_async_context_callback(
97       m_work_queue, new FunctionContext(
98         [this, on_acquired](int r) {
99           post_acquire_lock_handler(r, on_acquired);
100         }));
101     MockManagedLock::get_instance().try_acquire_lock(post_acquire_ctx);
102   }
103
104   void release_lock(Context *on_released) {
105     Context *post_release_ctx = new FunctionContext(
106       [this, on_released](int r) {
107         post_release_lock_handler(false, r, on_released);
108       });
109
110     Context *release_ctx = new FunctionContext(
111       [this, on_released, post_release_ctx](int r) {
112         if (r < 0) {
113           on_released->complete(r);
114         } else {
115           MockManagedLock::get_instance().release_lock(post_release_ctx);
116         }
117       });
118
119     Context *pre_release_ctx = new FunctionContext(
120       [this, release_ctx](int r) {
121         bool shutting_down =
122           MockManagedLock::get_instance().m_release_lock_on_shutdown;
123         pre_release_lock_handler(shutting_down, release_ctx);
124       });
125
126     m_work_queue->queue(pre_release_ctx, 0);
127   }
128
129   void get_locker(managed_lock::Locker *locker, Context *on_finish) {
130     MockManagedLock::get_instance().get_locker(locker, on_finish);
131   }
132
133   void break_lock(const managed_lock::Locker &locker, bool force_break_lock,
134                   Context *on_finish) {
135     MockManagedLock::get_instance().break_lock(locker, force_break_lock,
136                                                on_finish);
137   }
138
139   void set_state_post_acquiring() {
140     MockManagedLock::get_instance().set_state_post_acquiring();
141   }
142
143   bool is_shutdown() const {
144     return MockManagedLock::get_instance().is_shutdown();
145   }
146
147   bool is_state_post_acquiring() const {
148     return MockManagedLock::get_instance().is_state_post_acquiring();
149   }
150
151   bool is_state_pre_releasing() const {
152     return MockManagedLock::get_instance().is_state_pre_releasing();
153   }
154
155   bool is_state_locked() const {
156     return MockManagedLock::get_instance().is_state_locked();
157   }
158
159   virtual void post_acquire_lock_handler(int r, Context *on_finish) = 0;
160   virtual void pre_release_lock_handler(bool shutting_down,
161                                         Context *on_finish) = 0;
162   virtual void post_release_lock_handler(bool shutting_down, int r,
163                                          Context *on_finish) = 0;
164 };
165
166 } // namespace librbd
167
168 namespace rbd {
169 namespace mirror {
170
171 template <>
172 struct Threads<librbd::MockTestImageCtx> {
173   Mutex &timer_lock;
174   SafeTimer *timer;
175   ContextWQ *work_queue;
176
177   Threads(Threads<librbd::ImageCtx> *threads)
178     : timer_lock(threads->timer_lock), timer(threads->timer),
179       work_queue(threads->work_queue) {
180   }
181 };
182
183 template <>
184 struct MirrorStatusWatcher<librbd::MockTestImageCtx> {
185   static MirrorStatusWatcher* s_instance;
186
187   static MirrorStatusWatcher *create(librados::IoCtx &io_ctx,
188                                      ContextWQ *work_queue) {
189     assert(s_instance != nullptr);
190     return s_instance;
191   }
192
193   MirrorStatusWatcher() {
194     assert(s_instance == nullptr);
195     s_instance = this;
196   }
197
198   ~MirrorStatusWatcher() {
199     assert(s_instance == this);
200     s_instance = nullptr;
201   }
202
203   MOCK_METHOD0(destroy, void());
204   MOCK_METHOD1(init, void(Context *));
205   MOCK_METHOD1(shut_down, void(Context *));
206 };
207
208 MirrorStatusWatcher<librbd::MockTestImageCtx> *MirrorStatusWatcher<librbd::MockTestImageCtx>::s_instance = nullptr;
209
210 template <>
211 struct Instances<librbd::MockTestImageCtx> {
212   static Instances* s_instance;
213
214   static Instances *create(Threads<librbd::MockTestImageCtx> *threads,
215                            librados::IoCtx &ioctx) {
216     assert(s_instance != nullptr);
217     return s_instance;
218   }
219
220   Instances() {
221     assert(s_instance == nullptr);
222     s_instance = this;
223   }
224
225   ~Instances() {
226     assert(s_instance == this);
227     s_instance = nullptr;
228   }
229
230   MOCK_METHOD0(destroy, void());
231   MOCK_METHOD1(init, void(Context *));
232   MOCK_METHOD1(shut_down, void(Context *));
233   MOCK_METHOD1(notify, void(const std::string &));
234 };
235
236 Instances<librbd::MockTestImageCtx> *Instances<librbd::MockTestImageCtx>::s_instance = nullptr;
237
238 } // namespace mirror
239 } // namespace rbd
240
241
242 // template definitions
243 #include "tools/rbd_mirror/LeaderWatcher.cc"
244
245 namespace rbd {
246 namespace mirror {
247
248 using ::testing::_;
249 using ::testing::AtLeast;
250 using ::testing::DoAll;
251 using ::testing::InSequence;
252 using ::testing::Invoke;
253 using ::testing::Return;
254
255 using librbd::MockManagedLock;
256
257 struct MockListener : public LeaderWatcher<librbd::MockTestImageCtx>::Listener {
258   static MockListener* s_instance;
259
260   MockListener() {
261     assert(s_instance == nullptr);
262     s_instance = this;
263   }
264
265   ~MockListener() override {
266     assert(s_instance == this);
267     s_instance = nullptr;
268   }
269
270   MOCK_METHOD1(post_acquire_handler, void(Context *));
271   MOCK_METHOD1(pre_release_handler, void(Context *));
272
273   MOCK_METHOD1(update_leader_handler, void(const std::string &));
274 };
275
276 MockListener *MockListener::s_instance = nullptr;
277
278 class TestMockLeaderWatcher : public TestMockFixture {
279 public:
280   typedef MirrorStatusWatcher<librbd::MockTestImageCtx> MockMirrorStatusWatcher;
281   typedef Instances<librbd::MockTestImageCtx> MockInstances;
282   typedef LeaderWatcher<librbd::MockTestImageCtx> MockLeaderWatcher;
283   typedef Threads<librbd::MockTestImageCtx> MockThreads;
284
285   void SetUp() override {
286     TestMockFixture::SetUp();
287     m_mock_threads = new MockThreads(m_threads);
288   }
289
290   void TearDown() override {
291     delete m_mock_threads;
292     TestMockFixture::TearDown();
293   }
294
295   void expect_construct(MockManagedLock &mock_managed_lock) {
296     EXPECT_CALL(mock_managed_lock, construct());
297   }
298
299   void expect_destroy(MockManagedLock &mock_managed_lock) {
300     EXPECT_CALL(mock_managed_lock, destroy());
301   }
302
303   void expect_is_lock_owner(MockManagedLock &mock_managed_lock, bool owner) {
304     EXPECT_CALL(mock_managed_lock, is_lock_owner())
305       .WillOnce(Return(owner));
306   }
307
308   void expect_shut_down(MockManagedLock &mock_managed_lock,
309                         bool release_lock_on_shutdown, int r) {
310     mock_managed_lock.m_release_lock_on_shutdown = release_lock_on_shutdown;
311     EXPECT_CALL(mock_managed_lock, shut_down(_))
312       .WillOnce(CompleteContext(r));
313   }
314
315   void expect_try_acquire_lock(MockManagedLock &mock_managed_lock, int r) {
316     EXPECT_CALL(mock_managed_lock, try_acquire_lock(_))
317       .WillOnce(CompleteContext(r));
318     if (r == 0) {
319       expect_set_state_post_acquiring(mock_managed_lock);
320     }
321   }
322
323   void expect_release_lock(MockManagedLock &mock_managed_lock, int r,
324                            Context *on_finish = nullptr) {
325     EXPECT_CALL(mock_managed_lock, release_lock(_))
326       .WillOnce(Invoke([on_finish, r](Context *ctx) {
327                          ctx->complete(r);
328                          if (on_finish != nullptr) {
329                            on_finish->complete(0);
330                          }
331                        }));
332   }
333
334   void expect_get_locker(MockManagedLock &mock_managed_lock,
335                          const librbd::managed_lock::Locker &locker, int r) {
336     EXPECT_CALL(mock_managed_lock, get_locker(_, _))
337       .WillOnce(Invoke([r, locker](librbd::managed_lock::Locker *out,
338                                    Context *ctx) {
339                          if (r == 0) {
340                            *out = locker;
341                          }
342                          ctx->complete(r);
343                        }));
344   }
345
346   void expect_break_lock(MockManagedLock &mock_managed_lock,
347                          const librbd::managed_lock::Locker &locker, int r,
348                          Context *on_finish) {
349     EXPECT_CALL(mock_managed_lock, break_lock(locker, true, _))
350       .WillOnce(Invoke([on_finish, r](const librbd::managed_lock::Locker &,
351                                       bool, Context *ctx) {
352                          ctx->complete(r);
353                          on_finish->complete(0);
354                        }));
355   }
356
357   void expect_set_state_post_acquiring(MockManagedLock &mock_managed_lock) {
358     EXPECT_CALL(mock_managed_lock, set_state_post_acquiring());
359   }
360
361   void expect_is_shutdown(MockManagedLock &mock_managed_lock) {
362     EXPECT_CALL(mock_managed_lock, is_shutdown())
363       .Times(AtLeast(0)).WillRepeatedly(Return(false));
364   }
365
366   void expect_is_leader(MockManagedLock &mock_managed_lock, bool post_acquiring,
367                         bool locked) {
368     EXPECT_CALL(mock_managed_lock, is_state_post_acquiring())
369       .WillOnce(Return(post_acquiring));
370     if (!post_acquiring) {
371       EXPECT_CALL(mock_managed_lock, is_state_locked())
372         .WillOnce(Return(locked));
373     }
374   }
375
376   void expect_is_leader(MockManagedLock &mock_managed_lock) {
377     EXPECT_CALL(mock_managed_lock, is_state_post_acquiring())
378       .Times(AtLeast(0)).WillRepeatedly(Return(false));
379     EXPECT_CALL(mock_managed_lock, is_state_locked())
380       .Times(AtLeast(0)).WillRepeatedly(Return(false));
381     EXPECT_CALL(mock_managed_lock, is_state_pre_releasing())
382       .Times(AtLeast(0)).WillRepeatedly(Return(false));
383   }
384
385   void expect_notify_heartbeat(MockManagedLock &mock_managed_lock,
386                                Context *on_finish) {
387     // is_leader in notify_heartbeat
388     EXPECT_CALL(mock_managed_lock, is_state_post_acquiring())
389       .WillOnce(Return(false));
390     EXPECT_CALL(mock_managed_lock, is_state_locked())
391       .WillOnce(Return(true));
392
393     // is_leader in handle_notify_heartbeat
394     EXPECT_CALL(mock_managed_lock, is_state_post_acquiring())
395       .WillOnce(Return(false));
396     EXPECT_CALL(mock_managed_lock, is_state_locked())
397       .WillOnce(DoAll(Invoke([on_finish]() {
398                         on_finish->complete(0);
399                       }),
400                       Return(true)));
401   }
402
403   void expect_destroy(MockMirrorStatusWatcher &mock_mirror_status_watcher) {
404     EXPECT_CALL(mock_mirror_status_watcher, destroy());
405   }
406
407   void expect_init(MockMirrorStatusWatcher &mock_mirror_status_watcher, int r) {
408     EXPECT_CALL(mock_mirror_status_watcher, init(_))
409       .WillOnce(CompleteContext(m_mock_threads->work_queue, r));
410   }
411
412   void expect_shut_down(MockMirrorStatusWatcher &mock_mirror_status_watcher, int r) {
413     EXPECT_CALL(mock_mirror_status_watcher, shut_down(_))
414       .WillOnce(CompleteContext(m_mock_threads->work_queue, r));
415     expect_destroy(mock_mirror_status_watcher);
416   }
417
418   void expect_destroy(MockInstances &mock_instances) {
419     EXPECT_CALL(mock_instances, destroy());
420   }
421
422   void expect_init(MockInstances &mock_instances, int r) {
423     EXPECT_CALL(mock_instances, init(_))
424       .WillOnce(CompleteContext(m_mock_threads->work_queue, r));
425   }
426
427   void expect_shut_down(MockInstances &mock_instances, int r) {
428     EXPECT_CALL(mock_instances, shut_down(_))
429       .WillOnce(CompleteContext(m_mock_threads->work_queue, r));
430     expect_destroy(mock_instances);
431   }
432
433   void expect_acquire_notify(MockManagedLock &mock_managed_lock,
434                              MockListener &mock_listener, int r) {
435     expect_is_leader(mock_managed_lock, true, false);
436     EXPECT_CALL(mock_listener, post_acquire_handler(_))
437       .WillOnce(CompleteContext(r));
438     expect_is_leader(mock_managed_lock, true, false);
439   }
440
441   void expect_release_notify(MockManagedLock &mock_managed_lock,
442                              MockListener &mock_listener, int r) {
443     expect_is_leader(mock_managed_lock, false, false);
444     EXPECT_CALL(mock_listener, pre_release_handler(_))
445       .WillOnce(CompleteContext(r));
446     expect_is_leader(mock_managed_lock, false, false);
447   }
448
449   MockThreads *m_mock_threads;
450 };
451
452 TEST_F(TestMockLeaderWatcher, InitShutdown) {
453   MockManagedLock mock_managed_lock;
454   MockMirrorStatusWatcher mock_mirror_status_watcher;
455   MockInstances mock_instances;
456   MockListener listener;
457
458   expect_is_shutdown(mock_managed_lock);
459   expect_destroy(mock_managed_lock);
460
461   InSequence seq;
462
463   expect_construct(mock_managed_lock);
464   MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
465
466   // Inint
467   C_SaferCond on_heartbeat_finish;
468   expect_is_leader(mock_managed_lock, false, false);
469   expect_try_acquire_lock(mock_managed_lock, 0);
470   expect_init(mock_mirror_status_watcher, 0);
471   expect_init(mock_instances, 0);
472   expect_acquire_notify(mock_managed_lock, listener, 0);
473   expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
474
475   ASSERT_EQ(0, leader_watcher.init());
476   ASSERT_EQ(0, on_heartbeat_finish.wait());
477
478   // Shutdown
479   expect_release_notify(mock_managed_lock, listener, 0);
480   expect_shut_down(mock_instances, 0);
481   expect_shut_down(mock_mirror_status_watcher, 0);
482   expect_is_leader(mock_managed_lock, false, false);
483   expect_release_lock(mock_managed_lock, 0);
484   expect_shut_down(mock_managed_lock, true, 0);
485   expect_is_leader(mock_managed_lock, false, false);
486
487   leader_watcher.shut_down();
488 }
489
490 TEST_F(TestMockLeaderWatcher, InitReleaseShutdown) {
491   MockManagedLock mock_managed_lock;
492   MockMirrorStatusWatcher mock_mirror_status_watcher;
493   MockInstances mock_instances;
494   MockListener listener;
495
496   expect_is_shutdown(mock_managed_lock);
497   expect_destroy(mock_managed_lock);
498
499   InSequence seq;
500
501   expect_construct(mock_managed_lock);
502   MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
503
504   // Inint
505   C_SaferCond on_heartbeat_finish;
506   expect_is_leader(mock_managed_lock, false, false);
507   expect_try_acquire_lock(mock_managed_lock, 0);
508   expect_init(mock_mirror_status_watcher, 0);
509   expect_init(mock_instances, 0);
510   expect_acquire_notify(mock_managed_lock, listener, 0);
511   expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
512
513   ASSERT_EQ(0, leader_watcher.init());
514   ASSERT_EQ(0, on_heartbeat_finish.wait());
515
516   // Release
517   expect_is_leader(mock_managed_lock, false, true);
518   expect_release_notify(mock_managed_lock, listener, 0);
519   expect_shut_down(mock_instances, 0);
520   expect_shut_down(mock_mirror_status_watcher, 0);
521   expect_is_leader(mock_managed_lock, false, false);
522   C_SaferCond on_release;
523   expect_release_lock(mock_managed_lock, 0, &on_release);
524
525   leader_watcher.release_leader();
526   ASSERT_EQ(0, on_release.wait());
527
528   // Shutdown
529   expect_shut_down(mock_managed_lock, false, 0);
530   expect_is_leader(mock_managed_lock, false, false);
531
532   leader_watcher.shut_down();
533 }
534
535 TEST_F(TestMockLeaderWatcher, AcquireError) {
536   MockManagedLock mock_managed_lock;
537   MockMirrorStatusWatcher mock_mirror_status_watcher;
538   MockInstances mock_instances;
539   MockListener listener;
540
541   expect_is_shutdown(mock_managed_lock);
542   expect_is_leader(mock_managed_lock);
543   expect_destroy(mock_managed_lock);
544
545   InSequence seq;
546
547   expect_construct(mock_managed_lock);
548   MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
549
550   // Inint
551   C_SaferCond on_heartbeat_finish;
552   expect_is_leader(mock_managed_lock, false, false);
553   expect_try_acquire_lock(mock_managed_lock, -EAGAIN);
554   expect_get_locker(mock_managed_lock, librbd::managed_lock::Locker(), -ENOENT);
555   expect_try_acquire_lock(mock_managed_lock, 0);
556   expect_init(mock_mirror_status_watcher, 0);
557   expect_init(mock_instances, 0);
558   expect_acquire_notify(mock_managed_lock, listener, 0);
559   expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
560
561   ASSERT_EQ(0, leader_watcher.init());
562   ASSERT_EQ(0, on_heartbeat_finish.wait());
563
564   // Shutdown
565   expect_release_notify(mock_managed_lock, listener, 0);
566   expect_shut_down(mock_instances, 0);
567   expect_shut_down(mock_mirror_status_watcher, 0);
568   expect_is_leader(mock_managed_lock, false, false);
569   expect_release_lock(mock_managed_lock, 0);
570   expect_shut_down(mock_managed_lock, true, 0);
571   expect_is_leader(mock_managed_lock, false, false);
572
573   leader_watcher.shut_down();
574 }
575
576 TEST_F(TestMockLeaderWatcher, ReleaseError) {
577   MockManagedLock mock_managed_lock;
578   MockMirrorStatusWatcher mock_mirror_status_watcher;
579   MockInstances mock_instances;
580   MockListener listener;
581
582   expect_is_shutdown(mock_managed_lock);
583   expect_destroy(mock_managed_lock);
584
585   InSequence seq;
586
587   expect_construct(mock_managed_lock);
588   MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
589
590   // Inint
591   C_SaferCond on_heartbeat_finish;
592   expect_is_leader(mock_managed_lock, false, false);
593   expect_try_acquire_lock(mock_managed_lock, 0);
594   expect_init(mock_mirror_status_watcher, 0);
595   expect_init(mock_instances, 0);
596   expect_acquire_notify(mock_managed_lock, listener, 0);
597   expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
598
599   ASSERT_EQ(0, leader_watcher.init());
600   ASSERT_EQ(0, on_heartbeat_finish.wait());
601
602   // Release
603   expect_is_leader(mock_managed_lock, false, true);
604   expect_release_notify(mock_managed_lock, listener, -EINVAL);
605   expect_shut_down(mock_instances, 0);
606   expect_shut_down(mock_mirror_status_watcher, -EINVAL);
607   expect_is_leader(mock_managed_lock, false, false);
608   C_SaferCond on_release;
609   expect_release_lock(mock_managed_lock, -EINVAL, &on_release);
610
611   leader_watcher.release_leader();
612   ASSERT_EQ(0, on_release.wait());
613
614   // Shutdown
615   expect_shut_down(mock_managed_lock, false, 0);
616   expect_is_leader(mock_managed_lock, false, false);
617
618   leader_watcher.shut_down();
619 }
620
621 TEST_F(TestMockLeaderWatcher, Break) {
622   EXPECT_EQ(0, _rados->conf_set("rbd_mirror_leader_heartbeat_interval", "1"));
623   EXPECT_EQ(0, _rados->conf_set("rbd_mirror_leader_max_missed_heartbeats",
624                                 "1"));
625   CephContext *cct = reinterpret_cast<CephContext *>(m_local_io_ctx.cct());
626   int max_acquire_attempts = cct->_conf->get_val<int64_t>(
627     "rbd_mirror_leader_max_acquire_attempts_before_break");
628
629   MockManagedLock mock_managed_lock;
630   MockMirrorStatusWatcher mock_mirror_status_watcher;
631   MockInstances mock_instances;
632   MockListener listener;
633   librbd::managed_lock::Locker
634     locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123};
635
636   expect_is_shutdown(mock_managed_lock);
637   expect_is_leader(mock_managed_lock);
638   expect_destroy(mock_managed_lock);
639   EXPECT_CALL(listener, update_leader_handler(_));
640
641   InSequence seq;
642
643   expect_construct(mock_managed_lock);
644   MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
645
646   // Init
647   expect_is_leader(mock_managed_lock, false, false);
648   for (int i = 0; i < max_acquire_attempts; i++) {
649     expect_try_acquire_lock(mock_managed_lock, -EAGAIN);
650     expect_get_locker(mock_managed_lock, locker, 0);
651   }
652   C_SaferCond on_break;
653   expect_break_lock(mock_managed_lock, locker, 0, &on_break);
654   C_SaferCond on_heartbeat_finish;
655   expect_try_acquire_lock(mock_managed_lock, 0);
656   expect_init(mock_mirror_status_watcher, 0);
657   expect_init(mock_instances, 0);
658   expect_acquire_notify(mock_managed_lock, listener, 0);
659   expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
660
661   ASSERT_EQ(0, leader_watcher.init());
662   ASSERT_EQ(0, on_heartbeat_finish.wait());
663
664   // Shutdown
665   expect_release_notify(mock_managed_lock, listener, 0);
666   expect_shut_down(mock_instances, 0);
667   expect_shut_down(mock_mirror_status_watcher, 0);
668   expect_is_leader(mock_managed_lock, false, false);
669   expect_release_lock(mock_managed_lock, 0);
670   expect_shut_down(mock_managed_lock, true, 0);
671   expect_is_leader(mock_managed_lock, false, false);
672
673   leader_watcher.shut_down();
674 }
675
676 } // namespace mirror
677 } // namespace rbd