]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/test/librbd/test_mock_ManagedLock.cc
update sources to 12.2.10
[ceph.git] / ceph / src / test / librbd / test_mock_ManagedLock.cc
index a808523fc204ba3f49d619598a134d60374c1c9f..a1e955a6a658ed7e4b9a6d8694fe9e6a53c4134e 100644 (file)
@@ -26,6 +26,22 @@ struct Traits<MockManagedLockImageCtx> {
 };
 }
 
+struct MockMockManagedLock : public ManagedLock<MockManagedLockImageCtx> {
+  MockMockManagedLock(librados::IoCtx& ioctx, ContextWQ *work_queue,
+                 const std::string& oid, librbd::MockImageWatcher *watcher,
+                 managed_lock::Mode  mode, bool blacklist_on_break_lock,
+                 uint32_t blacklist_expire_seconds)
+    : ManagedLock<MockManagedLockImageCtx>(ioctx, work_queue, oid, watcher,
+      librbd::managed_lock::EXCLUSIVE, true, 0) {
+  };
+  virtual ~MockMockManagedLock() = default;
+
+  MOCK_METHOD2(post_reacquire_lock_handler, void(int, Context*));
+
+  MOCK_METHOD2(pre_release_lock_handler, void(bool, Context*));
+  MOCK_METHOD3(post_release_lock_handler, void(bool, int, Context*));
+};
+
 namespace managed_lock {
 
 template<typename T>
@@ -146,6 +162,7 @@ using ::testing::DoAll;
 using ::testing::Invoke;
 using ::testing::InSequence;
 using ::testing::Return;
+using ::testing::WithArg;
 
 class TestMockManagedLock : public TestMockFixture {
 public:
@@ -178,7 +195,6 @@ public:
                              ContextWQ *work_queue,
                              MockReacquireRequest &mock_reacquire_request,
                              int r) {
-    expect_get_watch_handle(watcher, 98765);
     EXPECT_CALL(mock_reacquire_request, send())
                   .WillOnce(QueueRequest(&mock_reacquire_request, r, work_queue));
   }
@@ -188,6 +204,35 @@ public:
                   .WillOnce(CompleteContext(0, (ContextWQ *)nullptr));
   }
 
+  void expect_post_reacquired_lock_handler(MockImageWatcher& watcher,
+                        MockMockManagedLock &managed_lock,
+                        uint64_t &client_id) {
+    expect_get_watch_handle(watcher);
+    EXPECT_CALL(managed_lock, post_reacquire_lock_handler(_, _))
+      .WillOnce(Invoke([&watcher, &client_id](int r, Context *on_finish){
+        if (r >= 0) {
+          client_id = 98765;
+        }
+        on_finish->complete(r);}));
+  }
+
+  void expect_pre_release_lock_handler(MockMockManagedLock &managed_lock,
+                                       bool shutting_down, int r) {
+    EXPECT_CALL(managed_lock, pre_release_lock_handler(shutting_down, _))
+      .WillOnce(WithArg<1>(Invoke([r](Context *on_finish){
+                             on_finish->complete(r);
+                           })));
+  }
+
+  void expect_post_release_lock_handler(MockMockManagedLock &managed_lock,
+                                        bool shutting_down, int expect_r,
+                                        int r) {
+    EXPECT_CALL(managed_lock, post_release_lock_handler(shutting_down, expect_r, _))
+      .WillOnce(WithArg<2>(Invoke([r](Context *on_finish){
+                             on_finish->complete(r);
+                           })));
+  }
+
   int when_acquire_lock(MockManagedLock &managed_lock) {
     C_SaferCond ctx;
     {
@@ -355,6 +400,28 @@ TEST_F(TestMockManagedLock, ReleaseLockUnlockedState) {
   ASSERT_EQ(0, when_shut_down(managed_lock));
 }
 
+TEST_F(TestMockManagedLock, ReleaseLockBlacklist) {
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockManagedLockImageCtx mock_image_ctx(*ictx);
+  MockMockManagedLock managed_lock(ictx->md_ctx, ictx->op_work_queue,
+                                   ictx->header_oid, mock_image_ctx.image_watcher,
+                                   librbd::managed_lock::EXCLUSIVE, true, 0);
+  InSequence seq;
+
+  MockAcquireRequest try_lock_acquire;
+  expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, try_lock_acquire, 0);
+  ASSERT_EQ(0, when_acquire_lock(managed_lock));
+
+  expect_pre_release_lock_handler(managed_lock, false, -EBLACKLISTED);
+  expect_post_release_lock_handler(managed_lock, false, -EBLACKLISTED, -EBLACKLISTED);
+  ASSERT_EQ(-EBLACKLISTED, when_release_lock(managed_lock));
+  ASSERT_FALSE(is_lock_owner(managed_lock));
+
+  ASSERT_EQ(0, when_shut_down(managed_lock));
+}
+
 TEST_F(TestMockManagedLock, ReleaseLockError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
@@ -455,6 +522,7 @@ TEST_F(TestMockManagedLock, ReacquireLock) {
 
   MockReacquireRequest mock_reacquire_request;
   C_SaferCond reacquire_ctx;
+  expect_get_watch_handle(*mock_image_ctx.image_watcher, 98765);
   expect_reacquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, mock_reacquire_request, 0);
   managed_lock.reacquire_lock(&reacquire_ctx);
   ASSERT_EQ(0, reacquire_ctx.wait());
@@ -465,6 +533,72 @@ TEST_F(TestMockManagedLock, ReacquireLock) {
   ASSERT_FALSE(is_lock_owner(managed_lock));
 }
 
+TEST_F(TestMockManagedLock, AttemptReacquireBlacklistedLock) {
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockManagedLockImageCtx mock_image_ctx(*ictx);
+  MockManagedLock managed_lock(ictx->md_ctx, ictx->op_work_queue,
+                               ictx->header_oid, mock_image_ctx.image_watcher,
+                               librbd::managed_lock::EXCLUSIVE, true, 0);
+  InSequence seq;
+
+  MockAcquireRequest request_lock_acquire;
+  expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue,
+                      request_lock_acquire, 0);
+  ASSERT_EQ(0, when_acquire_lock(managed_lock));
+  ASSERT_TRUE(is_lock_owner(managed_lock));
+
+  expect_get_watch_handle(*mock_image_ctx.image_watcher, 0);
+
+  MockReleaseRequest request_release;
+  expect_release_lock(ictx->op_work_queue, request_release, 0);
+
+  expect_get_watch_handle(*mock_image_ctx.image_watcher, 0);
+
+  managed_lock.reacquire_lock(nullptr);
+
+  ASSERT_EQ(0, when_shut_down(managed_lock));
+  ASSERT_FALSE(is_lock_owner(managed_lock));
+}
+
+TEST_F(TestMockManagedLock, ReacquireBlacklistedLock) {
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockManagedLockImageCtx mock_image_ctx(*ictx);
+  MockManagedLock managed_lock(ictx->md_ctx, ictx->op_work_queue,
+                               ictx->header_oid, mock_image_ctx.image_watcher,
+                               librbd::managed_lock::EXCLUSIVE, true, 0);
+  InSequence seq;
+
+  MockAcquireRequest request_lock_acquire;
+  expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue,
+                      request_lock_acquire, 0);
+  ASSERT_EQ(0, when_acquire_lock(managed_lock));
+  ASSERT_TRUE(is_lock_owner(managed_lock));
+
+  expect_get_watch_handle(*mock_image_ctx.image_watcher, 0);
+
+  MockReleaseRequest request_release;
+  expect_release_lock(ictx->op_work_queue, request_release, 0);
+
+  MockAcquireRequest request_lock_reacquire;
+  expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue,
+                      request_lock_reacquire, 0);
+  ASSERT_EQ(0, when_acquire_lock(managed_lock));
+  ASSERT_TRUE(is_lock_owner(managed_lock));
+
+  C_SaferCond reacquire_ctx;
+  managed_lock.reacquire_lock(&reacquire_ctx);
+  ASSERT_EQ(0, reacquire_ctx.wait());
+
+  MockReleaseRequest shutdown_release;
+  expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
+  ASSERT_EQ(0, when_shut_down(managed_lock));
+  ASSERT_FALSE(is_lock_owner(managed_lock));
+}
+
 TEST_F(TestMockManagedLock, ReacquireLockError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
@@ -482,6 +616,7 @@ TEST_F(TestMockManagedLock, ReacquireLockError) {
 
   MockReacquireRequest mock_reacquire_request;
   C_SaferCond reacquire_ctx;
+  expect_get_watch_handle(*mock_image_ctx.image_watcher, 98765);
   expect_reacquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, mock_reacquire_request, -EOPNOTSUPP);
 
   MockReleaseRequest reacquire_lock_release;
@@ -491,7 +626,7 @@ TEST_F(TestMockManagedLock, ReacquireLockError) {
   expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, reacquire_lock_acquire, 0);
 
   managed_lock.reacquire_lock(&reacquire_ctx);
-  ASSERT_EQ(-EOPNOTSUPP, reacquire_ctx.wait());
+  ASSERT_EQ(0, reacquire_ctx.wait());
 
   MockReleaseRequest shutdown_release;
   expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
@@ -499,4 +634,57 @@ TEST_F(TestMockManagedLock, ReacquireLockError) {
   ASSERT_FALSE(is_lock_owner(managed_lock));
 }
 
+TEST_F(TestMockManagedLock, ReacquireWithSameCookie) {
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockManagedLockImageCtx mock_image_ctx(*ictx);
+  MockMockManagedLock managed_lock(ictx->md_ctx, ictx->op_work_queue,
+                               ictx->header_oid, mock_image_ctx.image_watcher,
+                               librbd::managed_lock::EXCLUSIVE, true, 0);
+  InSequence seq;
+
+  MockAcquireRequest request_lock_acquire;
+  expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue,
+                      request_lock_acquire, 0);
+  ASSERT_EQ(0, when_acquire_lock(managed_lock));
+  ASSERT_TRUE(is_lock_owner(managed_lock));
+
+  // watcher with same cookie after rewatch
+  uint64_t client_id = 0;
+  C_SaferCond reacquire_ctx;
+  expect_post_reacquired_lock_handler(*mock_image_ctx.image_watcher,
+                                      managed_lock, client_id);
+  managed_lock.reacquire_lock(&reacquire_ctx);
+  ASSERT_LT(0U, client_id);
+  ASSERT_TRUE(is_lock_owner(managed_lock));
+
+  MockReleaseRequest shutdown_release;
+  expect_pre_release_lock_handler(managed_lock, true, 0);
+  expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
+  expect_post_release_lock_handler(managed_lock, true, 0, 0);
+  ASSERT_EQ(0, when_shut_down(managed_lock));
+}
+
+TEST_F(TestMockManagedLock, ShutDownWhileWaiting) {
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockManagedLockImageCtx mock_image_ctx(*ictx);
+  MockMockManagedLock managed_lock(ictx->md_ctx, ictx->op_work_queue,
+                               ictx->header_oid, mock_image_ctx.image_watcher,
+                               librbd::managed_lock::EXCLUSIVE, true, 0);
+
+  InSequence seq;
+
+  expect_get_watch_handle(*mock_image_ctx.image_watcher, 0);
+
+  C_SaferCond acquire_ctx;
+  managed_lock.acquire_lock(&acquire_ctx);
+
+  ASSERT_EQ(0, when_shut_down(managed_lock));
+  ASSERT_EQ(-ESHUTDOWN, acquire_ctx.wait());
+  ASSERT_FALSE(is_lock_owner(managed_lock));
+}
+
 } // namespace librbd