Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / rbd_mirror / image_sync / test_mock_SyncPointPruneRequest.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 "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
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
25 namespace journal {
26
27 template <>
28 struct 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"
37 template class rbd::mirror::image_sync::SyncPointPruneRequest<librbd::MockTestImageCtx>;
38
39 namespace rbd {
40 namespace mirror {
41 namespace image_sync {
42
43 using ::testing::_;
44 using ::testing::InSequence;
45 using ::testing::Return;
46 using ::testing::StrEq;
47 using ::testing::WithArg;
48
49 class TestMockImageSyncSyncPointPruneRequest : public TestMockFixture {
50 public:
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
94 TEST_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
117 TEST_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
146 TEST_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
177 TEST_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
205 TEST_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
230 TEST_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
257 TEST_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
286 TEST_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
309 TEST_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