]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/test/librbd/mirror/snapshot/test_mock_CreateNonPrimaryRequest.cc
import 15.2.2 octopus source
[ceph.git] / ceph / src / test / librbd / mirror / snapshot / test_mock_CreateNonPrimaryRequest.cc
index 25a85ce53193aade6ed1a90d11bfc939fbd59a2a..a92be03304ff5e943bd8b54281bfabdd86fdd1e4 100644 (file)
@@ -102,6 +102,14 @@ public:
   typedef WriteImageStateRequest<MockTestImageCtx> MockWriteImageStateRequest;
   typedef util::Mock MockUtils;
 
+  void expect_clone_md_ctx(MockTestImageCtx &mock_image_ctx) {
+    EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), clone())
+      .WillOnce(Invoke([&mock_image_ctx]() {
+                         get_mock_io_ctx(mock_image_ctx.md_ctx).get();
+                         return &get_mock_io_ctx(mock_image_ctx.md_ctx);
+                       }));
+  }
+
   void expect_refresh_image(MockTestImageCtx &mock_image_ctx,
                             bool refresh_required, int r) {
     EXPECT_CALL(*mock_image_ctx.state, is_refresh_required())
@@ -132,6 +140,20 @@ public:
       .WillOnce(Return(result));
   }
 
+  void expect_get_mirror_peers(MockTestImageCtx &mock_image_ctx,
+                               const std::vector<cls::rbd::MirrorPeer> &peers,
+                               int r) {
+    using ceph::encode;
+    bufferlist bl;
+    encode(peers, bl);
+
+    EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
+                exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_peer_list"),
+                     _, _, _))
+      .WillOnce(DoAll(WithArg<5>(CopyInBufferlist(bl)),
+                      Return(r)));
+  }
+
   void expect_create_snapshot(MockTestImageCtx &mock_image_ctx, int r) {
     EXPECT_CALL(*mock_image_ctx.operations, snap_create(_, _, _))
       .WillOnce(WithArg<2>(CompleteContext(
@@ -179,6 +201,38 @@ TEST_F(TestMockMirrorSnapshotCreateNonPrimaryRequest, Success) {
   ASSERT_EQ(0, ctx.wait());
 }
 
+TEST_F(TestMockMirrorSnapshotCreateNonPrimaryRequest, SuccessDemoted) {
+  REQUIRE_FORMAT_V2();
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockTestImageCtx mock_image_ctx(*ictx);
+
+  InSequence seq;
+
+  expect_clone_md_ctx(mock_image_ctx);
+  expect_refresh_image(mock_image_ctx, true, 0);
+  expect_get_mirror_image(
+    mock_image_ctx, {cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT, "gid",
+                     cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, 0);
+  MockUtils mock_utils;
+  expect_can_create_non_primary_snapshot(mock_utils, true);
+  expect_get_mirror_peers(mock_image_ctx,
+                          {{"uuid", cls::rbd::MIRROR_PEER_DIRECTION_TX, "ceph",
+                            "mirror", "mirror uuid"}}, 0);
+  expect_create_snapshot(mock_image_ctx, 0);
+  MockWriteImageStateRequest mock_write_image_state_request;
+  expect_write_image_state(mock_image_ctx, mock_write_image_state_request, 0);
+
+  C_SaferCond ctx;
+  auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, true,
+                                             "mirror_uuid", 123, {{1, 2}}, {},
+                                             nullptr, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+}
+
 TEST_F(TestMockMirrorSnapshotCreateNonPrimaryRequest, RefreshError) {
   REQUIRE_FORMAT_V2();
 
@@ -247,6 +301,33 @@ TEST_F(TestMockMirrorSnapshotCreateNonPrimaryRequest, CanNotError) {
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
 
+TEST_F(TestMockMirrorSnapshotCreateNonPrimaryRequest, GetMirrorPeersError) {
+  REQUIRE_FORMAT_V2();
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockTestImageCtx mock_image_ctx(*ictx);
+
+  InSequence seq;
+
+  expect_clone_md_ctx(mock_image_ctx);
+  expect_refresh_image(mock_image_ctx, true, 0);
+  expect_get_mirror_image(
+    mock_image_ctx, {cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT, "gid",
+                     cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, 0);
+  MockUtils mock_utils;
+  expect_can_create_non_primary_snapshot(mock_utils, true);
+  expect_get_mirror_peers(mock_image_ctx, {}, -EPERM);
+
+  C_SaferCond ctx;
+  auto req = new MockCreateNonPrimaryRequest(&mock_image_ctx, true,
+                                             "mirror_uuid", 123, {{1, 2}}, {},
+                                             nullptr, &ctx);
+  req->send();
+  ASSERT_EQ(-EPERM, ctx.wait());
+}
+
 TEST_F(TestMockMirrorSnapshotCreateNonPrimaryRequest, CreateSnapshotError) {
   REQUIRE_FORMAT_V2();