1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "test/librbd/test_mock_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "test/librbd/mock/MockImageCtx.h"
7 #include "librbd/ExclusiveLock.h"
8 #include "librbd/ManagedLock.h"
9 #include "librbd/exclusive_lock/PreAcquireRequest.h"
10 #include "librbd/exclusive_lock/PostAcquireRequest.h"
11 #include "librbd/exclusive_lock/PreReleaseRequest.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
20 struct MockExclusiveLockImageCtx : public MockImageCtx {
21 ContextWQ *op_work_queue;
23 MockExclusiveLockImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
24 op_work_queue = image_ctx.op_work_queue;
28 } // anonymous namespace
32 struct Traits<MockExclusiveLockImageCtx> {
33 typedef librbd::MockImageWatcher Watcher;
38 struct ManagedLock<MockExclusiveLockImageCtx> {
39 ManagedLock(librados::IoCtx& ioctx, ContextWQ *work_queue,
40 const std::string& oid, librbd::MockImageWatcher *watcher,
41 managed_lock::Mode mode, bool blacklist_on_break_lock,
42 uint32_t blacklist_expire_seconds)
43 : m_lock("ManagedLock::m_lock") {
46 virtual ~ManagedLock() = default;
50 virtual void shutdown_handler(int r, Context *) = 0;
51 virtual void pre_acquire_lock_handler(Context *) = 0;
52 virtual void post_acquire_lock_handler(int, Context *) = 0;
53 virtual void pre_release_lock_handler(bool, Context *) = 0;
54 virtual void post_release_lock_handler(bool, int, Context *) = 0;
55 virtual void post_reacquire_lock_handler(int, Context *) = 0;
57 MOCK_CONST_METHOD0(is_lock_owner, bool());
59 MOCK_METHOD1(shut_down, void(Context*));
60 MOCK_METHOD1(acquire_lock, void(Context*));
62 void set_state_uninitialized() {
65 MOCK_METHOD0(set_state_initializing, void());
66 MOCK_METHOD0(set_state_unlocked, void());
67 MOCK_METHOD0(set_state_waiting_for_lock, void());
68 MOCK_METHOD0(set_state_post_acquiring, void());
70 MOCK_CONST_METHOD0(is_state_shutdown, bool());
71 MOCK_CONST_METHOD0(is_state_acquiring, bool());
72 MOCK_CONST_METHOD0(is_state_post_acquiring, bool());
73 MOCK_CONST_METHOD0(is_state_releasing, bool());
74 MOCK_CONST_METHOD0(is_state_pre_releasing, bool());
75 MOCK_CONST_METHOD0(is_state_locked, bool());
76 MOCK_CONST_METHOD0(is_state_waiting_for_lock, bool());
78 MOCK_CONST_METHOD0(is_action_acquire_lock, bool());
79 MOCK_METHOD0(execute_next_action, void());
83 namespace exclusive_lock {
85 using librbd::ImageWatcher;
89 static std::list<T *> s_requests;
90 Context *on_lock_unlock = nullptr;
91 Context *on_finish = nullptr;
93 static T* create(MockExclusiveLockImageCtx &image_ctx,
94 Context *on_lock_unlock, Context *on_finish) {
95 assert(!s_requests.empty());
96 T* req = s_requests.front();
97 req->on_lock_unlock = on_lock_unlock;
98 req->on_finish = on_finish;
99 s_requests.pop_front();
104 s_requests.push_back(reinterpret_cast<T*>(this));
109 std::list<T *> BaseRequest<T>::s_requests;
112 struct PreAcquireRequest<MockExclusiveLockImageCtx> : public BaseRequest<PreAcquireRequest<MockExclusiveLockImageCtx> > {
113 static PreAcquireRequest<MockExclusiveLockImageCtx> *create(
114 MockExclusiveLockImageCtx &image_ctx, Context *on_finish) {
115 return BaseRequest::create(image_ctx, nullptr, on_finish);
117 MOCK_METHOD0(send, void());
121 struct PostAcquireRequest<MockExclusiveLockImageCtx> : public BaseRequest<PostAcquireRequest<MockExclusiveLockImageCtx> > {
122 MOCK_METHOD0(send, void());
126 struct PreReleaseRequest<MockExclusiveLockImageCtx> : public BaseRequest<PreReleaseRequest<MockExclusiveLockImageCtx> > {
127 static PreReleaseRequest<MockExclusiveLockImageCtx> *create(
128 MockExclusiveLockImageCtx &image_ctx, bool shutting_down,
129 AsyncOpTracker &async_op_tracker, Context *on_finish) {
130 return BaseRequest::create(image_ctx, nullptr, on_finish);
132 MOCK_METHOD0(send, void());
135 } // namespace exclusive_lock
136 } // namespace librbd
138 // template definitions
139 #include "librbd/ExclusiveLock.cc"
141 ACTION_P(FinishLockUnlock, request) {
142 if (request->on_lock_unlock != nullptr) {
143 request->on_lock_unlock->complete(0);
147 ACTION_P2(CompleteRequest, request, ret) {
148 request->on_finish->complete(ret);
154 using ::testing::DoAll;
155 using ::testing::Invoke;
156 using ::testing::InSequence;
157 using ::testing::Return;
159 class TestMockExclusiveLock : public TestMockFixture {
161 typedef ManagedLock<MockExclusiveLockImageCtx> MockManagedLock;
162 typedef ExclusiveLock<MockExclusiveLockImageCtx> MockExclusiveLock;
163 typedef exclusive_lock::PreAcquireRequest<MockExclusiveLockImageCtx> MockPreAcquireRequest;
164 typedef exclusive_lock::PostAcquireRequest<MockExclusiveLockImageCtx> MockPostAcquireRequest;
165 typedef exclusive_lock::PreReleaseRequest<MockExclusiveLockImageCtx> MockPreReleaseRequest;
167 void expect_set_state_initializing(MockManagedLock &managed_lock) {
168 EXPECT_CALL(managed_lock, set_state_initializing());
171 void expect_set_state_unlocked(MockManagedLock &managed_lock) {
172 EXPECT_CALL(managed_lock, set_state_unlocked());
175 void expect_set_state_waiting_for_lock(MockManagedLock &managed_lock) {
176 EXPECT_CALL(managed_lock, set_state_waiting_for_lock());
179 void expect_is_state_acquiring(MockManagedLock &managed_lock, bool ret_val) {
180 EXPECT_CALL(managed_lock, is_state_acquiring())
181 .WillOnce(Return(ret_val));
184 void expect_is_state_waiting_for_lock(MockManagedLock &managed_lock,
186 EXPECT_CALL(managed_lock, is_state_waiting_for_lock())
187 .WillOnce(Return(ret_val));
190 void expect_is_state_pre_releasing(MockManagedLock &managed_lock,
192 EXPECT_CALL(managed_lock, is_state_pre_releasing())
193 .WillOnce(Return(ret_val));
196 void expect_is_state_releasing(MockManagedLock &managed_lock, bool ret_val) {
197 EXPECT_CALL(managed_lock, is_state_releasing())
198 .WillOnce(Return(ret_val));
201 void expect_is_state_locked(MockManagedLock &managed_lock, bool ret_val) {
202 EXPECT_CALL(managed_lock, is_state_locked())
203 .WillOnce(Return(ret_val));
206 void expect_is_state_shutdown(MockManagedLock &managed_lock, bool ret_val) {
207 EXPECT_CALL(managed_lock, is_state_shutdown())
208 .WillOnce(Return(ret_val));
211 void expect_is_action_acquire_lock(MockManagedLock &managed_lock,
213 EXPECT_CALL(managed_lock, is_action_acquire_lock())
214 .WillOnce(Return(ret_val));
217 void expect_set_require_lock(MockExclusiveLockImageCtx &mock_image_ctx,
218 io::Direction direction, bool enabled) {
219 EXPECT_CALL(*mock_image_ctx.io_work_queue, set_require_lock(direction,
223 void expect_block_writes(MockExclusiveLockImageCtx &mock_image_ctx) {
224 EXPECT_CALL(*mock_image_ctx.io_work_queue, block_writes(_))
225 .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
226 if (mock_image_ctx.clone_copy_on_read ||
227 (mock_image_ctx.features & RBD_FEATURE_JOURNALING) != 0) {
228 expect_set_require_lock(mock_image_ctx, io::DIRECTION_BOTH, true);
230 expect_set_require_lock(mock_image_ctx, io::DIRECTION_WRITE, true);
234 void expect_unblock_writes(MockExclusiveLockImageCtx &mock_image_ctx) {
235 expect_set_require_lock(mock_image_ctx, io::DIRECTION_BOTH, false);
236 EXPECT_CALL(*mock_image_ctx.io_work_queue, unblock_writes());
239 void expect_prepare_lock_complete(MockExclusiveLockImageCtx &mock_image_ctx) {
240 EXPECT_CALL(*mock_image_ctx.state, handle_prepare_lock_complete());
243 void expect_pre_acquire_request(MockPreAcquireRequest &pre_acquire_request,
245 EXPECT_CALL(pre_acquire_request, send())
246 .WillOnce(CompleteRequest(&pre_acquire_request, r));
249 void expect_post_acquire_request(MockPostAcquireRequest &post_acquire_request,
251 EXPECT_CALL(post_acquire_request, send())
252 .WillOnce(CompleteRequest(&post_acquire_request, r));
255 void expect_pre_release_request(MockPreReleaseRequest &pre_release_request,
257 EXPECT_CALL(pre_release_request, send())
258 .WillOnce(CompleteRequest(&pre_release_request, r));
261 void expect_notify_request_lock(MockExclusiveLockImageCtx &mock_image_ctx,
262 MockExclusiveLock &mock_exclusive_lock) {
263 EXPECT_CALL(*mock_image_ctx.image_watcher, notify_request_lock());
266 void expect_notify_acquired_lock(MockExclusiveLockImageCtx &mock_image_ctx) {
267 EXPECT_CALL(*mock_image_ctx.image_watcher, notify_acquired_lock())
271 void expect_notify_released_lock(MockExclusiveLockImageCtx &mock_image_ctx) {
272 EXPECT_CALL(*mock_image_ctx.image_watcher, notify_released_lock())
276 void expect_flush_notifies(MockExclusiveLockImageCtx &mock_image_ctx) {
277 EXPECT_CALL(*mock_image_ctx.image_watcher, flush(_))
278 .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
281 void expect_shut_down(MockManagedLock &managed_lock) {
282 EXPECT_CALL(managed_lock, shut_down(_))
283 .WillOnce(CompleteContext(0, static_cast<ContextWQ*>(nullptr)));
286 int when_init(MockExclusiveLockImageCtx &mock_image_ctx,
287 MockExclusiveLock &exclusive_lock) {
290 RWLock::WLocker owner_locker(mock_image_ctx.owner_lock);
291 exclusive_lock.init(mock_image_ctx.features, &ctx);
296 int when_pre_acquire_lock_handler(MockManagedLock &managed_lock) {
298 managed_lock.pre_acquire_lock_handler(&ctx);
302 int when_post_acquire_lock_handler(MockManagedLock &managed_lock, int r) {
304 managed_lock.post_acquire_lock_handler(r, &ctx);
308 int when_pre_release_lock_handler(MockManagedLock &managed_lock,
309 bool shutting_down) {
311 managed_lock.pre_release_lock_handler(shutting_down, &ctx);
315 int when_post_release_lock_handler(MockManagedLock &managed_lock,
316 bool shutting_down, int r) {
318 managed_lock.post_release_lock_handler(shutting_down, r, &ctx);
322 int when_post_reacquire_lock_handler(MockManagedLock &managed_lock, int r) {
324 managed_lock.post_reacquire_lock_handler(r, &ctx);
328 int when_shut_down(MockExclusiveLockImageCtx &mock_image_ctx,
329 MockExclusiveLock &exclusive_lock) {
332 RWLock::WLocker owner_locker(mock_image_ctx.owner_lock);
333 exclusive_lock.shut_down(&ctx);
338 bool is_lock_owner(MockExclusiveLockImageCtx &mock_image_ctx,
339 MockExclusiveLock &exclusive_lock) {
340 RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
341 return exclusive_lock.is_lock_owner();
345 TEST_F(TestMockExclusiveLock, StateTransitions) {
346 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
348 librbd::ImageCtx *ictx;
349 ASSERT_EQ(0, open_image(m_image_name, &ictx));
351 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
352 MockExclusiveLock exclusive_lock(mock_image_ctx);
353 expect_op_work_queue(mock_image_ctx);
356 expect_set_state_initializing(exclusive_lock);
357 expect_block_writes(mock_image_ctx);
358 expect_set_state_unlocked(exclusive_lock);
359 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
361 // (try) acquire lock
362 MockPreAcquireRequest try_lock_pre_acquire;
363 expect_pre_acquire_request(try_lock_pre_acquire, 0);
364 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
366 MockPostAcquireRequest try_lock_post_acquire;
367 expect_post_acquire_request(try_lock_post_acquire, 0);
368 expect_is_state_acquiring(exclusive_lock, true);
369 expect_notify_acquired_lock(mock_image_ctx);
370 expect_unblock_writes(mock_image_ctx);
371 ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock, 0));
374 MockPreReleaseRequest pre_request_release;
375 expect_pre_release_request(pre_request_release, 0);
376 ASSERT_EQ(0, when_pre_release_lock_handler(exclusive_lock, false));
378 expect_is_state_pre_releasing(exclusive_lock, false);
379 expect_is_state_releasing(exclusive_lock, true);
380 expect_notify_released_lock(mock_image_ctx);
381 ASSERT_EQ(0, when_post_release_lock_handler(exclusive_lock, false, 0));
383 // (try) acquire lock
384 MockPreAcquireRequest request_lock_pre_acquire;
385 expect_pre_acquire_request(request_lock_pre_acquire, 0);
386 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
388 MockPostAcquireRequest request_lock_post_acquire;
389 expect_post_acquire_request(request_lock_post_acquire, 0);
390 expect_is_state_acquiring(exclusive_lock, true);
391 expect_notify_acquired_lock(mock_image_ctx);
392 expect_unblock_writes(mock_image_ctx);
393 ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock, 0));
395 // shut down (and release)
396 expect_shut_down(exclusive_lock);
397 expect_is_state_waiting_for_lock(exclusive_lock, false);
398 ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
400 MockPreReleaseRequest shutdown_pre_release;
401 expect_pre_release_request(shutdown_pre_release, 0);
402 ASSERT_EQ(0, when_pre_release_lock_handler(exclusive_lock, true));
404 expect_unblock_writes(mock_image_ctx);
405 expect_notify_released_lock(mock_image_ctx);
406 ASSERT_EQ(0, when_post_release_lock_handler(exclusive_lock, true, 0));
409 TEST_F(TestMockExclusiveLock, TryLockAlreadyLocked) {
410 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
412 librbd::ImageCtx *ictx;
413 ASSERT_EQ(0, open_image(m_image_name, &ictx));
415 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
416 MockExclusiveLock exclusive_lock(mock_image_ctx);
417 expect_op_work_queue(mock_image_ctx);
420 expect_set_state_initializing(exclusive_lock);
421 expect_block_writes(mock_image_ctx);
422 expect_set_state_unlocked(exclusive_lock);
423 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
426 MockPreAcquireRequest try_lock_pre_acquire;
427 expect_pre_acquire_request(try_lock_pre_acquire, 0);
428 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
430 expect_is_state_acquiring(exclusive_lock, true);
431 expect_prepare_lock_complete(mock_image_ctx);
432 expect_is_action_acquire_lock(exclusive_lock, false);
433 ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock, -EAGAIN));
436 TEST_F(TestMockExclusiveLock, TryLockError) {
437 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
439 librbd::ImageCtx *ictx;
440 ASSERT_EQ(0, open_image(m_image_name, &ictx));
442 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
443 MockExclusiveLock exclusive_lock(mock_image_ctx);
444 expect_op_work_queue(mock_image_ctx);
447 expect_set_state_initializing(exclusive_lock);
448 expect_block_writes(mock_image_ctx);
449 expect_set_state_unlocked(exclusive_lock);
450 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
453 MockPreAcquireRequest try_lock_pre_acquire;
454 expect_pre_acquire_request(try_lock_pre_acquire, 0);
455 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
457 expect_is_state_acquiring(exclusive_lock, true);
458 expect_prepare_lock_complete(mock_image_ctx);
459 expect_is_action_acquire_lock(exclusive_lock, false);
460 ASSERT_EQ(-EBUSY, when_post_acquire_lock_handler(exclusive_lock, -EBUSY));
463 TEST_F(TestMockExclusiveLock, AcquireLockAlreadyLocked) {
464 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
466 librbd::ImageCtx *ictx;
467 ASSERT_EQ(0, open_image(m_image_name, &ictx));
469 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
470 MockExclusiveLock exclusive_lock(mock_image_ctx);
471 expect_op_work_queue(mock_image_ctx);
474 expect_set_state_initializing(exclusive_lock);
475 expect_block_writes(mock_image_ctx);
476 expect_set_state_unlocked(exclusive_lock);
477 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
480 MockPreAcquireRequest try_lock_pre_acquire;
481 expect_pre_acquire_request(try_lock_pre_acquire, 0);
482 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
484 expect_is_state_acquiring(exclusive_lock, true);
485 expect_prepare_lock_complete(mock_image_ctx);
486 expect_is_action_acquire_lock(exclusive_lock, true);
487 expect_set_state_waiting_for_lock(exclusive_lock);
488 expect_notify_request_lock(mock_image_ctx, exclusive_lock);
489 ASSERT_EQ(-ECANCELED, when_post_acquire_lock_handler(exclusive_lock,
493 TEST_F(TestMockExclusiveLock, AcquireLockBusy) {
494 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
496 librbd::ImageCtx *ictx;
497 ASSERT_EQ(0, open_image(m_image_name, &ictx));
499 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
500 MockExclusiveLock exclusive_lock(mock_image_ctx);
501 expect_op_work_queue(mock_image_ctx);
504 expect_set_state_initializing(exclusive_lock);
505 expect_block_writes(mock_image_ctx);
506 expect_set_state_unlocked(exclusive_lock);
507 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
510 MockPreAcquireRequest try_lock_pre_acquire;
511 expect_pre_acquire_request(try_lock_pre_acquire, 0);
512 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
514 expect_is_state_acquiring(exclusive_lock, true);
515 expect_prepare_lock_complete(mock_image_ctx);
516 expect_is_action_acquire_lock(exclusive_lock, true);
517 expect_set_state_waiting_for_lock(exclusive_lock);
518 expect_notify_request_lock(mock_image_ctx, exclusive_lock);
519 ASSERT_EQ(-ECANCELED, when_post_acquire_lock_handler(exclusive_lock,
523 TEST_F(TestMockExclusiveLock, AcquireLockError) {
524 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
526 librbd::ImageCtx *ictx;
527 ASSERT_EQ(0, open_image(m_image_name, &ictx));
529 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
530 MockExclusiveLock exclusive_lock(mock_image_ctx);
531 expect_op_work_queue(mock_image_ctx);
534 expect_set_state_initializing(exclusive_lock);
535 expect_block_writes(mock_image_ctx);
536 expect_set_state_unlocked(exclusive_lock);
537 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
540 MockPreAcquireRequest try_lock_pre_acquire;
541 expect_pre_acquire_request(try_lock_pre_acquire, 0);
542 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
544 expect_is_state_acquiring(exclusive_lock, true);
545 expect_prepare_lock_complete(mock_image_ctx);
546 expect_is_action_acquire_lock(exclusive_lock, true);
547 ASSERT_EQ(-EBLACKLISTED, when_post_acquire_lock_handler(exclusive_lock,
551 TEST_F(TestMockExclusiveLock, PostAcquireLockError) {
552 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
554 librbd::ImageCtx *ictx;
555 ASSERT_EQ(0, open_image(m_image_name, &ictx));
557 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
558 MockExclusiveLock exclusive_lock(mock_image_ctx);
559 expect_op_work_queue(mock_image_ctx);
562 expect_set_state_initializing(exclusive_lock);
563 expect_block_writes(mock_image_ctx);
564 expect_set_state_unlocked(exclusive_lock);
565 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
567 // (try) acquire lock
568 MockPreAcquireRequest request_lock_pre_acquire;
569 expect_pre_acquire_request(request_lock_pre_acquire, 0);
570 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
572 MockPostAcquireRequest request_lock_post_acquire;
573 expect_post_acquire_request(request_lock_post_acquire, -EPERM);
574 expect_is_state_acquiring(exclusive_lock, true);
575 ASSERT_EQ(-EPERM, when_post_acquire_lock_handler(exclusive_lock, 0));
578 TEST_F(TestMockExclusiveLock, PreReleaseLockError) {
579 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
581 librbd::ImageCtx *ictx;
582 ASSERT_EQ(0, open_image(m_image_name, &ictx));
584 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
585 MockExclusiveLock exclusive_lock(mock_image_ctx);
586 expect_op_work_queue(mock_image_ctx);
589 expect_set_state_initializing(exclusive_lock);
590 expect_block_writes(mock_image_ctx);
591 expect_set_state_unlocked(exclusive_lock);
592 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
595 MockPreReleaseRequest pre_request_release;
596 expect_pre_release_request(pre_request_release, -EINVAL);
597 ASSERT_EQ(-EINVAL, when_pre_release_lock_handler(exclusive_lock, false));
599 expect_is_state_pre_releasing(exclusive_lock, true);
600 ASSERT_EQ(-EINVAL, when_post_release_lock_handler(exclusive_lock, false,
604 TEST_F(TestMockExclusiveLock, ReacquireLock) {
605 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
607 librbd::ImageCtx *ictx;
608 ASSERT_EQ(0, open_image(m_image_name, &ictx));
610 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
611 MockExclusiveLock exclusive_lock(mock_image_ctx);
612 expect_op_work_queue(mock_image_ctx);
615 expect_set_state_initializing(exclusive_lock);
616 expect_block_writes(mock_image_ctx);
617 expect_set_state_unlocked(exclusive_lock);
618 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
620 // (try) acquire lock
621 MockPreAcquireRequest try_lock_pre_acquire;
622 expect_pre_acquire_request(try_lock_pre_acquire, 0);
623 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
625 MockPostAcquireRequest try_lock_post_acquire;
626 expect_post_acquire_request(try_lock_post_acquire, 0);
627 expect_is_state_acquiring(exclusive_lock, true);
628 expect_notify_acquired_lock(mock_image_ctx);
629 expect_unblock_writes(mock_image_ctx);
630 ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock, 0));
633 expect_notify_acquired_lock(mock_image_ctx);
634 ASSERT_EQ(0, when_post_reacquire_lock_handler(exclusive_lock, 0));
636 // shut down (and release)
637 expect_shut_down(exclusive_lock);
638 expect_is_state_waiting_for_lock(exclusive_lock, false);
639 ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
641 MockPreReleaseRequest shutdown_pre_release;
642 expect_pre_release_request(shutdown_pre_release, 0);
643 ASSERT_EQ(0, when_pre_release_lock_handler(exclusive_lock, true));
645 expect_unblock_writes(mock_image_ctx);
646 expect_notify_released_lock(mock_image_ctx);
647 ASSERT_EQ(0, when_post_release_lock_handler(exclusive_lock, true, 0));
650 TEST_F(TestMockExclusiveLock, BlockRequests) {
651 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
653 librbd::ImageCtx *ictx;
654 ASSERT_EQ(0, open_image(m_image_name, &ictx));
656 MockExclusiveLockImageCtx mock_image_ctx(*ictx);
657 MockExclusiveLock exclusive_lock(mock_image_ctx);
659 expect_op_work_queue(mock_image_ctx);
662 expect_set_state_initializing(exclusive_lock);
663 expect_block_writes(mock_image_ctx);
664 expect_set_state_unlocked(exclusive_lock);
665 ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
668 expect_is_state_shutdown(exclusive_lock, false);
669 expect_is_state_locked(exclusive_lock, true);
670 ASSERT_TRUE(exclusive_lock.accept_requests(&ret_val));
671 ASSERT_EQ(0, ret_val);
673 exclusive_lock.block_requests(-EROFS);
674 expect_is_state_shutdown(exclusive_lock, false);
675 expect_is_state_locked(exclusive_lock, true);
676 ASSERT_FALSE(exclusive_lock.accept_requests(&ret_val));
677 ASSERT_EQ(-EROFS, ret_val);
679 exclusive_lock.unblock_requests();
680 expect_is_state_shutdown(exclusive_lock, false);
681 expect_is_state_locked(exclusive_lock, true);
682 ASSERT_TRUE(exclusive_lock.accept_requests(&ret_val));
683 ASSERT_EQ(0, ret_val);
686 } // namespace librbd