]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / rbd_mirror / image_sync / test_mock_SyncPointPruneRequest.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/rbd_mirror/test_mock_fixture.h"
5#include "include/rbd/librbd.hpp"
6#include "librbd/journal/Types.h"
7#include "librbd/journal/TypeTraits.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 "tools/rbd_mirror/image_sync/SyncPointPruneRequest.h"
12
13namespace librbd {
14
15namespace {
16
17struct MockTestImageCtx : public librbd::MockImageCtx {
11fdf7f2 18 explicit MockTestImageCtx(librbd::ImageCtx &image_ctx)
7c673cae
FG
19 : librbd::MockImageCtx(image_ctx) {
20 }
21};
22
23} // anonymous namespace
24
25namespace journal {
26
27template <>
28struct TypeTraits<librbd::MockTestImageCtx> {
29 typedef ::journal::MockJournaler Journaler;
30};
31
32} // namespace journal
33} // namespace librbd
34
35// template definitions
36#include "tools/rbd_mirror/image_sync/SyncPointPruneRequest.cc"
37template class rbd::mirror::image_sync::SyncPointPruneRequest<librbd::MockTestImageCtx>;
38
39namespace rbd {
40namespace mirror {
41namespace image_sync {
42
43using ::testing::_;
44using ::testing::InSequence;
45using ::testing::Return;
46using ::testing::StrEq;
47using ::testing::WithArg;
48
49class TestMockImageSyncSyncPointPruneRequest : public TestMockFixture {
50public:
51 typedef SyncPointPruneRequest<librbd::MockTestImageCtx> MockSyncPointPruneRequest;
52
53 void SetUp() override {
54 TestMockFixture::SetUp();
55
56 librbd::RBD rbd;
57 ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
58 ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
59 }
60
61 void expect_update_client(journal::MockJournaler &mock_journaler, int r) {
62 EXPECT_CALL(mock_journaler, update_client(_, _))
63 .WillOnce(WithArg<1>(CompleteContext(r)));
64 }
65
66 void expect_get_snap_id(librbd::MockTestImageCtx &mock_remote_image_ctx,
67 const std::string &snap_name, uint64_t snap_id) {
68 EXPECT_CALL(mock_remote_image_ctx, get_snap_id(_, StrEq(snap_name)))
69 .WillOnce(Return(snap_id));
70 }
71
72 void expect_image_refresh(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) {
73 EXPECT_CALL(*mock_remote_image_ctx.state, refresh(_))
74 .WillOnce(CompleteContext(r));
75 }
76
77 void expect_snap_remove(librbd::MockTestImageCtx &mock_remote_image_ctx,
78 const std::string &snap_name, int r) {
79 EXPECT_CALL(*mock_remote_image_ctx.operations, snap_remove(_, StrEq(snap_name), _))
80 .WillOnce(WithArg<2>(CompleteContext(r)));
81 }
82
83 MockSyncPointPruneRequest *create_request(librbd::MockTestImageCtx &mock_remote_image_ctx,
84 journal::MockJournaler &mock_journaler,
85 bool sync_complete, Context *ctx) {
86 return new MockSyncPointPruneRequest(&mock_remote_image_ctx, sync_complete,
87 &mock_journaler, &m_client_meta, ctx);
88 }
89
90 librbd::ImageCtx *m_remote_image_ctx;
91 librbd::journal::MirrorPeerClientMeta m_client_meta;
92};
93
94TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncInProgressSuccess) {
95 librbd::journal::MirrorPeerClientMeta client_meta;
96 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
97 "snap1",
98 boost::none);
99 m_client_meta = client_meta;
100
101 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
102 journal::MockJournaler mock_journaler;
103
104 InSequence seq;
105 expect_get_snap_id(mock_remote_image_ctx, "snap1", 123);
106 expect_image_refresh(mock_remote_image_ctx, 0);
107 expect_update_client(mock_journaler, 0);
108
109 C_SaferCond ctx;
110 MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
111 mock_journaler, false, &ctx);
112 req->send();
113 ASSERT_EQ(0, ctx.wait());
114 ASSERT_EQ(client_meta, m_client_meta);
115}
116
117TEST_F(TestMockImageSyncSyncPointPruneRequest, RestartedSyncInProgressSuccess) {
118 librbd::journal::MirrorPeerClientMeta client_meta;
119 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
120 "snap2",
121 "snap1", boost::none);
122 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
123 "snap1",
124 boost::none);
125 m_client_meta = client_meta;
126
127 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
128 journal::MockJournaler mock_journaler;
129
130 InSequence seq;
131 expect_get_snap_id(mock_remote_image_ctx, "snap1", 123);
132 expect_snap_remove(mock_remote_image_ctx, "snap2", 0);
133 expect_image_refresh(mock_remote_image_ctx, 0);
134 expect_update_client(mock_journaler, 0);
135
136 C_SaferCond ctx;
137 MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
138 mock_journaler, false, &ctx);
139 req->send();
140 ASSERT_EQ(0, ctx.wait());
141
142 client_meta.sync_points.pop_back();
143 ASSERT_EQ(client_meta, m_client_meta);
144}
145
146TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncInProgressMissingSnapSuccess) {
147 librbd::journal::MirrorPeerClientMeta client_meta;
148 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
149 "snap2",
150 "snap1",
151 boost::none);
152 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
153 "snap1",
154 boost::none);
155 m_client_meta = client_meta;
156
157 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
158 journal::MockJournaler mock_journaler;
159
160 InSequence seq;
161 expect_get_snap_id(mock_remote_image_ctx, "snap1", CEPH_NOSNAP);
162 expect_snap_remove(mock_remote_image_ctx, "snap2", 0);
163 expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
164 expect_image_refresh(mock_remote_image_ctx, 0);
165 expect_update_client(mock_journaler, 0);
166
167 C_SaferCond ctx;
168 MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
169 mock_journaler, false, &ctx);
170 req->send();
171 ASSERT_EQ(0, ctx.wait());
172
173 client_meta.sync_points.clear();
174 ASSERT_EQ(client_meta, m_client_meta);
175}
176
177TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncInProgressUnexpectedFromSnapSuccess) {
178 librbd::journal::MirrorPeerClientMeta client_meta;
179 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
180 "snap2",
181 "snap1",
182 boost::none);
183 m_client_meta = client_meta;
184
185 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
186 journal::MockJournaler mock_journaler;
187
188 InSequence seq;
189 expect_get_snap_id(mock_remote_image_ctx, "snap2", 124);
190 expect_snap_remove(mock_remote_image_ctx, "snap2", 0);
191 expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
192 expect_image_refresh(mock_remote_image_ctx, 0);
193 expect_update_client(mock_journaler, 0);
194
195 C_SaferCond ctx;
196 MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
197 mock_journaler, false, &ctx);
198 req->send();
199 ASSERT_EQ(0, ctx.wait());
200
201 client_meta.sync_points.clear();
202 ASSERT_EQ(client_meta, m_client_meta);
203}
204
205TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncCompleteSuccess) {
206 librbd::journal::MirrorPeerClientMeta client_meta;
207 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
208 "snap1",
209 boost::none);
210 m_client_meta = client_meta;
211 ASSERT_EQ(librbd::journal::MIRROR_PEER_STATE_SYNCING, m_client_meta.state);
212
213 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
214 journal::MockJournaler mock_journaler;
215
216 InSequence seq;
217 expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
218 expect_image_refresh(mock_remote_image_ctx, 0);
219 expect_update_client(mock_journaler, 0);
220
221 C_SaferCond ctx;
222 MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
223 mock_journaler, true, &ctx);
224 req->send();
225 ASSERT_EQ(0, ctx.wait());
226 ASSERT_TRUE(m_client_meta.sync_points.empty());
227 ASSERT_EQ(librbd::journal::MIRROR_PEER_STATE_REPLAYING, m_client_meta.state);
228}
229
230TEST_F(TestMockImageSyncSyncPointPruneRequest, RestartedSyncCompleteSuccess) {
231 librbd::journal::MirrorPeerClientMeta client_meta;
232 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
233 "snap2",
234 "snap1",
235 boost::none);
236 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
237 "snap1",
238 boost::none);
239 m_client_meta = client_meta;
240
241 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
242 journal::MockJournaler mock_journaler;
243
244 InSequence seq;
245 expect_image_refresh(mock_remote_image_ctx, 0);
246 expect_update_client(mock_journaler, 0);
247
248 C_SaferCond ctx;
249 MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
250 mock_journaler, true, &ctx);
251 req->send();
252 ASSERT_EQ(0, ctx.wait());
253 client_meta.sync_points.pop_front();
254 ASSERT_EQ(client_meta, m_client_meta);
255}
256
257TEST_F(TestMockImageSyncSyncPointPruneRequest, RestartedCatchUpSyncCompleteSuccess) {
258 librbd::journal::MirrorPeerClientMeta client_meta;
259 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
260 "snap3",
261 "snap2",
262 boost::none);
263 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
264 "snap2",
265 "snap1",
266 boost::none);
267 m_client_meta = client_meta;
268
269 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
270 journal::MockJournaler mock_journaler;
271
272 InSequence seq;
273 expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
274 expect_image_refresh(mock_remote_image_ctx, 0);
275 expect_update_client(mock_journaler, 0);
276
277 C_SaferCond ctx;
278 MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
279 mock_journaler, true, &ctx);
280 req->send();
281 ASSERT_EQ(0, ctx.wait());
282 client_meta.sync_points.pop_front();
283 ASSERT_EQ(client_meta, m_client_meta);
284}
285
286TEST_F(TestMockImageSyncSyncPointPruneRequest, SnapshotDNE) {
287 librbd::journal::MirrorPeerClientMeta client_meta;
288 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
289 "snap1",
290 boost::none);
291 m_client_meta = client_meta;
292
293 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
294 journal::MockJournaler mock_journaler;
295
296 InSequence seq;
297 expect_snap_remove(mock_remote_image_ctx, "snap1", -ENOENT);
298 expect_image_refresh(mock_remote_image_ctx, 0);
299 expect_update_client(mock_journaler, 0);
300
301 C_SaferCond ctx;
302 MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
303 mock_journaler, true, &ctx);
304 req->send();
305 ASSERT_EQ(0, ctx.wait());
306 ASSERT_TRUE(m_client_meta.sync_points.empty());
307}
308
309TEST_F(TestMockImageSyncSyncPointPruneRequest, ClientUpdateError) {
310 librbd::journal::MirrorPeerClientMeta client_meta;
311 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
312 "snap2",
313 "snap1",
314 boost::none);
315 client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
316 "snap1",
317 boost::none);
318 m_client_meta = client_meta;
319
320 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
321 journal::MockJournaler mock_journaler;
322
323 InSequence seq;
324 expect_image_refresh(mock_remote_image_ctx, 0);
325 expect_update_client(mock_journaler, -EINVAL);
326
327 C_SaferCond ctx;
328 MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
329 mock_journaler, true, &ctx);
330 req->send();
331 ASSERT_EQ(-EINVAL, ctx.wait());
332
333 ASSERT_EQ(client_meta, m_client_meta);
334}
335
336} // namespace image_sync
337} // namespace mirror
338} // namespace rbd