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