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 "librbd/ManagedLock.h"
7 #include "librbd/managed_lock/AcquireRequest.h"
8 #include "librbd/managed_lock/BreakRequest.h"
9 #include "librbd/managed_lock/GetLockerRequest.h"
10 #include "librbd/managed_lock/ReacquireRequest.h"
11 #include "librbd/managed_lock/ReleaseRequest.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
20 struct MockManagedLockImageCtx
: public MockImageCtx
{
21 explicit MockManagedLockImageCtx(ImageCtx
&image_ctx
) : MockImageCtx(image_ctx
) {}
26 struct Traits
<MockManagedLockImageCtx
> {
27 typedef librbd::MockImageWatcher Watcher
;
31 struct MockMockManagedLock
: public ManagedLock
<MockManagedLockImageCtx
> {
32 MockMockManagedLock(librados::IoCtx
& ioctx
, AsioEngine
& asio_engine
,
33 const std::string
& oid
, librbd::MockImageWatcher
*watcher
,
34 managed_lock::Mode mode
, bool blocklist_on_break_lock
,
35 uint32_t blocklist_expire_seconds
)
36 : ManagedLock
<MockManagedLockImageCtx
>(ioctx
, asio_engine
, oid
, watcher
,
37 librbd::managed_lock::EXCLUSIVE
, true, 0) {
39 virtual ~MockMockManagedLock() = default;
41 MOCK_METHOD2(post_reacquire_lock_handler
, void(int, Context
*));
43 MOCK_METHOD2(pre_release_lock_handler
, void(bool, Context
*));
44 MOCK_METHOD3(post_release_lock_handler
, void(bool, int, Context
*));
47 namespace managed_lock
{
51 static std::list
<T
*> s_requests
;
52 Context
*on_finish
= nullptr;
54 static T
* create(librados::IoCtx
& ioctx
, MockImageWatcher
*watcher
,
55 const std::string
& oid
, const std::string
& cookie
,
57 ceph_assert(!s_requests
.empty());
58 T
* req
= s_requests
.front();
59 req
->on_finish
= on_finish
;
60 s_requests
.pop_front();
65 s_requests
.push_back(reinterpret_cast<T
*>(this));
70 std::list
<T
*> BaseRequest
<T
>::s_requests
;
73 struct AcquireRequest
<MockManagedLockImageCtx
>
74 : public BaseRequest
<AcquireRequest
<MockManagedLockImageCtx
> > {
75 static AcquireRequest
* create(librados::IoCtx
& ioctx
,
76 MockImageWatcher
*watcher
,
77 AsioEngine
& asio_engine
,
78 const std::string
& oid
,
79 const std::string
& cookie
,
80 bool exclusive
, bool blocklist_on_break_lock
,
81 uint32_t blocklist_expire_seconds
,
83 return BaseRequest::create(ioctx
, watcher
, oid
, cookie
, on_finish
);
86 MOCK_METHOD0(send
, void());
90 struct ReacquireRequest
<MockManagedLockImageCtx
> : public BaseRequest
<ReacquireRequest
<MockManagedLockImageCtx
> > {
91 static ReacquireRequest
* create(librados::IoCtx
&ioctx
, const std::string
& oid
,
92 const string
& old_cookie
, const std::string
& new_cookie
,
93 bool exclusive
, Context
*on_finish
) {
94 return BaseRequest::create(ioctx
, nullptr, oid
, new_cookie
,
98 MOCK_METHOD0(send
, void());
102 struct ReleaseRequest
<MockManagedLockImageCtx
> : public BaseRequest
<ReleaseRequest
<MockManagedLockImageCtx
> > {
103 static ReleaseRequest
* create(librados::IoCtx
& ioctx
, MockImageWatcher
*watcher
,
104 asio::ContextWQ
*work_queue
,
105 const std::string
& oid
,
106 const std::string
& cookie
, Context
*on_finish
) {
107 return BaseRequest::create(ioctx
, watcher
, oid
, cookie
, on_finish
);
109 MOCK_METHOD0(send
, void());
113 struct GetLockerRequest
<MockManagedLockImageCtx
> {
114 static GetLockerRequest
* create(librados::IoCtx
& ioctx
,
115 const std::string
& oid
, bool exclusive
,
116 Locker
*locker
, Context
*on_finish
) {
117 ceph_abort_msg("unexpected call");
121 ceph_abort_msg("unexpected call");
126 struct BreakRequest
<MockManagedLockImageCtx
> {
127 static BreakRequest
* create(librados::IoCtx
& ioctx
,
128 AsioEngine
& asio_engine
,
129 const std::string
& oid
, const Locker
&locker
,
130 bool exclusive
, bool blocklist_locker
,
131 uint32_t blocklist_expire_seconds
,
132 bool force_break_lock
, Context
*on_finish
) {
133 ceph_abort_msg("unexpected call");
137 ceph_abort_msg("unexpected call");
141 } // namespace managed_lock
142 } // namespace librbd
144 // template definitions
145 #include "librbd/ManagedLock.cc"
146 template class librbd::ManagedLock
<librbd::MockManagedLockImageCtx
>;
149 ACTION_P3(QueueRequest
, request
, r
, wq
) {
150 if (request
->on_finish
!= nullptr) {
152 wq
->queue(request
->on_finish
, r
);
154 request
->on_finish
->complete(r
);
159 ACTION_P2(QueueContext
, r
, wq
) {
163 ACTION_P(Notify
, ctx
) {
170 using ::testing::DoAll
;
171 using ::testing::Invoke
;
172 using ::testing::InSequence
;
173 using ::testing::Return
;
174 using ::testing::WithArg
;
176 class TestMockManagedLock
: public TestMockFixture
{
178 typedef ManagedLock
<MockManagedLockImageCtx
> MockManagedLock
;
179 typedef managed_lock::AcquireRequest
<MockManagedLockImageCtx
> MockAcquireRequest
;
180 typedef managed_lock::ReacquireRequest
<MockManagedLockImageCtx
> MockReacquireRequest
;
181 typedef managed_lock::ReleaseRequest
<MockManagedLockImageCtx
> MockReleaseRequest
;
183 void expect_get_watch_handle(MockImageWatcher
&mock_watcher
,
184 uint64_t watch_handle
= 1234567890) {
185 EXPECT_CALL(mock_watcher
, get_watch_handle())
186 .WillOnce(Return(watch_handle
));
189 void expect_acquire_lock(MockImageWatcher
&watcher
,
190 asio::ContextWQ
*work_queue
,
191 MockAcquireRequest
&acquire_request
, int r
) {
192 expect_get_watch_handle(watcher
);
193 EXPECT_CALL(acquire_request
, send())
194 .WillOnce(QueueRequest(&acquire_request
, r
, work_queue
));
197 void expect_release_lock(asio::ContextWQ
*work_queue
,
198 MockReleaseRequest
&release_request
, int r
) {
199 EXPECT_CALL(release_request
, send())
200 .WillOnce(QueueRequest(&release_request
, r
, work_queue
));
203 void expect_reacquire_lock(MockImageWatcher
& watcher
,
204 asio::ContextWQ
*work_queue
,
205 MockReacquireRequest
&mock_reacquire_request
,
207 EXPECT_CALL(mock_reacquire_request
, send())
208 .WillOnce(QueueRequest(&mock_reacquire_request
, r
, work_queue
));
211 void expect_flush_notifies(MockImageWatcher
*mock_watcher
) {
212 EXPECT_CALL(*mock_watcher
, flush(_
))
213 .WillOnce(CompleteContext(0, (asio::ContextWQ
*)nullptr));
216 void expect_post_reacquired_lock_handler(MockImageWatcher
& watcher
,
217 MockMockManagedLock
&managed_lock
, uint64_t &client_id
) {
218 expect_get_watch_handle(watcher
);
219 EXPECT_CALL(managed_lock
, post_reacquire_lock_handler(_
, _
))
220 .WillOnce(Invoke([&client_id
](int r
, Context
*on_finish
){
224 on_finish
->complete(r
);}));
227 void expect_pre_release_lock_handler(MockMockManagedLock
&managed_lock
,
228 bool shutting_down
, int r
) {
229 EXPECT_CALL(managed_lock
, pre_release_lock_handler(shutting_down
, _
))
230 .WillOnce(WithArg
<1>(Invoke([r
](Context
*on_finish
){
231 on_finish
->complete(r
);
235 void expect_post_release_lock_handler(MockMockManagedLock
&managed_lock
,
236 bool shutting_down
, int expect_r
,
238 EXPECT_CALL(managed_lock
, post_release_lock_handler(shutting_down
, expect_r
, _
))
239 .WillOnce(WithArg
<2>(Invoke([r
](Context
*on_finish
){
240 on_finish
->complete(r
);
244 int when_acquire_lock(MockManagedLock
&managed_lock
) {
247 managed_lock
.acquire_lock(&ctx
);
251 int when_release_lock(MockManagedLock
&managed_lock
) {
254 managed_lock
.release_lock(&ctx
);
258 int when_shut_down(MockManagedLock
&managed_lock
) {
261 managed_lock
.shut_down(&ctx
);
266 bool is_lock_owner(MockManagedLock
&managed_lock
) {
267 return managed_lock
.is_lock_owner();
271 TEST_F(TestMockManagedLock
, StateTransitions
) {
272 librbd::ImageCtx
*ictx
;
273 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
275 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
276 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
277 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
278 librbd::managed_lock::EXCLUSIVE
, true, 0);
281 MockAcquireRequest request_lock_acquire1
;
282 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, request_lock_acquire1
, 0);
283 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
284 ASSERT_TRUE(is_lock_owner(managed_lock
));
286 MockReleaseRequest request_release
;
287 expect_release_lock(ictx
->op_work_queue
, request_release
, 0);
288 ASSERT_EQ(0, when_release_lock(managed_lock
));
289 ASSERT_FALSE(is_lock_owner(managed_lock
));
291 MockAcquireRequest request_lock_acquire2
;
292 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, request_lock_acquire2
, 0);
293 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
294 ASSERT_TRUE(is_lock_owner(managed_lock
));
296 MockReleaseRequest shutdown_release
;
297 expect_release_lock(ictx
->op_work_queue
, shutdown_release
, 0);
298 ASSERT_EQ(0, when_shut_down(managed_lock
));
299 ASSERT_FALSE(is_lock_owner(managed_lock
));
302 TEST_F(TestMockManagedLock
, AcquireLockLockedState
) {
303 librbd::ImageCtx
*ictx
;
304 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
306 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
307 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
308 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
309 librbd::managed_lock::EXCLUSIVE
, true, 0);
312 MockAcquireRequest try_lock_acquire
;
313 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, try_lock_acquire
, 0);
314 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
315 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
317 MockReleaseRequest shutdown_release
;
318 expect_release_lock(ictx
->op_work_queue
, shutdown_release
, 0);
319 ASSERT_EQ(0, when_shut_down(managed_lock
));
322 TEST_F(TestMockManagedLock
, AcquireLockAlreadyLocked
) {
323 librbd::ImageCtx
*ictx
;
324 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
326 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
327 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
328 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
329 librbd::managed_lock::EXCLUSIVE
, true, 0);
332 MockAcquireRequest try_lock_acquire
;
333 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, try_lock_acquire
, -EAGAIN
);
334 ASSERT_EQ(-EAGAIN
, when_acquire_lock(managed_lock
));
335 ASSERT_FALSE(is_lock_owner(managed_lock
));
337 ASSERT_EQ(0, when_shut_down(managed_lock
));
340 TEST_F(TestMockManagedLock
, AcquireLockBusy
) {
341 librbd::ImageCtx
*ictx
;
342 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
344 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
345 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
346 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
347 librbd::managed_lock::EXCLUSIVE
, true, 0);
350 MockAcquireRequest try_lock_acquire
;
351 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, try_lock_acquire
, -EBUSY
);
352 ASSERT_EQ(-EBUSY
, when_acquire_lock(managed_lock
));
353 ASSERT_FALSE(is_lock_owner(managed_lock
));
355 ASSERT_EQ(0, when_shut_down(managed_lock
));
358 TEST_F(TestMockManagedLock
, AcquireLockError
) {
359 librbd::ImageCtx
*ictx
;
360 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
362 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
363 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
364 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
365 librbd::managed_lock::EXCLUSIVE
, true, 0);
368 MockAcquireRequest try_lock_acquire
;
369 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, try_lock_acquire
, -EINVAL
);
371 ASSERT_EQ(-EINVAL
, when_acquire_lock(managed_lock
));
372 ASSERT_FALSE(is_lock_owner(managed_lock
));
374 ASSERT_EQ(0, when_shut_down(managed_lock
));
377 TEST_F(TestMockManagedLock
, AcquireLockBlocklist
) {
378 librbd::ImageCtx
*ictx
;
379 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
381 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
382 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
383 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
384 librbd::managed_lock::EXCLUSIVE
, true, 0);
387 // will abort after seeing blocklist error (avoid infinite request loop)
388 MockAcquireRequest request_lock_acquire
;
389 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, request_lock_acquire
, -EBLOCKLISTED
);
390 ASSERT_EQ(-EBLOCKLISTED
, when_acquire_lock(managed_lock
));
391 ASSERT_FALSE(is_lock_owner(managed_lock
));
393 ASSERT_EQ(0, when_shut_down(managed_lock
));
396 TEST_F(TestMockManagedLock
, ReleaseLockUnlockedState
) {
397 librbd::ImageCtx
*ictx
;
398 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
400 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
401 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
402 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
403 librbd::managed_lock::EXCLUSIVE
, true, 0);
406 ASSERT_EQ(0, when_release_lock(managed_lock
));
408 ASSERT_EQ(0, when_shut_down(managed_lock
));
411 TEST_F(TestMockManagedLock
, ReleaseLockBlocklist
) {
412 librbd::ImageCtx
*ictx
;
413 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
415 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
416 MockMockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
417 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
418 librbd::managed_lock::EXCLUSIVE
, true, 0);
421 MockAcquireRequest try_lock_acquire
;
422 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, try_lock_acquire
, 0);
423 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
425 expect_pre_release_lock_handler(managed_lock
, false, -EBLOCKLISTED
);
426 expect_post_release_lock_handler(managed_lock
, false, -EBLOCKLISTED
, -EBLOCKLISTED
);
427 ASSERT_EQ(-EBLOCKLISTED
, when_release_lock(managed_lock
));
428 ASSERT_FALSE(is_lock_owner(managed_lock
));
430 ASSERT_EQ(0, when_shut_down(managed_lock
));
433 TEST_F(TestMockManagedLock
, ReleaseLockError
) {
434 librbd::ImageCtx
*ictx
;
435 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
437 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
438 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
439 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
440 librbd::managed_lock::EXCLUSIVE
, true, 0);
443 MockAcquireRequest try_lock_acquire
;
444 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, try_lock_acquire
, 0);
445 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
447 MockReleaseRequest release
;
448 expect_release_lock(ictx
->op_work_queue
, release
, -EINVAL
);
450 ASSERT_EQ(-EINVAL
, when_release_lock(managed_lock
));
451 ASSERT_TRUE(is_lock_owner(managed_lock
));
453 MockReleaseRequest shutdown_release
;
454 expect_release_lock(ictx
->op_work_queue
, shutdown_release
, 0);
455 ASSERT_EQ(0, when_shut_down(managed_lock
));
456 ASSERT_FALSE(is_lock_owner(managed_lock
));
459 TEST_F(TestMockManagedLock
, ConcurrentRequests
) {
460 librbd::ImageCtx
*ictx
;
461 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
463 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
464 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
465 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
466 librbd::managed_lock::EXCLUSIVE
, true, 0);
469 expect_get_watch_handle(*mock_image_ctx
.image_watcher
);
471 C_SaferCond wait_for_send_ctx1
;
472 MockAcquireRequest acquire_error
;
473 EXPECT_CALL(acquire_error
, send())
474 .WillOnce(Notify(&wait_for_send_ctx1
));
476 MockAcquireRequest request_acquire
;
477 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, request_acquire
, 0);
479 MockReleaseRequest release
;
480 C_SaferCond wait_for_send_ctx2
;
481 EXPECT_CALL(release
, send())
482 .WillOnce(Notify(&wait_for_send_ctx2
));
484 C_SaferCond acquire_request_ctx1
;
485 managed_lock
.acquire_lock(&acquire_request_ctx1
);
487 C_SaferCond acquire_lock_ctx1
;
488 C_SaferCond acquire_lock_ctx2
;
489 managed_lock
.acquire_lock(&acquire_lock_ctx1
);
490 managed_lock
.acquire_lock(&acquire_lock_ctx2
);
493 ASSERT_EQ(0, wait_for_send_ctx1
.wait());
494 acquire_error
.on_finish
->complete(-EINVAL
);
495 ASSERT_EQ(-EINVAL
, acquire_request_ctx1
.wait());
497 C_SaferCond acquire_lock_ctx3
;
498 managed_lock
.acquire_lock(&acquire_lock_ctx3
);
500 C_SaferCond release_lock_ctx1
;
501 managed_lock
.release_lock(&release_lock_ctx1
);
503 // all three pending request locks should complete
504 ASSERT_EQ(-EINVAL
, acquire_lock_ctx1
.wait());
505 ASSERT_EQ(-EINVAL
, acquire_lock_ctx2
.wait());
506 ASSERT_EQ(0, acquire_lock_ctx3
.wait());
508 // proceed with the release
509 ASSERT_EQ(0, wait_for_send_ctx2
.wait());
510 release
.on_finish
->complete(0);
511 ASSERT_EQ(0, release_lock_ctx1
.wait());
513 ASSERT_EQ(0, when_shut_down(managed_lock
));
516 TEST_F(TestMockManagedLock
, ReacquireLock
) {
517 librbd::ImageCtx
*ictx
;
518 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
520 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
521 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
522 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
523 librbd::managed_lock::EXCLUSIVE
, true, 0);
526 MockAcquireRequest request_lock_acquire
;
527 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, request_lock_acquire
, 0);
528 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
529 ASSERT_TRUE(is_lock_owner(managed_lock
));
531 MockReacquireRequest mock_reacquire_request
;
532 C_SaferCond reacquire_ctx
;
533 expect_get_watch_handle(*mock_image_ctx
.image_watcher
, 98765);
534 expect_reacquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, mock_reacquire_request
, 0);
535 managed_lock
.reacquire_lock(&reacquire_ctx
);
536 ASSERT_EQ(0, reacquire_ctx
.wait());
538 MockReleaseRequest shutdown_release
;
539 expect_release_lock(ictx
->op_work_queue
, shutdown_release
, 0);
540 ASSERT_EQ(0, when_shut_down(managed_lock
));
541 ASSERT_FALSE(is_lock_owner(managed_lock
));
544 TEST_F(TestMockManagedLock
, AttemptReacquireBlocklistedLock
) {
545 librbd::ImageCtx
*ictx
;
546 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
548 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
549 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
550 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
551 librbd::managed_lock::EXCLUSIVE
, true, 0);
554 MockAcquireRequest request_lock_acquire
;
555 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
,
556 request_lock_acquire
, 0);
557 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
558 ASSERT_TRUE(is_lock_owner(managed_lock
));
560 expect_get_watch_handle(*mock_image_ctx
.image_watcher
, 0);
562 MockReleaseRequest request_release
;
563 expect_release_lock(ictx
->op_work_queue
, request_release
, 0);
565 expect_get_watch_handle(*mock_image_ctx
.image_watcher
, 0);
567 managed_lock
.reacquire_lock(nullptr);
569 ASSERT_EQ(0, when_shut_down(managed_lock
));
570 ASSERT_FALSE(is_lock_owner(managed_lock
));
573 TEST_F(TestMockManagedLock
, ReacquireBlocklistedLock
) {
574 librbd::ImageCtx
*ictx
;
575 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
577 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
578 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
579 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
580 librbd::managed_lock::EXCLUSIVE
, true, 0);
583 MockAcquireRequest request_lock_acquire
;
584 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
,
585 request_lock_acquire
, 0);
586 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
587 ASSERT_TRUE(is_lock_owner(managed_lock
));
589 expect_get_watch_handle(*mock_image_ctx
.image_watcher
, 0);
591 MockReleaseRequest request_release
;
592 expect_release_lock(ictx
->op_work_queue
, request_release
, 0);
594 MockAcquireRequest request_lock_reacquire
;
595 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
,
596 request_lock_reacquire
, 0);
597 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
598 ASSERT_TRUE(is_lock_owner(managed_lock
));
600 C_SaferCond reacquire_ctx
;
601 managed_lock
.reacquire_lock(&reacquire_ctx
);
602 ASSERT_EQ(0, reacquire_ctx
.wait());
604 MockReleaseRequest shutdown_release
;
605 expect_release_lock(ictx
->op_work_queue
, shutdown_release
, 0);
606 ASSERT_EQ(0, when_shut_down(managed_lock
));
607 ASSERT_FALSE(is_lock_owner(managed_lock
));
610 TEST_F(TestMockManagedLock
, ReacquireLockError
) {
611 librbd::ImageCtx
*ictx
;
612 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
614 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
615 MockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
616 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
617 librbd::managed_lock::EXCLUSIVE
, true, 0);
620 MockAcquireRequest request_lock_acquire
;
621 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, request_lock_acquire
, 0);
622 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
623 ASSERT_TRUE(is_lock_owner(managed_lock
));
625 MockReacquireRequest mock_reacquire_request
;
626 C_SaferCond reacquire_ctx
;
627 expect_get_watch_handle(*mock_image_ctx
.image_watcher
, 98765);
628 expect_reacquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, mock_reacquire_request
, -EOPNOTSUPP
);
630 MockReleaseRequest reacquire_lock_release
;
631 expect_release_lock(ictx
->op_work_queue
, reacquire_lock_release
, 0);
633 MockAcquireRequest reacquire_lock_acquire
;
634 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, reacquire_lock_acquire
, 0);
636 managed_lock
.reacquire_lock(&reacquire_ctx
);
637 ASSERT_EQ(0, reacquire_ctx
.wait());
639 MockReleaseRequest shutdown_release
;
640 expect_release_lock(ictx
->op_work_queue
, shutdown_release
, 0);
641 ASSERT_EQ(0, when_shut_down(managed_lock
));
642 ASSERT_FALSE(is_lock_owner(managed_lock
));
645 TEST_F(TestMockManagedLock
, ReacquireWithSameCookie
) {
646 librbd::ImageCtx
*ictx
;
647 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
649 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
650 MockMockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
651 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
652 librbd::managed_lock::EXCLUSIVE
, true, 0);
655 MockAcquireRequest request_lock_acquire
;
656 expect_acquire_lock(*mock_image_ctx
.image_watcher
, ictx
->op_work_queue
, request_lock_acquire
, 0);
657 ASSERT_EQ(0, when_acquire_lock(managed_lock
));
658 ASSERT_TRUE(is_lock_owner(managed_lock
));
660 // watcher with same cookie after rewatch
661 uint64_t client_id
= 0;
662 C_SaferCond reacquire_ctx
;
663 expect_post_reacquired_lock_handler(*mock_image_ctx
.image_watcher
, managed_lock
, client_id
);
664 managed_lock
.reacquire_lock(&reacquire_ctx
);
665 ASSERT_LT(0U, client_id
);
666 ASSERT_TRUE(is_lock_owner(managed_lock
));
668 MockReleaseRequest shutdown_release
;
669 expect_pre_release_lock_handler(managed_lock
, true, 0);
670 expect_release_lock(ictx
->op_work_queue
, shutdown_release
, 0);
671 expect_post_release_lock_handler(managed_lock
, true, 0, 0);
672 ASSERT_EQ(0, when_shut_down(managed_lock
));
675 TEST_F(TestMockManagedLock
, ShutDownWhileWaiting
) {
676 librbd::ImageCtx
*ictx
;
677 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
679 MockManagedLockImageCtx
mock_image_ctx(*ictx
);
680 MockMockManagedLock
managed_lock(ictx
->md_ctx
, *ictx
->asio_engine
,
681 ictx
->header_oid
, mock_image_ctx
.image_watcher
,
682 librbd::managed_lock::EXCLUSIVE
, true, 0);
686 expect_get_watch_handle(*mock_image_ctx
.image_watcher
, 0);
688 C_SaferCond acquire_ctx
;
689 managed_lock
.acquire_lock(&acquire_ctx
);
691 ASSERT_EQ(0, when_shut_down(managed_lock
));
692 ASSERT_EQ(-ESHUTDOWN
, acquire_ctx
.wait());
693 ASSERT_FALSE(is_lock_owner(managed_lock
));
696 } // namespace librbd