]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librbd/test_mock_ManagedLock.cc
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / test / librbd / test_mock_ManagedLock.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
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"
14#include <list>
15
20effc67
TL
16using namespace std;
17
7c673cae
FG
18namespace librbd {
19
20struct MockManagedLockImageCtx : public MockImageCtx {
11fdf7f2 21 explicit MockManagedLockImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {}
7c673cae
FG
22};
23
24namespace watcher {
25template <>
26struct Traits<MockManagedLockImageCtx> {
27 typedef librbd::MockImageWatcher Watcher;
28};
29}
30
91327a77 31struct MockMockManagedLock : public ManagedLock<MockManagedLockImageCtx> {
f67539c2 32 MockMockManagedLock(librados::IoCtx& ioctx, AsioEngine& asio_engine,
91327a77 33 const std::string& oid, librbd::MockImageWatcher *watcher,
f67539c2
TL
34 managed_lock::Mode mode, bool blocklist_on_break_lock,
35 uint32_t blocklist_expire_seconds)
36 : ManagedLock<MockManagedLockImageCtx>(ioctx, asio_engine, oid, watcher,
91327a77
AA
37 librbd::managed_lock::EXCLUSIVE, true, 0) {
38 };
39 virtual ~MockMockManagedLock() = default;
40
41 MOCK_METHOD2(post_reacquire_lock_handler, void(int, Context*));
42
43 MOCK_METHOD2(pre_release_lock_handler, void(bool, Context*));
44 MOCK_METHOD3(post_release_lock_handler, void(bool, int, Context*));
45};
46
7c673cae
FG
47namespace managed_lock {
48
49template<typename T>
50struct BaseRequest {
51 static std::list<T *> s_requests;
52 Context *on_finish = nullptr;
53
54 static T* create(librados::IoCtx& ioctx, MockImageWatcher *watcher,
f67539c2
TL
55 const std::string& oid, const std::string& cookie,
56 Context *on_finish) {
11fdf7f2 57 ceph_assert(!s_requests.empty());
7c673cae
FG
58 T* req = s_requests.front();
59 req->on_finish = on_finish;
60 s_requests.pop_front();
61 return req;
62 }
63
64 BaseRequest() {
65 s_requests.push_back(reinterpret_cast<T*>(this));
66 }
67};
68
69template<typename T>
70std::list<T *> BaseRequest<T>::s_requests;
71
72template <>
f67539c2
TL
73struct AcquireRequest<MockManagedLockImageCtx>
74 : public BaseRequest<AcquireRequest<MockManagedLockImageCtx> > {
7c673cae
FG
75 static AcquireRequest* create(librados::IoCtx& ioctx,
76 MockImageWatcher *watcher,
f67539c2
TL
77 AsioEngine& asio_engine,
78 const std::string& oid,
7c673cae 79 const std::string& cookie,
f67539c2
TL
80 bool exclusive, bool blocklist_on_break_lock,
81 uint32_t blocklist_expire_seconds,
7c673cae 82 Context *on_finish) {
f67539c2 83 return BaseRequest::create(ioctx, watcher, oid, cookie, on_finish);
7c673cae
FG
84 }
85
86 MOCK_METHOD0(send, void());
87};
88
89template <>
90struct 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) {
f67539c2 94 return BaseRequest::create(ioctx, nullptr, oid, new_cookie,
7c673cae
FG
95 on_finish);
96 }
97
98 MOCK_METHOD0(send, void());
99};
100
101template <>
102struct ReleaseRequest<MockManagedLockImageCtx> : public BaseRequest<ReleaseRequest<MockManagedLockImageCtx> > {
103 static ReleaseRequest* create(librados::IoCtx& ioctx, MockImageWatcher *watcher,
f67539c2
TL
104 asio::ContextWQ *work_queue,
105 const std::string& oid,
7c673cae 106 const std::string& cookie, Context *on_finish) {
f67539c2 107 return BaseRequest::create(ioctx, watcher, oid, cookie, on_finish);
7c673cae
FG
108 }
109 MOCK_METHOD0(send, void());
110};
111
112template <>
113struct GetLockerRequest<MockManagedLockImageCtx> {
114 static GetLockerRequest* create(librados::IoCtx& ioctx,
115 const std::string& oid, bool exclusive,
116 Locker *locker, Context *on_finish) {
11fdf7f2 117 ceph_abort_msg("unexpected call");
7c673cae
FG
118 }
119
120 void send() {
11fdf7f2 121 ceph_abort_msg("unexpected call");
7c673cae
FG
122 }
123};
124
125template <>
126struct BreakRequest<MockManagedLockImageCtx> {
f67539c2
TL
127 static BreakRequest* create(librados::IoCtx& ioctx,
128 AsioEngine& asio_engine,
7c673cae 129 const std::string& oid, const Locker &locker,
f67539c2
TL
130 bool exclusive, bool blocklist_locker,
131 uint32_t blocklist_expire_seconds,
7c673cae 132 bool force_break_lock, Context *on_finish) {
11fdf7f2 133 ceph_abort_msg("unexpected call");
7c673cae
FG
134 }
135
136 void send() {
11fdf7f2 137 ceph_abort_msg("unexpected call");
7c673cae
FG
138 }
139};
140
141} // namespace managed_lock
142} // namespace librbd
143
144// template definitions
145#include "librbd/ManagedLock.cc"
146template class librbd::ManagedLock<librbd::MockManagedLockImageCtx>;
147
148
149ACTION_P3(QueueRequest, request, r, wq) {
150 if (request->on_finish != nullptr) {
151 if (wq != nullptr) {
152 wq->queue(request->on_finish, r);
153 } else {
154 request->on_finish->complete(r);
155 }
156 }
157}
158
159ACTION_P2(QueueContext, r, wq) {
160 wq->queue(arg0, r);
161}
162
11fdf7f2
TL
163ACTION_P(Notify, ctx) {
164 ctx->complete(0);
165}
166
7c673cae
FG
167namespace librbd {
168
169using ::testing::_;
170using ::testing::DoAll;
171using ::testing::Invoke;
172using ::testing::InSequence;
173using ::testing::Return;
91327a77 174using ::testing::WithArg;
7c673cae
FG
175
176class TestMockManagedLock : public TestMockFixture {
177public:
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;
182
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));
187 }
188
189 void expect_acquire_lock(MockImageWatcher &watcher,
f67539c2 190 asio::ContextWQ *work_queue,
7c673cae
FG
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));
195 }
196
1e59de90
TL
197 void expect_is_blocklisted(MockImageWatcher &watcher,
198 bool blocklisted) {
199 EXPECT_CALL(watcher, is_blocklisted()).WillOnce(Return(blocklisted));
200 }
201
f67539c2 202 void expect_release_lock(asio::ContextWQ *work_queue,
7c673cae
FG
203 MockReleaseRequest &release_request, int r) {
204 EXPECT_CALL(release_request, send())
205 .WillOnce(QueueRequest(&release_request, r, work_queue));
206 }
207
208 void expect_reacquire_lock(MockImageWatcher& watcher,
f67539c2 209 asio::ContextWQ *work_queue,
7c673cae
FG
210 MockReacquireRequest &mock_reacquire_request,
211 int r) {
7c673cae
FG
212 EXPECT_CALL(mock_reacquire_request, send())
213 .WillOnce(QueueRequest(&mock_reacquire_request, r, work_queue));
214 }
215
216 void expect_flush_notifies(MockImageWatcher *mock_watcher) {
217 EXPECT_CALL(*mock_watcher, flush(_))
f67539c2 218 .WillOnce(CompleteContext(0, (asio::ContextWQ *)nullptr));
7c673cae
FG
219 }
220
f67539c2 221 void expect_post_reacquired_lock_handler(MockImageWatcher& watcher,
11fdf7f2 222 MockMockManagedLock &managed_lock, uint64_t &client_id) {
91327a77
AA
223 expect_get_watch_handle(watcher);
224 EXPECT_CALL(managed_lock, post_reacquire_lock_handler(_, _))
11fdf7f2 225 .WillOnce(Invoke([&client_id](int r, Context *on_finish){
91327a77
AA
226 if (r >= 0) {
227 client_id = 98765;
228 }
229 on_finish->complete(r);}));
230 }
231
232 void expect_pre_release_lock_handler(MockMockManagedLock &managed_lock,
233 bool shutting_down, int r) {
234 EXPECT_CALL(managed_lock, pre_release_lock_handler(shutting_down, _))
235 .WillOnce(WithArg<1>(Invoke([r](Context *on_finish){
236 on_finish->complete(r);
237 })));
238 }
239
240 void expect_post_release_lock_handler(MockMockManagedLock &managed_lock,
241 bool shutting_down, int expect_r,
242 int r) {
243 EXPECT_CALL(managed_lock, post_release_lock_handler(shutting_down, expect_r, _))
244 .WillOnce(WithArg<2>(Invoke([r](Context *on_finish){
245 on_finish->complete(r);
246 })));
247 }
248
7c673cae
FG
249 int when_acquire_lock(MockManagedLock &managed_lock) {
250 C_SaferCond ctx;
251 {
252 managed_lock.acquire_lock(&ctx);
253 }
254 return ctx.wait();
255 }
256 int when_release_lock(MockManagedLock &managed_lock) {
257 C_SaferCond ctx;
258 {
259 managed_lock.release_lock(&ctx);
260 }
261 return ctx.wait();
262 }
263 int when_shut_down(MockManagedLock &managed_lock) {
264 C_SaferCond ctx;
265 {
266 managed_lock.shut_down(&ctx);
267 }
268 return ctx.wait();
269 }
270
271 bool is_lock_owner(MockManagedLock &managed_lock) {
272 return managed_lock.is_lock_owner();
273 }
274};
275
276TEST_F(TestMockManagedLock, StateTransitions) {
277 librbd::ImageCtx *ictx;
278 ASSERT_EQ(0, open_image(m_image_name, &ictx));
279
280 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 281 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
282 ictx->header_oid, mock_image_ctx.image_watcher,
283 librbd::managed_lock::EXCLUSIVE, true, 0);
284 InSequence seq;
285
286 MockAcquireRequest request_lock_acquire1;
287 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, request_lock_acquire1, 0);
288 ASSERT_EQ(0, when_acquire_lock(managed_lock));
289 ASSERT_TRUE(is_lock_owner(managed_lock));
290
291 MockReleaseRequest request_release;
292 expect_release_lock(ictx->op_work_queue, request_release, 0);
293 ASSERT_EQ(0, when_release_lock(managed_lock));
294 ASSERT_FALSE(is_lock_owner(managed_lock));
295
296 MockAcquireRequest request_lock_acquire2;
297 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, request_lock_acquire2, 0);
298 ASSERT_EQ(0, when_acquire_lock(managed_lock));
299 ASSERT_TRUE(is_lock_owner(managed_lock));
300
301 MockReleaseRequest shutdown_release;
302 expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
303 ASSERT_EQ(0, when_shut_down(managed_lock));
304 ASSERT_FALSE(is_lock_owner(managed_lock));
305}
306
307TEST_F(TestMockManagedLock, AcquireLockLockedState) {
308 librbd::ImageCtx *ictx;
309 ASSERT_EQ(0, open_image(m_image_name, &ictx));
310
311 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 312 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
313 ictx->header_oid, mock_image_ctx.image_watcher,
314 librbd::managed_lock::EXCLUSIVE, true, 0);
315 InSequence seq;
316
317 MockAcquireRequest try_lock_acquire;
318 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, try_lock_acquire, 0);
319 ASSERT_EQ(0, when_acquire_lock(managed_lock));
320 ASSERT_EQ(0, when_acquire_lock(managed_lock));
321
322 MockReleaseRequest shutdown_release;
323 expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
324 ASSERT_EQ(0, when_shut_down(managed_lock));
325}
326
327TEST_F(TestMockManagedLock, AcquireLockAlreadyLocked) {
328 librbd::ImageCtx *ictx;
329 ASSERT_EQ(0, open_image(m_image_name, &ictx));
330
331 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 332 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
333 ictx->header_oid, mock_image_ctx.image_watcher,
334 librbd::managed_lock::EXCLUSIVE, true, 0);
335 InSequence seq;
336
337 MockAcquireRequest try_lock_acquire;
338 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, try_lock_acquire, -EAGAIN);
339 ASSERT_EQ(-EAGAIN, when_acquire_lock(managed_lock));
340 ASSERT_FALSE(is_lock_owner(managed_lock));
341
342 ASSERT_EQ(0, when_shut_down(managed_lock));
343}
344
345TEST_F(TestMockManagedLock, AcquireLockBusy) {
346 librbd::ImageCtx *ictx;
347 ASSERT_EQ(0, open_image(m_image_name, &ictx));
348
349 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 350 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
351 ictx->header_oid, mock_image_ctx.image_watcher,
352 librbd::managed_lock::EXCLUSIVE, true, 0);
353 InSequence seq;
354
355 MockAcquireRequest try_lock_acquire;
356 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, try_lock_acquire, -EBUSY);
357 ASSERT_EQ(-EBUSY, when_acquire_lock(managed_lock));
358 ASSERT_FALSE(is_lock_owner(managed_lock));
359
360 ASSERT_EQ(0, when_shut_down(managed_lock));
361}
362
363TEST_F(TestMockManagedLock, AcquireLockError) {
364 librbd::ImageCtx *ictx;
365 ASSERT_EQ(0, open_image(m_image_name, &ictx));
366
367 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 368 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
369 ictx->header_oid, mock_image_ctx.image_watcher,
370 librbd::managed_lock::EXCLUSIVE, true, 0);
371 InSequence seq;
372
373 MockAcquireRequest try_lock_acquire;
374 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, try_lock_acquire, -EINVAL);
375
376 ASSERT_EQ(-EINVAL, when_acquire_lock(managed_lock));
377 ASSERT_FALSE(is_lock_owner(managed_lock));
378
379 ASSERT_EQ(0, when_shut_down(managed_lock));
380}
381
f67539c2 382TEST_F(TestMockManagedLock, AcquireLockBlocklist) {
7c673cae
FG
383 librbd::ImageCtx *ictx;
384 ASSERT_EQ(0, open_image(m_image_name, &ictx));
385
386 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 387 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
388 ictx->header_oid, mock_image_ctx.image_watcher,
389 librbd::managed_lock::EXCLUSIVE, true, 0);
390 InSequence seq;
391
f67539c2 392 // will abort after seeing blocklist error (avoid infinite request loop)
7c673cae 393 MockAcquireRequest request_lock_acquire;
f67539c2
TL
394 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, request_lock_acquire, -EBLOCKLISTED);
395 ASSERT_EQ(-EBLOCKLISTED, when_acquire_lock(managed_lock));
7c673cae
FG
396 ASSERT_FALSE(is_lock_owner(managed_lock));
397
398 ASSERT_EQ(0, when_shut_down(managed_lock));
399}
400
1e59de90
TL
401TEST_F(TestMockManagedLock, AcquireLockBlocklistedWatch) {
402 librbd::ImageCtx *ictx;
403 ASSERT_EQ(0, open_image(m_image_name, &ictx));
404
405 MockManagedLockImageCtx mock_image_ctx(*ictx);
406 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
407 ictx->header_oid, mock_image_ctx.image_watcher,
408 librbd::managed_lock::EXCLUSIVE, true, 0);
409
410 InSequence seq;
411
412 expect_get_watch_handle(*mock_image_ctx.image_watcher, 0);
413 expect_is_blocklisted(*mock_image_ctx.image_watcher, true);
414
415 ASSERT_EQ(-EBLOCKLISTED, when_acquire_lock(managed_lock));
416 ASSERT_FALSE(is_lock_owner(managed_lock));
417
418 ASSERT_EQ(0, when_shut_down(managed_lock));
419}
420
7c673cae
FG
421TEST_F(TestMockManagedLock, ReleaseLockUnlockedState) {
422 librbd::ImageCtx *ictx;
423 ASSERT_EQ(0, open_image(m_image_name, &ictx));
424
425 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 426 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
427 ictx->header_oid, mock_image_ctx.image_watcher,
428 librbd::managed_lock::EXCLUSIVE, true, 0);
429 InSequence seq;
430
431 ASSERT_EQ(0, when_release_lock(managed_lock));
432
433 ASSERT_EQ(0, when_shut_down(managed_lock));
434}
435
f67539c2 436TEST_F(TestMockManagedLock, ReleaseLockBlocklist) {
91327a77
AA
437 librbd::ImageCtx *ictx;
438 ASSERT_EQ(0, open_image(m_image_name, &ictx));
439
440 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 441 MockMockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
91327a77
AA
442 ictx->header_oid, mock_image_ctx.image_watcher,
443 librbd::managed_lock::EXCLUSIVE, true, 0);
444 InSequence seq;
445
446 MockAcquireRequest try_lock_acquire;
447 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, try_lock_acquire, 0);
448 ASSERT_EQ(0, when_acquire_lock(managed_lock));
449
f67539c2
TL
450 expect_pre_release_lock_handler(managed_lock, false, -EBLOCKLISTED);
451 expect_post_release_lock_handler(managed_lock, false, -EBLOCKLISTED, -EBLOCKLISTED);
452 ASSERT_EQ(-EBLOCKLISTED, when_release_lock(managed_lock));
91327a77
AA
453 ASSERT_FALSE(is_lock_owner(managed_lock));
454
455 ASSERT_EQ(0, when_shut_down(managed_lock));
456}
457
7c673cae
FG
458TEST_F(TestMockManagedLock, ReleaseLockError) {
459 librbd::ImageCtx *ictx;
460 ASSERT_EQ(0, open_image(m_image_name, &ictx));
461
462 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 463 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
464 ictx->header_oid, mock_image_ctx.image_watcher,
465 librbd::managed_lock::EXCLUSIVE, true, 0);
466 InSequence seq;
467
468 MockAcquireRequest try_lock_acquire;
469 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, try_lock_acquire, 0);
470 ASSERT_EQ(0, when_acquire_lock(managed_lock));
471
472 MockReleaseRequest release;
473 expect_release_lock(ictx->op_work_queue, release, -EINVAL);
474
475 ASSERT_EQ(-EINVAL, when_release_lock(managed_lock));
476 ASSERT_TRUE(is_lock_owner(managed_lock));
477
478 MockReleaseRequest shutdown_release;
479 expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
480 ASSERT_EQ(0, when_shut_down(managed_lock));
481 ASSERT_FALSE(is_lock_owner(managed_lock));
482}
483
484TEST_F(TestMockManagedLock, ConcurrentRequests) {
485 librbd::ImageCtx *ictx;
486 ASSERT_EQ(0, open_image(m_image_name, &ictx));
487
488 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 489 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
490 ictx->header_oid, mock_image_ctx.image_watcher,
491 librbd::managed_lock::EXCLUSIVE, true, 0);
492 InSequence seq;
493
494 expect_get_watch_handle(*mock_image_ctx.image_watcher);
495
496 C_SaferCond wait_for_send_ctx1;
497 MockAcquireRequest acquire_error;
498 EXPECT_CALL(acquire_error, send())
499 .WillOnce(Notify(&wait_for_send_ctx1));
500
501 MockAcquireRequest request_acquire;
502 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, request_acquire, 0);
503
504 MockReleaseRequest release;
505 C_SaferCond wait_for_send_ctx2;
506 EXPECT_CALL(release, send())
507 .WillOnce(Notify(&wait_for_send_ctx2));
508
509 C_SaferCond acquire_request_ctx1;
510 managed_lock.acquire_lock(&acquire_request_ctx1);
511
512 C_SaferCond acquire_lock_ctx1;
513 C_SaferCond acquire_lock_ctx2;
514 managed_lock.acquire_lock(&acquire_lock_ctx1);
515 managed_lock.acquire_lock(&acquire_lock_ctx2);
516
517 // fail the try_lock
518 ASSERT_EQ(0, wait_for_send_ctx1.wait());
519 acquire_error.on_finish->complete(-EINVAL);
520 ASSERT_EQ(-EINVAL, acquire_request_ctx1.wait());
521
522 C_SaferCond acquire_lock_ctx3;
523 managed_lock.acquire_lock(&acquire_lock_ctx3);
524
525 C_SaferCond release_lock_ctx1;
526 managed_lock.release_lock(&release_lock_ctx1);
527
528 // all three pending request locks should complete
529 ASSERT_EQ(-EINVAL, acquire_lock_ctx1.wait());
530 ASSERT_EQ(-EINVAL, acquire_lock_ctx2.wait());
531 ASSERT_EQ(0, acquire_lock_ctx3.wait());
532
533 // proceed with the release
534 ASSERT_EQ(0, wait_for_send_ctx2.wait());
535 release.on_finish->complete(0);
536 ASSERT_EQ(0, release_lock_ctx1.wait());
537
538 ASSERT_EQ(0, when_shut_down(managed_lock));
539}
540
541TEST_F(TestMockManagedLock, ReacquireLock) {
542 librbd::ImageCtx *ictx;
543 ASSERT_EQ(0, open_image(m_image_name, &ictx));
544
545 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 546 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
547 ictx->header_oid, mock_image_ctx.image_watcher,
548 librbd::managed_lock::EXCLUSIVE, true, 0);
549 InSequence seq;
550
551 MockAcquireRequest request_lock_acquire;
552 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, request_lock_acquire, 0);
553 ASSERT_EQ(0, when_acquire_lock(managed_lock));
554 ASSERT_TRUE(is_lock_owner(managed_lock));
555
556 MockReacquireRequest mock_reacquire_request;
557 C_SaferCond reacquire_ctx;
91327a77 558 expect_get_watch_handle(*mock_image_ctx.image_watcher, 98765);
7c673cae
FG
559 expect_reacquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, mock_reacquire_request, 0);
560 managed_lock.reacquire_lock(&reacquire_ctx);
561 ASSERT_EQ(0, reacquire_ctx.wait());
562
563 MockReleaseRequest shutdown_release;
564 expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
565 ASSERT_EQ(0, when_shut_down(managed_lock));
566 ASSERT_FALSE(is_lock_owner(managed_lock));
567}
568
f67539c2 569TEST_F(TestMockManagedLock, AttemptReacquireBlocklistedLock) {
91327a77
AA
570 librbd::ImageCtx *ictx;
571 ASSERT_EQ(0, open_image(m_image_name, &ictx));
572
573 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 574 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
91327a77
AA
575 ictx->header_oid, mock_image_ctx.image_watcher,
576 librbd::managed_lock::EXCLUSIVE, true, 0);
577 InSequence seq;
578
579 MockAcquireRequest request_lock_acquire;
580 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue,
581 request_lock_acquire, 0);
582 ASSERT_EQ(0, when_acquire_lock(managed_lock));
583 ASSERT_TRUE(is_lock_owner(managed_lock));
584
585 expect_get_watch_handle(*mock_image_ctx.image_watcher, 0);
586
587 MockReleaseRequest request_release;
588 expect_release_lock(ictx->op_work_queue, request_release, 0);
589
590 expect_get_watch_handle(*mock_image_ctx.image_watcher, 0);
1e59de90 591 expect_is_blocklisted(*mock_image_ctx.image_watcher, false);
91327a77
AA
592
593 managed_lock.reacquire_lock(nullptr);
594
595 ASSERT_EQ(0, when_shut_down(managed_lock));
596 ASSERT_FALSE(is_lock_owner(managed_lock));
597}
598
f67539c2 599TEST_F(TestMockManagedLock, ReacquireBlocklistedLock) {
91327a77
AA
600 librbd::ImageCtx *ictx;
601 ASSERT_EQ(0, open_image(m_image_name, &ictx));
602
603 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 604 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
91327a77
AA
605 ictx->header_oid, mock_image_ctx.image_watcher,
606 librbd::managed_lock::EXCLUSIVE, true, 0);
607 InSequence seq;
608
609 MockAcquireRequest request_lock_acquire;
610 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue,
611 request_lock_acquire, 0);
612 ASSERT_EQ(0, when_acquire_lock(managed_lock));
613 ASSERT_TRUE(is_lock_owner(managed_lock));
614
615 expect_get_watch_handle(*mock_image_ctx.image_watcher, 0);
616
617 MockReleaseRequest request_release;
618 expect_release_lock(ictx->op_work_queue, request_release, 0);
619
620 MockAcquireRequest request_lock_reacquire;
621 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue,
622 request_lock_reacquire, 0);
623 ASSERT_EQ(0, when_acquire_lock(managed_lock));
624 ASSERT_TRUE(is_lock_owner(managed_lock));
625
626 C_SaferCond reacquire_ctx;
627 managed_lock.reacquire_lock(&reacquire_ctx);
628 ASSERT_EQ(0, reacquire_ctx.wait());
629
630 MockReleaseRequest shutdown_release;
631 expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
632 ASSERT_EQ(0, when_shut_down(managed_lock));
633 ASSERT_FALSE(is_lock_owner(managed_lock));
634}
635
7c673cae
FG
636TEST_F(TestMockManagedLock, ReacquireLockError) {
637 librbd::ImageCtx *ictx;
638 ASSERT_EQ(0, open_image(m_image_name, &ictx));
639
640 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 641 MockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
7c673cae
FG
642 ictx->header_oid, mock_image_ctx.image_watcher,
643 librbd::managed_lock::EXCLUSIVE, true, 0);
644 InSequence seq;
645
646 MockAcquireRequest request_lock_acquire;
647 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, request_lock_acquire, 0);
648 ASSERT_EQ(0, when_acquire_lock(managed_lock));
649 ASSERT_TRUE(is_lock_owner(managed_lock));
650
651 MockReacquireRequest mock_reacquire_request;
652 C_SaferCond reacquire_ctx;
91327a77 653 expect_get_watch_handle(*mock_image_ctx.image_watcher, 98765);
7c673cae
FG
654 expect_reacquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, mock_reacquire_request, -EOPNOTSUPP);
655
656 MockReleaseRequest reacquire_lock_release;
657 expect_release_lock(ictx->op_work_queue, reacquire_lock_release, 0);
658
659 MockAcquireRequest reacquire_lock_acquire;
660 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, reacquire_lock_acquire, 0);
661
662 managed_lock.reacquire_lock(&reacquire_ctx);
91327a77 663 ASSERT_EQ(0, reacquire_ctx.wait());
7c673cae
FG
664
665 MockReleaseRequest shutdown_release;
666 expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
667 ASSERT_EQ(0, when_shut_down(managed_lock));
668 ASSERT_FALSE(is_lock_owner(managed_lock));
669}
670
91327a77
AA
671TEST_F(TestMockManagedLock, ReacquireWithSameCookie) {
672 librbd::ImageCtx *ictx;
673 ASSERT_EQ(0, open_image(m_image_name, &ictx));
674
675 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 676 MockMockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
91327a77
AA
677 ictx->header_oid, mock_image_ctx.image_watcher,
678 librbd::managed_lock::EXCLUSIVE, true, 0);
679 InSequence seq;
680
681 MockAcquireRequest request_lock_acquire;
11fdf7f2 682 expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, request_lock_acquire, 0);
91327a77
AA
683 ASSERT_EQ(0, when_acquire_lock(managed_lock));
684 ASSERT_TRUE(is_lock_owner(managed_lock));
685
686 // watcher with same cookie after rewatch
687 uint64_t client_id = 0;
688 C_SaferCond reacquire_ctx;
11fdf7f2 689 expect_post_reacquired_lock_handler(*mock_image_ctx.image_watcher, managed_lock, client_id);
91327a77
AA
690 managed_lock.reacquire_lock(&reacquire_ctx);
691 ASSERT_LT(0U, client_id);
692 ASSERT_TRUE(is_lock_owner(managed_lock));
693
694 MockReleaseRequest shutdown_release;
695 expect_pre_release_lock_handler(managed_lock, true, 0);
696 expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
697 expect_post_release_lock_handler(managed_lock, true, 0, 0);
698 ASSERT_EQ(0, when_shut_down(managed_lock));
699}
700
701TEST_F(TestMockManagedLock, ShutDownWhileWaiting) {
702 librbd::ImageCtx *ictx;
703 ASSERT_EQ(0, open_image(m_image_name, &ictx));
704
705 MockManagedLockImageCtx mock_image_ctx(*ictx);
f67539c2 706 MockMockManagedLock managed_lock(ictx->md_ctx, *ictx->asio_engine,
91327a77
AA
707 ictx->header_oid, mock_image_ctx.image_watcher,
708 librbd::managed_lock::EXCLUSIVE, true, 0);
709
710 InSequence seq;
711
712 expect_get_watch_handle(*mock_image_ctx.image_watcher, 0);
1e59de90 713 expect_is_blocklisted(*mock_image_ctx.image_watcher, false);
91327a77
AA
714
715 C_SaferCond acquire_ctx;
716 managed_lock.acquire_lock(&acquire_ctx);
717
718 ASSERT_EQ(0, when_shut_down(managed_lock));
1e59de90 719 ASSERT_EQ(-ERESTART, acquire_ctx.wait());
91327a77
AA
720 ASSERT_FALSE(is_lock_owner(managed_lock));
721}
722
7c673cae 723} // namespace librbd