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