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_on_read(MockExclusiveLockImageCtx
&mock_image_ctx
) {
218 EXPECT_CALL(*mock_image_ctx
.io_work_queue
, set_require_lock_on_read());
221 void expect_clear_require_lock_on_read(MockExclusiveLockImageCtx
&mock_image_ctx
) {
222 EXPECT_CALL(*mock_image_ctx
.io_work_queue
, clear_require_lock_on_read());
225 void expect_block_writes(MockExclusiveLockImageCtx
&mock_image_ctx
) {
226 EXPECT_CALL(*mock_image_ctx
.io_work_queue
, block_writes(_
))
227 .WillOnce(CompleteContext(0, mock_image_ctx
.image_ctx
->op_work_queue
));
228 if ((mock_image_ctx
.features
& RBD_FEATURE_JOURNALING
) != 0) {
229 expect_set_require_lock_on_read(mock_image_ctx
);
233 void expect_unblock_writes(MockExclusiveLockImageCtx
&mock_image_ctx
) {
234 expect_clear_require_lock_on_read(mock_image_ctx
);
235 EXPECT_CALL(*mock_image_ctx
.io_work_queue
, unblock_writes());
238 void expect_prepare_lock_complete(MockExclusiveLockImageCtx
&mock_image_ctx
) {
239 EXPECT_CALL(*mock_image_ctx
.state
, handle_prepare_lock_complete());
242 void expect_pre_acquire_request(MockPreAcquireRequest
&pre_acquire_request
,
244 EXPECT_CALL(pre_acquire_request
, send())
245 .WillOnce(CompleteRequest(&pre_acquire_request
, r
));
248 void expect_post_acquire_request(MockPostAcquireRequest
&post_acquire_request
,
250 EXPECT_CALL(post_acquire_request
, send())
251 .WillOnce(CompleteRequest(&post_acquire_request
, r
));
254 void expect_pre_release_request(MockPreReleaseRequest
&pre_release_request
,
256 EXPECT_CALL(pre_release_request
, send())
257 .WillOnce(CompleteRequest(&pre_release_request
, r
));
260 void expect_notify_request_lock(MockExclusiveLockImageCtx
&mock_image_ctx
,
261 MockExclusiveLock
&mock_exclusive_lock
) {
262 EXPECT_CALL(*mock_image_ctx
.image_watcher
, notify_request_lock());
265 void expect_notify_acquired_lock(MockExclusiveLockImageCtx
&mock_image_ctx
) {
266 EXPECT_CALL(*mock_image_ctx
.image_watcher
, notify_acquired_lock())
270 void expect_notify_released_lock(MockExclusiveLockImageCtx
&mock_image_ctx
) {
271 EXPECT_CALL(*mock_image_ctx
.image_watcher
, notify_released_lock())
275 void expect_is_lock_request_needed(MockExclusiveLockImageCtx
&mock_image_ctx
, bool ret
) {
276 EXPECT_CALL(*mock_image_ctx
.io_work_queue
, is_lock_request_needed())
277 .WillRepeatedly(Return(ret
));
280 void expect_flush_notifies(MockExclusiveLockImageCtx
&mock_image_ctx
) {
281 EXPECT_CALL(*mock_image_ctx
.image_watcher
, flush(_
))
282 .WillOnce(CompleteContext(0, mock_image_ctx
.image_ctx
->op_work_queue
));
285 void expect_shut_down(MockManagedLock
&managed_lock
) {
286 EXPECT_CALL(managed_lock
, shut_down(_
))
287 .WillOnce(CompleteContext(0, static_cast<ContextWQ
*>(nullptr)));
290 int when_init(MockExclusiveLockImageCtx
&mock_image_ctx
,
291 MockExclusiveLock
&exclusive_lock
) {
294 RWLock::WLocker
owner_locker(mock_image_ctx
.owner_lock
);
295 exclusive_lock
.init(mock_image_ctx
.features
, &ctx
);
300 int when_pre_acquire_lock_handler(MockManagedLock
&managed_lock
) {
302 managed_lock
.pre_acquire_lock_handler(&ctx
);
306 int when_post_acquire_lock_handler(MockManagedLock
&managed_lock
, int r
) {
308 managed_lock
.post_acquire_lock_handler(r
, &ctx
);
312 int when_pre_release_lock_handler(MockManagedLock
&managed_lock
,
313 bool shutting_down
) {
315 managed_lock
.pre_release_lock_handler(shutting_down
, &ctx
);
319 int when_post_release_lock_handler(MockManagedLock
&managed_lock
,
320 bool shutting_down
, int r
) {
322 managed_lock
.post_release_lock_handler(shutting_down
, r
, &ctx
);
326 int when_post_reacquire_lock_handler(MockManagedLock
&managed_lock
, int r
) {
328 managed_lock
.post_reacquire_lock_handler(r
, &ctx
);
332 int when_shut_down(MockExclusiveLockImageCtx
&mock_image_ctx
,
333 MockExclusiveLock
&exclusive_lock
) {
336 RWLock::WLocker
owner_locker(mock_image_ctx
.owner_lock
);
337 exclusive_lock
.shut_down(&ctx
);
342 bool is_lock_owner(MockExclusiveLockImageCtx
&mock_image_ctx
,
343 MockExclusiveLock
&exclusive_lock
) {
344 RWLock::RLocker
owner_locker(mock_image_ctx
.owner_lock
);
345 return exclusive_lock
.is_lock_owner();
349 TEST_F(TestMockExclusiveLock
, StateTransitions
) {
350 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
352 librbd::ImageCtx
*ictx
;
353 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
355 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
356 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
357 expect_op_work_queue(mock_image_ctx
);
360 expect_set_state_initializing(exclusive_lock
);
361 expect_block_writes(mock_image_ctx
);
362 expect_set_state_unlocked(exclusive_lock
);
363 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
365 // (try) acquire lock
366 MockPreAcquireRequest try_lock_pre_acquire
;
367 expect_pre_acquire_request(try_lock_pre_acquire
, 0);
368 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock
));
370 MockPostAcquireRequest try_lock_post_acquire
;
371 expect_post_acquire_request(try_lock_post_acquire
, 0);
372 expect_is_state_acquiring(exclusive_lock
, true);
373 expect_notify_acquired_lock(mock_image_ctx
);
374 expect_unblock_writes(mock_image_ctx
);
375 ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock
, 0));
378 MockPreReleaseRequest pre_request_release
;
379 expect_pre_release_request(pre_request_release
, 0);
380 ASSERT_EQ(0, when_pre_release_lock_handler(exclusive_lock
, false));
382 expect_is_state_pre_releasing(exclusive_lock
, false);
383 expect_is_state_releasing(exclusive_lock
, true);
384 expect_notify_released_lock(mock_image_ctx
);
385 expect_is_lock_request_needed(mock_image_ctx
, false);
386 ASSERT_EQ(0, when_post_release_lock_handler(exclusive_lock
, false, 0));
388 // (try) acquire lock
389 MockPreAcquireRequest request_lock_pre_acquire
;
390 expect_pre_acquire_request(request_lock_pre_acquire
, 0);
391 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock
));
393 MockPostAcquireRequest request_lock_post_acquire
;
394 expect_post_acquire_request(request_lock_post_acquire
, 0);
395 expect_is_state_acquiring(exclusive_lock
, true);
396 expect_notify_acquired_lock(mock_image_ctx
);
397 expect_unblock_writes(mock_image_ctx
);
398 ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock
, 0));
400 // shut down (and release)
401 expect_shut_down(exclusive_lock
);
402 expect_is_state_waiting_for_lock(exclusive_lock
, false);
403 ASSERT_EQ(0, when_shut_down(mock_image_ctx
, exclusive_lock
));
405 MockPreReleaseRequest shutdown_pre_release
;
406 expect_pre_release_request(shutdown_pre_release
, 0);
407 ASSERT_EQ(0, when_pre_release_lock_handler(exclusive_lock
, true));
409 expect_unblock_writes(mock_image_ctx
);
410 expect_notify_released_lock(mock_image_ctx
);
411 ASSERT_EQ(0, when_post_release_lock_handler(exclusive_lock
, true, 0));
414 TEST_F(TestMockExclusiveLock
, TryLockAlreadyLocked
) {
415 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
417 librbd::ImageCtx
*ictx
;
418 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
420 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
421 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
422 expect_op_work_queue(mock_image_ctx
);
425 expect_set_state_initializing(exclusive_lock
);
426 expect_block_writes(mock_image_ctx
);
427 expect_set_state_unlocked(exclusive_lock
);
428 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
431 MockPreAcquireRequest try_lock_pre_acquire
;
432 expect_pre_acquire_request(try_lock_pre_acquire
, 0);
433 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock
));
435 expect_is_state_acquiring(exclusive_lock
, true);
436 expect_prepare_lock_complete(mock_image_ctx
);
437 expect_is_action_acquire_lock(exclusive_lock
, false);
438 ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock
, -EAGAIN
));
441 TEST_F(TestMockExclusiveLock
, TryLockError
) {
442 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
444 librbd::ImageCtx
*ictx
;
445 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
447 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
448 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
449 expect_op_work_queue(mock_image_ctx
);
452 expect_set_state_initializing(exclusive_lock
);
453 expect_block_writes(mock_image_ctx
);
454 expect_set_state_unlocked(exclusive_lock
);
455 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
458 MockPreAcquireRequest try_lock_pre_acquire
;
459 expect_pre_acquire_request(try_lock_pre_acquire
, 0);
460 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock
));
462 expect_is_state_acquiring(exclusive_lock
, true);
463 expect_prepare_lock_complete(mock_image_ctx
);
464 expect_is_action_acquire_lock(exclusive_lock
, false);
465 ASSERT_EQ(-EBUSY
, when_post_acquire_lock_handler(exclusive_lock
, -EBUSY
));
468 TEST_F(TestMockExclusiveLock
, AcquireLockAlreadyLocked
) {
469 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
471 librbd::ImageCtx
*ictx
;
472 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
474 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
475 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
476 expect_op_work_queue(mock_image_ctx
);
479 expect_set_state_initializing(exclusive_lock
);
480 expect_block_writes(mock_image_ctx
);
481 expect_set_state_unlocked(exclusive_lock
);
482 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
485 MockPreAcquireRequest try_lock_pre_acquire
;
486 expect_pre_acquire_request(try_lock_pre_acquire
, 0);
487 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock
));
489 expect_is_state_acquiring(exclusive_lock
, true);
490 expect_prepare_lock_complete(mock_image_ctx
);
491 expect_is_action_acquire_lock(exclusive_lock
, true);
492 expect_set_state_waiting_for_lock(exclusive_lock
);
493 expect_notify_request_lock(mock_image_ctx
, exclusive_lock
);
494 ASSERT_EQ(-ECANCELED
, when_post_acquire_lock_handler(exclusive_lock
,
498 TEST_F(TestMockExclusiveLock
, AcquireLockBusy
) {
499 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
501 librbd::ImageCtx
*ictx
;
502 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
504 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
505 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
506 expect_op_work_queue(mock_image_ctx
);
509 expect_set_state_initializing(exclusive_lock
);
510 expect_block_writes(mock_image_ctx
);
511 expect_set_state_unlocked(exclusive_lock
);
512 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
515 MockPreAcquireRequest try_lock_pre_acquire
;
516 expect_pre_acquire_request(try_lock_pre_acquire
, 0);
517 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock
));
519 expect_is_state_acquiring(exclusive_lock
, true);
520 expect_prepare_lock_complete(mock_image_ctx
);
521 expect_is_action_acquire_lock(exclusive_lock
, true);
522 expect_set_state_waiting_for_lock(exclusive_lock
);
523 expect_notify_request_lock(mock_image_ctx
, exclusive_lock
);
524 ASSERT_EQ(-ECANCELED
, when_post_acquire_lock_handler(exclusive_lock
,
528 TEST_F(TestMockExclusiveLock
, AcquireLockError
) {
529 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
531 librbd::ImageCtx
*ictx
;
532 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
534 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
535 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
536 expect_op_work_queue(mock_image_ctx
);
539 expect_set_state_initializing(exclusive_lock
);
540 expect_block_writes(mock_image_ctx
);
541 expect_set_state_unlocked(exclusive_lock
);
542 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
545 MockPreAcquireRequest try_lock_pre_acquire
;
546 expect_pre_acquire_request(try_lock_pre_acquire
, 0);
547 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock
));
549 expect_is_state_acquiring(exclusive_lock
, true);
550 expect_prepare_lock_complete(mock_image_ctx
);
551 expect_is_action_acquire_lock(exclusive_lock
, true);
552 ASSERT_EQ(-EBLACKLISTED
, when_post_acquire_lock_handler(exclusive_lock
,
556 TEST_F(TestMockExclusiveLock
, PostAcquireLockError
) {
557 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
559 librbd::ImageCtx
*ictx
;
560 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
562 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
563 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
564 expect_op_work_queue(mock_image_ctx
);
567 expect_set_state_initializing(exclusive_lock
);
568 expect_block_writes(mock_image_ctx
);
569 expect_set_state_unlocked(exclusive_lock
);
570 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
572 // (try) acquire lock
573 MockPreAcquireRequest request_lock_pre_acquire
;
574 expect_pre_acquire_request(request_lock_pre_acquire
, 0);
575 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock
));
577 MockPostAcquireRequest request_lock_post_acquire
;
578 expect_post_acquire_request(request_lock_post_acquire
, -EPERM
);
579 expect_is_state_acquiring(exclusive_lock
, true);
580 ASSERT_EQ(-EPERM
, when_post_acquire_lock_handler(exclusive_lock
, 0));
583 TEST_F(TestMockExclusiveLock
, PreReleaseLockError
) {
584 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
586 librbd::ImageCtx
*ictx
;
587 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
589 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
590 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
591 expect_op_work_queue(mock_image_ctx
);
594 expect_set_state_initializing(exclusive_lock
);
595 expect_block_writes(mock_image_ctx
);
596 expect_set_state_unlocked(exclusive_lock
);
597 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
600 MockPreReleaseRequest pre_request_release
;
601 expect_pre_release_request(pre_request_release
, -EINVAL
);
602 ASSERT_EQ(-EINVAL
, when_pre_release_lock_handler(exclusive_lock
, false));
604 expect_is_state_pre_releasing(exclusive_lock
, true);
605 ASSERT_EQ(-EINVAL
, when_post_release_lock_handler(exclusive_lock
, false,
609 TEST_F(TestMockExclusiveLock
, ReacquireLock
) {
610 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
612 librbd::ImageCtx
*ictx
;
613 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
615 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
616 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
617 expect_op_work_queue(mock_image_ctx
);
620 expect_set_state_initializing(exclusive_lock
);
621 expect_block_writes(mock_image_ctx
);
622 expect_set_state_unlocked(exclusive_lock
);
623 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
625 // (try) acquire lock
626 MockPreAcquireRequest try_lock_pre_acquire
;
627 expect_pre_acquire_request(try_lock_pre_acquire
, 0);
628 ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock
));
630 MockPostAcquireRequest try_lock_post_acquire
;
631 expect_post_acquire_request(try_lock_post_acquire
, 0);
632 expect_is_state_acquiring(exclusive_lock
, true);
633 expect_notify_acquired_lock(mock_image_ctx
);
634 expect_unblock_writes(mock_image_ctx
);
635 ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock
, 0));
638 expect_notify_acquired_lock(mock_image_ctx
);
639 ASSERT_EQ(0, when_post_reacquire_lock_handler(exclusive_lock
, 0));
641 // shut down (and release)
642 expect_shut_down(exclusive_lock
);
643 expect_is_state_waiting_for_lock(exclusive_lock
, false);
644 ASSERT_EQ(0, when_shut_down(mock_image_ctx
, exclusive_lock
));
646 MockPreReleaseRequest shutdown_pre_release
;
647 expect_pre_release_request(shutdown_pre_release
, 0);
648 ASSERT_EQ(0, when_pre_release_lock_handler(exclusive_lock
, true));
650 expect_unblock_writes(mock_image_ctx
);
651 expect_notify_released_lock(mock_image_ctx
);
652 ASSERT_EQ(0, when_post_release_lock_handler(exclusive_lock
, true, 0));
655 TEST_F(TestMockExclusiveLock
, BlockRequests
) {
656 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK
);
658 librbd::ImageCtx
*ictx
;
659 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
661 MockExclusiveLockImageCtx
mock_image_ctx(*ictx
);
662 MockExclusiveLock
exclusive_lock(mock_image_ctx
);
664 expect_op_work_queue(mock_image_ctx
);
667 expect_set_state_initializing(exclusive_lock
);
668 expect_block_writes(mock_image_ctx
);
669 expect_set_state_unlocked(exclusive_lock
);
670 ASSERT_EQ(0, when_init(mock_image_ctx
, exclusive_lock
));
673 expect_is_state_shutdown(exclusive_lock
, false);
674 expect_is_state_locked(exclusive_lock
, true);
675 ASSERT_TRUE(exclusive_lock
.accept_requests(&ret_val
));
676 ASSERT_EQ(0, ret_val
);
678 exclusive_lock
.block_requests(-EROFS
);
679 expect_is_state_shutdown(exclusive_lock
, false);
680 expect_is_state_locked(exclusive_lock
, true);
681 ASSERT_FALSE(exclusive_lock
.accept_requests(&ret_val
));
682 ASSERT_EQ(-EROFS
, ret_val
);
684 exclusive_lock
.unblock_requests();
685 expect_is_state_shutdown(exclusive_lock
, false);
686 expect_is_state_locked(exclusive_lock
, true);
687 ASSERT_TRUE(exclusive_lock
.accept_requests(&ret_val
));
688 ASSERT_EQ(0, ret_val
);
691 } // namespace librbd