]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/test/rbd_mirror/test_mock_InstanceWatcher.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / test / rbd_mirror / test_mock_InstanceWatcher.cc
index 075134d9912e49134999f8f8ba8421dbae3fa459..8e9b79e8d566ba23f1b37e2d3ce31741183307c2 100644 (file)
@@ -9,7 +9,6 @@
 #include "test/librbd/mock/MockImageCtx.h"
 #include "test/rbd_mirror/test_mock_fixture.h"
 #include "tools/rbd_mirror/InstanceReplayer.h"
-#include "tools/rbd_mirror/ImageSyncThrottler.h"
 #include "tools/rbd_mirror/InstanceWatcher.h"
 #include "tools/rbd_mirror/Threads.h"
 
@@ -64,7 +63,7 @@ namespace mirror {
 
 template <>
 struct Threads<librbd::MockTestImageCtx> {
-  Mutex &timer_lock;
+  ceph::mutex &timer_lock;
   SafeTimer *timer;
   ContextWQ *work_queue;
 
@@ -84,31 +83,26 @@ struct InstanceReplayer<librbd::MockTestImageCtx> {
 };
 
 template <>
-struct ImageSyncThrottler<librbd::MockTestImageCtx> {
-  static ImageSyncThrottler* s_instance;
+struct Throttler<librbd::MockTestImageCtx> {
+  static Throttler* s_instance;
 
-  static ImageSyncThrottler *create(CephContext *cct) {
-    ceph_assert(s_instance != nullptr);
-    return s_instance;
-  }
-
-  ImageSyncThrottler() {
+  Throttler() {
     ceph_assert(s_instance == nullptr);
     s_instance = this;
   }
 
-  virtual ~ImageSyncThrottler() {
+  virtual ~Throttler() {
     ceph_assert(s_instance == this);
     s_instance = nullptr;
   }
 
-  MOCK_METHOD0(destroy, void());
-  MOCK_METHOD1(drain, void(int));
-  MOCK_METHOD2(start_op, void(const std::string &, Context *));
-  MOCK_METHOD1(finish_op, void(const std::string &));
+  MOCK_METHOD3(start_op, void(const std::string &, const std::string &,
+                              Context *));
+  MOCK_METHOD2(finish_op, void(const std::string &, const std::string &));
+  MOCK_METHOD2(drain, void(const std::string &, int));
 };
 
-ImageSyncThrottler<librbd::MockTestImageCtx>* ImageSyncThrottler<librbd::MockTestImageCtx>::s_instance = nullptr;
+Throttler<librbd::MockTestImageCtx>* Throttler<librbd::MockTestImageCtx>::s_instance = nullptr;
 
 } // namespace mirror
 } // namespace rbd
@@ -224,7 +218,8 @@ TEST_F(TestMockInstanceWatcher, InitShutdown) {
   librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_local_io_ctx));
 
   auto instance_watcher = new MockInstanceWatcher(
-    m_local_io_ctx, m_mock_threads->work_queue, nullptr, m_instance_id);
+      m_local_io_ctx, m_mock_threads->work_queue, nullptr, nullptr,
+      m_instance_id);
   InSequence seq;
 
   // Init
@@ -248,7 +243,8 @@ TEST_F(TestMockInstanceWatcher, InitError) {
   librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_local_io_ctx));
 
   auto instance_watcher = new MockInstanceWatcher(
-    m_local_io_ctx, m_mock_threads->work_queue, nullptr, m_instance_id);
+      m_local_io_ctx, m_mock_threads->work_queue, nullptr, nullptr,
+      m_instance_id);
   InSequence seq;
 
   expect_register_instance(mock_io_ctx, 0);
@@ -268,7 +264,8 @@ TEST_F(TestMockInstanceWatcher, ShutdownError) {
   librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_local_io_ctx));
 
   auto instance_watcher = new MockInstanceWatcher(
-    m_local_io_ctx, m_mock_threads->work_queue, nullptr, m_instance_id);
+      m_local_io_ctx, m_mock_threads->work_queue, nullptr, nullptr,
+      m_instance_id);
   InSequence seq;
 
   // Init
@@ -337,7 +334,7 @@ TEST_F(TestMockInstanceWatcher, ImageAcquireRelease) {
   librados::MockTestMemIoCtxImpl &mock_io_ctx1(get_mock_io_ctx(io_ctx1));
   MockInstanceReplayer mock_instance_replayer1;
   auto instance_watcher1 = MockInstanceWatcher::create(
-      io_ctx1, m_mock_threads->work_queue, &mock_instance_replayer1);
+      io_ctx1, m_mock_threads->work_queue, &mock_instance_replayer1, nullptr);
 
   librados::Rados cluster;
   librados::IoCtx io_ctx2;
@@ -347,7 +344,7 @@ TEST_F(TestMockInstanceWatcher, ImageAcquireRelease) {
   librados::MockTestMemIoCtxImpl &mock_io_ctx2(get_mock_io_ctx(io_ctx2));
   MockInstanceReplayer mock_instance_replayer2;
   auto instance_watcher2 = MockInstanceWatcher::create(
-    io_ctx2, m_mock_threads->work_queue, &mock_instance_replayer2);
+    io_ctx2, m_mock_threads->work_queue, &mock_instance_replayer2, nullptr);
 
   InSequence seq;
 
@@ -420,7 +417,7 @@ TEST_F(TestMockInstanceWatcher, PeerImageRemoved) {
   librados::MockTestMemIoCtxImpl &mock_io_ctx1(get_mock_io_ctx(io_ctx1));
   MockInstanceReplayer mock_instance_replayer1;
   auto instance_watcher1 = MockInstanceWatcher::create(
-      io_ctx1, m_mock_threads->work_queue, &mock_instance_replayer1);
+      io_ctx1, m_mock_threads->work_queue, &mock_instance_replayer1, nullptr);
 
   librados::Rados cluster;
   librados::IoCtx io_ctx2;
@@ -430,7 +427,7 @@ TEST_F(TestMockInstanceWatcher, PeerImageRemoved) {
   librados::MockTestMemIoCtxImpl &mock_io_ctx2(get_mock_io_ctx(io_ctx2));
   MockInstanceReplayer mock_instance_replayer2;
   auto instance_watcher2 = MockInstanceWatcher::create(
-    io_ctx2, m_mock_threads->work_queue, &mock_instance_replayer2);
+    io_ctx2, m_mock_threads->work_queue, &mock_instance_replayer2, nullptr);
 
   InSequence seq;
 
@@ -486,7 +483,8 @@ TEST_F(TestMockInstanceWatcher, ImageAcquireReleaseCancel) {
   librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_local_io_ctx));
 
   auto instance_watcher = new MockInstanceWatcher(
-    m_local_io_ctx, m_mock_threads->work_queue, nullptr, m_instance_id);
+      m_local_io_ctx, m_mock_threads->work_queue, nullptr, nullptr,
+      m_instance_id);
   InSequence seq;
 
   // Init
@@ -502,7 +500,7 @@ TEST_F(TestMockInstanceWatcher, ImageAcquireReleaseCancel) {
                     const std::string& o, librados::AioCompletionImpl *c,
                     bufferlist& bl, uint64_t timeout_ms, bufferlist *pbl) {
                     c->get();
-                    auto ctx = new FunctionContext(
+                    auto ctx = new LambdaContext(
                       [instance_watcher, &mock_io_ctx, c, pbl](int r) {
                         instance_watcher->cancel_notify_requests("other");
                         encode(librbd::watcher::NotifyResponse(), *pbl);
@@ -523,7 +521,7 @@ TEST_F(TestMockInstanceWatcher, ImageAcquireReleaseCancel) {
                     const std::string& o, librados::AioCompletionImpl *c,
                     bufferlist& bl, uint64_t timeout_ms, bufferlist *pbl) {
                     c->get();
-                    auto ctx = new FunctionContext(
+                    auto ctx = new LambdaContext(
                       [instance_watcher, &mock_io_ctx, c, pbl](int r) {
                         instance_watcher->cancel_notify_requests("other");
                         encode(librbd::watcher::NotifyResponse(), *pbl);
@@ -553,8 +551,8 @@ TEST_F(TestMockInstanceWatcher, PeerImageAcquireWatchDNE) {
 
   MockInstanceReplayer mock_instance_replayer;
   auto instance_watcher = new MockInstanceWatcher(
-    m_local_io_ctx, m_mock_threads->work_queue, &mock_instance_replayer,
-    m_instance_id);
+      m_local_io_ctx, m_mock_threads->work_queue, &mock_instance_replayer,
+      nullptr, m_instance_id);
   InSequence seq;
 
   // Init
@@ -585,8 +583,8 @@ TEST_F(TestMockInstanceWatcher, PeerImageReleaseWatchDNE) {
 
   MockInstanceReplayer mock_instance_replayer;
   auto instance_watcher = new MockInstanceWatcher(
-    m_local_io_ctx, m_mock_threads->work_queue, &mock_instance_replayer,
-    m_instance_id);
+      m_local_io_ctx, m_mock_threads->work_queue, &mock_instance_replayer,
+      nullptr, m_instance_id);
   InSequence seq;
 
   // Init
@@ -616,7 +614,8 @@ TEST_F(TestMockInstanceWatcher, PeerImageRemovedCancel) {
   librados::MockTestMemIoCtxImpl &mock_io_ctx(get_mock_io_ctx(m_local_io_ctx));
 
   auto instance_watcher = new MockInstanceWatcher(
-    m_local_io_ctx, m_mock_threads->work_queue, nullptr, m_instance_id);
+      m_local_io_ctx, m_mock_threads->work_queue, nullptr, nullptr,
+      m_instance_id);
   InSequence seq;
 
   // Init
@@ -632,7 +631,7 @@ TEST_F(TestMockInstanceWatcher, PeerImageRemovedCancel) {
                     const std::string& o, librados::AioCompletionImpl *c,
                     bufferlist& bl, uint64_t timeout_ms, bufferlist *pbl) {
                     c->get();
-                    auto ctx = new FunctionContext(
+                    auto ctx = new LambdaContext(
                       [instance_watcher, &mock_io_ctx, c, pbl](int r) {
                         instance_watcher->cancel_notify_requests("other");
                         encode(librbd::watcher::NotifyResponse(), *pbl);
@@ -659,10 +658,10 @@ TEST_F(TestMockInstanceWatcher, PeerImageRemovedCancel) {
 
 class TestMockInstanceWatcher_NotifySync : public TestMockInstanceWatcher {
 public:
-  typedef ImageSyncThrottler<librbd::MockTestImageCtx> MockImageSyncThrottler;
+  typedef Throttler<librbd::MockTestImageCtx> MockThrottler;
 
   MockManagedLock mock_managed_lock;
-  MockImageSyncThrottler mock_image_sync_throttler;
+  MockThrottler mock_image_sync_throttler;
   std::string instance_id1;
   std::string instance_id2;
 
@@ -680,14 +679,16 @@ public:
     librados::MockTestMemIoCtxImpl &mock_io_ctx1(get_mock_io_ctx(io_ctx1));
     instance_watcher1 = MockInstanceWatcher::create(io_ctx1,
                                                     m_mock_threads->work_queue,
-                                                    nullptr);
+                                                    nullptr,
+                                                    &mock_image_sync_throttler);
     EXPECT_EQ("", connect_cluster_pp(cluster));
     EXPECT_EQ(0, cluster.ioctx_create(_local_pool_name.c_str(), io_ctx2));
     instance_id2 = stringify(io_ctx2.get_instance_id());
     librados::MockTestMemIoCtxImpl &mock_io_ctx2(get_mock_io_ctx(io_ctx2));
     instance_watcher2 = MockInstanceWatcher::create(io_ctx2,
                                                     m_mock_threads->work_queue,
-                                                    nullptr);
+                                                    nullptr,
+                                                    &mock_image_sync_throttler);
     InSequence seq;
 
     // Init instance watcher 1 (leader)
@@ -712,7 +713,7 @@ public:
 
     InSequence seq;
 
-    expect_throttler_destroy();
+    expect_throttler_drain();
     instance_watcher1->handle_release_leader();
 
     // Shutdown instance watcher 1
@@ -736,24 +737,12 @@ public:
     TestMockInstanceWatcher::TearDown();
   }
 
-  void expect_throttler_destroy(
-      std::vector<Context *> *throttler_queue = nullptr) {
-    EXPECT_CALL(mock_image_sync_throttler, drain(-ESTALE))
-        .WillOnce(Invoke([throttler_queue] (int r) {
-              if (throttler_queue != nullptr) {
-                for (auto ctx : *throttler_queue) {
-                  ctx->complete(r);
-                }
-              }
-            }));
-    EXPECT_CALL(mock_image_sync_throttler, destroy());
-  }
-
   void expect_throttler_start_op(const std::string &sync_id,
                                  Context *on_call = nullptr,
                                  Context **on_start_ctx = nullptr) {
-    EXPECT_CALL(mock_image_sync_throttler, start_op(sync_id, _))
+    EXPECT_CALL(mock_image_sync_throttler, start_op("", sync_id, _))
         .WillOnce(Invoke([on_call, on_start_ctx] (const std::string &,
+                                                  const std::string &,
                                                   Context *ctx) {
                            if (on_start_ctx != nullptr) {
                              *on_start_ctx = ctx;
@@ -768,11 +757,15 @@ public:
 
   void expect_throttler_finish_op(const std::string &sync_id,
                                   Context *on_finish) {
-    EXPECT_CALL(mock_image_sync_throttler, finish_op("sync_id"))
-        .WillOnce(Invoke([on_finish](const std::string &) {
+    EXPECT_CALL(mock_image_sync_throttler, finish_op("", "sync_id"))
+        .WillOnce(Invoke([on_finish](const std::string &, const std::string &) {
               on_finish->complete(0);
             }));
   }
+
+  void expect_throttler_drain() {
+    EXPECT_CALL(mock_image_sync_throttler, drain("", -ESTALE));
+  }
 };
 
 TEST_F(TestMockInstanceWatcher_NotifySync, StartStopOnLeader) {
@@ -863,8 +856,9 @@ TEST_F(TestMockInstanceWatcher_NotifySync, InFlightPrevNotification) {
   ASSERT_EQ(0, on_start1.wait());
 
   C_SaferCond on_start2;
-  EXPECT_CALL(mock_image_sync_throttler, finish_op("sync_id"))
-      .WillOnce(Invoke([this, &on_start2](const std::string &) {
+  EXPECT_CALL(mock_image_sync_throttler, finish_op("", "sync_id"))
+      .WillOnce(Invoke([this, &on_start2](const std::string &,
+                                          const std::string &) {
             instance_watcher2->notify_sync_request("sync_id", &on_start2);
           }));
   expect_throttler_start_op("sync_id");
@@ -880,7 +874,7 @@ TEST_F(TestMockInstanceWatcher_NotifySync, InFlightPrevNotification) {
 TEST_F(TestMockInstanceWatcher_NotifySync, NoInFlightReleaseAcquireLeader) {
   InSequence seq;
 
-  expect_throttler_destroy();
+  expect_throttler_drain();
   instance_watcher1->handle_release_leader();
   instance_watcher1->handle_acquire_leader();
 }
@@ -888,7 +882,7 @@ TEST_F(TestMockInstanceWatcher_NotifySync, NoInFlightReleaseAcquireLeader) {
 TEST_F(TestMockInstanceWatcher_NotifySync, StartedOnLeaderReleaseLeader) {
   InSequence seq;
 
-  expect_throttler_destroy();
+  expect_throttler_drain();
   instance_watcher1->handle_release_leader();
   instance_watcher2->handle_acquire_leader();
 
@@ -896,7 +890,7 @@ TEST_F(TestMockInstanceWatcher_NotifySync, StartedOnLeaderReleaseLeader) {
   C_SaferCond on_start;
   instance_watcher2->notify_sync_request("sync_id", &on_start);
   ASSERT_EQ(0, on_start.wait());
-  expect_throttler_destroy();
+  expect_throttler_drain();
   instance_watcher2->handle_release_leader();
   instance_watcher2->notify_sync_complete("sync_id");
 
@@ -913,9 +907,11 @@ TEST_F(TestMockInstanceWatcher_NotifySync, WaitingOnLeaderReleaseLeader) {
   instance_watcher1->notify_sync_request("sync_id", &on_start);
   ASSERT_EQ(0, on_start_op_called.wait());
 
-  std::vector<Context *> throttler_queue = {on_start_ctx};
-  expect_throttler_destroy(&throttler_queue);
+  expect_throttler_drain();
   instance_watcher1->handle_release_leader();
+  // emulate throttler queue drain on leader release
+  on_start_ctx->complete(-ESTALE);
+
   expect_throttler_start_op("sync_id");
   instance_watcher2->handle_acquire_leader();
   instance_watcher1->handle_update_leader(instance_id2);
@@ -926,7 +922,7 @@ TEST_F(TestMockInstanceWatcher_NotifySync, WaitingOnLeaderReleaseLeader) {
   instance_watcher1->notify_sync_complete("sync_id");
   ASSERT_EQ(0, on_finish.wait());
 
-  expect_throttler_destroy();
+  expect_throttler_drain();
   instance_watcher2->handle_release_leader();
   instance_watcher1->handle_acquire_leader();
 }
@@ -934,7 +930,7 @@ TEST_F(TestMockInstanceWatcher_NotifySync, WaitingOnLeaderReleaseLeader) {
 TEST_F(TestMockInstanceWatcher_NotifySync, StartedOnNonLeaderAcquireLeader) {
   InSequence seq;
 
-  expect_throttler_destroy();
+  expect_throttler_drain();
   instance_watcher1->handle_release_leader();
   instance_watcher2->handle_acquire_leader();
   instance_watcher1->handle_update_leader(instance_id2);
@@ -944,7 +940,7 @@ TEST_F(TestMockInstanceWatcher_NotifySync, StartedOnNonLeaderAcquireLeader) {
   instance_watcher1->notify_sync_request("sync_id", &on_start);
   ASSERT_EQ(0, on_start.wait());
 
-  expect_throttler_destroy();
+  expect_throttler_drain();
   instance_watcher2->handle_release_leader();
   instance_watcher1->handle_acquire_leader();
   instance_watcher2->handle_update_leader(instance_id1);
@@ -963,12 +959,13 @@ TEST_F(TestMockInstanceWatcher_NotifySync, WaitingOnNonLeaderAcquireLeader) {
   instance_watcher2->notify_sync_request("sync_id", &on_start);
   ASSERT_EQ(0, on_start_op_called.wait());
 
-  std::vector<Context *> throttler_queue = {on_start_ctx};
-  expect_throttler_destroy(&throttler_queue);
+  expect_throttler_drain();
   instance_watcher1->handle_release_leader();
+  // emulate throttler queue drain on leader release
+  on_start_ctx->complete(-ESTALE);
 
-  EXPECT_CALL(mock_image_sync_throttler, start_op("sync_id", _))
-      .WillOnce(WithArg<1>(CompleteContext(0)));
+  EXPECT_CALL(mock_image_sync_throttler, start_op("", "sync_id", _))
+      .WillOnce(WithArg<2>(CompleteContext(0)));
   instance_watcher2->handle_acquire_leader();
   instance_watcher1->handle_update_leader(instance_id2);
 
@@ -979,7 +976,7 @@ TEST_F(TestMockInstanceWatcher_NotifySync, WaitingOnNonLeaderAcquireLeader) {
   instance_watcher2->notify_sync_complete("sync_id");
   ASSERT_EQ(0, on_finish.wait());
 
-  expect_throttler_destroy();
+  expect_throttler_drain();
   instance_watcher2->handle_release_leader();
   instance_watcher1->handle_acquire_leader();
 }