]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc
b79d4de9e18d5f468225595e56d001e2a2762a11
[ceph.git] / ceph / src / test / rbd_mirror / image_replayer / test_mock_PrepareLocalImageRequest.cc
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/rbd_mirror/test_mock_fixture.h"
5 #include "cls/rbd/cls_rbd_types.h"
6 #include "librbd/journal/TypeTraits.h"
7 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.h"
8 #include "test/journal/mock/MockJournaler.h"
9 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
10 #include "test/librbd/mock/MockImageCtx.h"
11 #include "test/librbd/mock/MockJournal.h"
12
13 namespace librbd {
14
15 namespace {
16
17 struct MockTestImageCtx : public librbd::MockImageCtx {
18 MockTestImageCtx(librbd::ImageCtx &image_ctx)
19 : librbd::MockImageCtx(image_ctx) {
20 }
21 };
22
23 } // anonymous namespace
24 } // namespace librbd
25
26 // template definitions
27 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc"
28
29 namespace rbd {
30 namespace mirror {
31 namespace image_replayer {
32
33 using ::testing::_;
34 using ::testing::DoAll;
35 using ::testing::InSequence;
36 using ::testing::Invoke;
37 using ::testing::Return;
38 using ::testing::StrEq;
39 using ::testing::WithArg;
40 using ::testing::WithArgs;
41
42 class TestMockImageReplayerPrepareLocalImageRequest : public TestMockFixture {
43 public:
44 typedef PrepareLocalImageRequest<librbd::MockTestImageCtx> MockPrepareLocalImageRequest;
45
46 void expect_mirror_image_get_image_id(librados::IoCtx &io_ctx,
47 const std::string &image_id, int r) {
48 bufferlist bl;
49 ::encode(image_id, bl);
50
51 EXPECT_CALL(get_mock_io_ctx(io_ctx),
52 exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_image_get_image_id"), _, _, _))
53 .WillOnce(DoAll(WithArg<5>(Invoke([bl](bufferlist *out_bl) {
54 *out_bl = bl;
55 })),
56 Return(r)));
57 }
58
59 void expect_mirror_image_get(librados::IoCtx &io_ctx,
60 cls::rbd::MirrorImageState state,
61 const std::string &global_id, int r) {
62 cls::rbd::MirrorImage mirror_image;
63 mirror_image.state = state;
64 mirror_image.global_image_id = global_id;
65
66 bufferlist bl;
67 ::encode(mirror_image, bl);
68
69 EXPECT_CALL(get_mock_io_ctx(io_ctx),
70 exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_image_get"), _, _, _))
71 .WillOnce(DoAll(WithArg<5>(Invoke([bl](bufferlist *out_bl) {
72 *out_bl = bl;
73 })),
74 Return(r)));
75 }
76
77 void expect_get_tag_owner(librbd::MockJournal &mock_journal,
78 const std::string &local_image_id,
79 const std::string &tag_owner, int r) {
80 EXPECT_CALL(mock_journal, get_tag_owner(local_image_id, _, _, _))
81 .WillOnce(WithArgs<1, 3>(Invoke([tag_owner, r](std::string *owner, Context *on_finish) {
82 *owner = tag_owner;
83 on_finish->complete(r);
84 })));
85 }
86
87 };
88
89 TEST_F(TestMockImageReplayerPrepareLocalImageRequest, Success) {
90 InSequence seq;
91 expect_mirror_image_get_image_id(m_local_io_ctx, "local image id", 0);
92 expect_mirror_image_get(m_local_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_ENABLED,
93 "global image id", 0);
94
95 librbd::MockJournal mock_journal;
96 expect_get_tag_owner(mock_journal, "local image id", "remote mirror uuid", 0);
97
98 std::string local_image_id;
99 std::string tag_owner;
100 C_SaferCond ctx;
101 auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx,
102 "global image id",
103 &local_image_id,
104 &tag_owner,
105 m_threads->work_queue,
106 &ctx);
107 req->send();
108
109 ASSERT_EQ(0, ctx.wait());
110 ASSERT_EQ(std::string("local image id"), local_image_id);
111 ASSERT_EQ(std::string("remote mirror uuid"), tag_owner);
112 }
113
114 TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageIdDNE) {
115 InSequence seq;
116 expect_mirror_image_get_image_id(m_local_io_ctx, "", -ENOENT);
117
118 std::string local_image_id;
119 std::string tag_owner;
120 C_SaferCond ctx;
121 auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx,
122 "global image id",
123 &local_image_id,
124 &tag_owner,
125 m_threads->work_queue,
126 &ctx);
127 req->send();
128
129 ASSERT_EQ(-ENOENT, ctx.wait());
130 }
131
132 TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageIdError) {
133 InSequence seq;
134 expect_mirror_image_get_image_id(m_local_io_ctx, "", -EINVAL);
135
136 std::string local_image_id;
137 std::string tag_owner;
138 C_SaferCond ctx;
139 auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx,
140 "global image id",
141 &local_image_id,
142 &tag_owner,
143 m_threads->work_queue,
144 &ctx);
145 req->send();
146
147 ASSERT_EQ(-EINVAL, ctx.wait());
148 }
149
150 TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageError) {
151 InSequence seq;
152 expect_mirror_image_get_image_id(m_local_io_ctx, "local image id", 0);
153 expect_mirror_image_get(m_local_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_DISABLED,
154 "", -EINVAL);
155
156 std::string local_image_id;
157 std::string tag_owner;
158 C_SaferCond ctx;
159 auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx,
160 "global image id",
161 &local_image_id,
162 &tag_owner,
163 m_threads->work_queue,
164 &ctx);
165 req->send();
166
167 ASSERT_EQ(-EINVAL, ctx.wait());
168 }
169
170 TEST_F(TestMockImageReplayerPrepareLocalImageRequest, TagOwnerError) {
171 InSequence seq;
172 expect_mirror_image_get_image_id(m_local_io_ctx, "local image id", 0);
173 expect_mirror_image_get(m_local_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_ENABLED,
174 "global image id", 0);
175
176 librbd::MockJournal mock_journal;
177 expect_get_tag_owner(mock_journal, "local image id", "remote mirror uuid",
178 -ENOENT);
179
180 std::string local_image_id;
181 std::string tag_owner;
182 C_SaferCond ctx;
183 auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx,
184 "global image id",
185 &local_image_id,
186 &tag_owner,
187 m_threads->work_queue,
188 &ctx);
189 req->send();
190
191 ASSERT_EQ(-ENOENT, ctx.wait());
192 }
193
194 } // namespace image_replayer
195 } // namespace mirror
196 } // namespace rbd