Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / rbd_mirror / image_sync / test_mock_SnapshotCreateRequest.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 "test/librados_test_stub/LibradosTestStub.h"
6 #include "include/rbd/librbd.hpp"
7 #include "librbd/ImageCtx.h"
8 #include "librbd/ImageState.h"
9 #include "librbd/Operations.h"
10 #include "osdc/Striper.h"
11 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
12 #include "test/librbd/mock/MockImageCtx.h"
13 #include "tools/rbd_mirror/image_sync/SnapshotCreateRequest.h"
14 #include "tools/rbd_mirror/Threads.h"
15
16 namespace librbd {
17 namespace {
18
19 struct MockTestImageCtx : public librbd::MockImageCtx {
20   MockTestImageCtx(librbd::ImageCtx &image_ctx)
21     : librbd::MockImageCtx(image_ctx) {
22   }
23 };
24
25 } // anonymous namespace
26 } // namespace librbd
27
28 // template definitions
29 #include "tools/rbd_mirror/image_sync/SnapshotCreateRequest.cc"
30 template class rbd::mirror::image_sync::SnapshotCreateRequest<librbd::MockTestImageCtx>;
31
32 namespace rbd {
33 namespace mirror {
34 namespace image_sync {
35
36 using ::testing::_;
37 using ::testing::DoAll;
38 using ::testing::InSequence;
39 using ::testing::Invoke;
40 using ::testing::InvokeWithoutArgs;
41 using ::testing::Return;
42 using ::testing::ReturnNew;
43 using ::testing::StrEq;
44 using ::testing::WithArg;
45
46 class TestMockImageSyncSnapshotCreateRequest : public TestMockFixture {
47 public:
48   typedef SnapshotCreateRequest<librbd::MockTestImageCtx> MockSnapshotCreateRequest;
49
50   void SetUp() override {
51     TestMockFixture::SetUp();
52
53     librbd::RBD rbd;
54     ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
55     ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx));
56   }
57
58   void expect_start_op(librbd::MockExclusiveLock &mock_exclusive_lock) {
59     EXPECT_CALL(mock_exclusive_lock, start_op()).WillOnce(
60       ReturnNew<FunctionContext>([](int) {}));
61   }
62
63   void expect_test_features(librbd::MockTestImageCtx &mock_image_ctx,
64                             uint64_t features, bool enabled) {
65     EXPECT_CALL(mock_image_ctx, test_features(features))
66                   .WillOnce(Return(enabled));
67   }
68
69   void expect_set_size(librbd::MockTestImageCtx &mock_image_ctx, int r) {
70     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
71                 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("set_size"), _, _, _))
72                   .WillOnce(Return(r));
73   }
74
75   void expect_remove_parent(librbd::MockTestImageCtx &mock_image_ctx, int r) {
76     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
77                 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("remove_parent"), _, _, _))
78                   .WillOnce(Return(r));
79   }
80
81   void expect_set_parent(librbd::MockTestImageCtx &mock_image_ctx, int r) {
82     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
83                 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("set_parent"), _, _, _))
84                   .WillOnce(Return(r));
85   }
86
87   void expect_snap_create(librbd::MockTestImageCtx &mock_image_ctx,
88                           const std::string &snap_name, uint64_t snap_id, int r) {
89     EXPECT_CALL(*mock_image_ctx.operations, execute_snap_create(_, StrEq(snap_name), _, 0, true))
90                   .WillOnce(DoAll(InvokeWithoutArgs([&mock_image_ctx, snap_id, snap_name]() {
91                                     inject_snap(mock_image_ctx, snap_id, snap_name);
92                                   }),
93                                   WithArg<2>(Invoke([this, r](Context *ctx) {
94                                     m_threads->work_queue->queue(ctx, r);
95                                   }))));
96   }
97
98   void expect_object_map_resize(librbd::MockTestImageCtx &mock_image_ctx,
99                                 librados::snap_t snap_id, int r) {
100     std::string oid(librbd::ObjectMap<>::object_map_name(mock_image_ctx.id,
101                                                          snap_id));
102     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
103                 exec(oid, _, StrEq("rbd"), StrEq("object_map_resize"), _, _, _))
104                   .WillOnce(Return(r));
105   }
106
107   static void inject_snap(librbd::MockTestImageCtx &mock_image_ctx,
108                    uint64_t snap_id, const std::string &snap_name) {
109     mock_image_ctx.snap_ids[{cls::rbd::UserSnapshotNamespace(),
110                              snap_name}] = snap_id;
111   }
112
113   MockSnapshotCreateRequest *create_request(librbd::MockTestImageCtx &mock_local_image_ctx,
114                                             const std::string &snap_name,
115                                             const cls::rbd::SnapshotNamespace &snap_namespace,
116                                             uint64_t size,
117                                             const librbd::ParentSpec &spec,
118                                             uint64_t parent_overlap,
119                                             Context *on_finish) {
120     return new MockSnapshotCreateRequest(&mock_local_image_ctx, snap_name, snap_namespace, size,
121                                          spec, parent_overlap, on_finish);
122   }
123
124   librbd::ImageCtx *m_local_image_ctx;
125 };
126
127 TEST_F(TestMockImageSyncSnapshotCreateRequest, Resize) {
128   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
129   librbd::MockExclusiveLock mock_exclusive_lock;
130   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
131
132   InSequence seq;
133   expect_start_op(mock_exclusive_lock);
134   expect_set_size(mock_local_image_ctx, 0);
135   expect_start_op(mock_exclusive_lock);
136   expect_snap_create(mock_local_image_ctx, "snap1", 10, 0);
137   expect_test_features(mock_local_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
138
139   C_SaferCond ctx;
140   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
141                                                       "snap1",
142                                                       cls::rbd::UserSnapshotNamespace(),
143                                                       123, {}, 0,
144                                                       &ctx);
145   request->send();
146   ASSERT_EQ(0, ctx.wait());
147 }
148
149 TEST_F(TestMockImageSyncSnapshotCreateRequest, ResizeError) {
150   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
151   librbd::MockExclusiveLock mock_exclusive_lock;
152   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
153
154   InSequence seq;
155   expect_start_op(mock_exclusive_lock);
156   expect_set_size(mock_local_image_ctx, -EINVAL);
157
158   C_SaferCond ctx;
159   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
160                                                       "snap1",
161                                                       cls::rbd::UserSnapshotNamespace(),
162                                                       123, {}, 0,
163                                                       &ctx);
164   request->send();
165   ASSERT_EQ(-EINVAL, ctx.wait());
166 }
167
168 TEST_F(TestMockImageSyncSnapshotCreateRequest, RemoveParent) {
169   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
170   librbd::MockExclusiveLock mock_exclusive_lock;
171   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
172
173   mock_local_image_ctx.parent_md.spec.pool_id = 213;
174
175   InSequence seq;
176   expect_start_op(mock_exclusive_lock);
177   expect_remove_parent(mock_local_image_ctx, 0);
178   expect_start_op(mock_exclusive_lock);
179   expect_snap_create(mock_local_image_ctx, "snap1", 10, 0);
180   expect_test_features(mock_local_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
181
182   C_SaferCond ctx;
183   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
184                                                       "snap1",
185                                                       cls::rbd::UserSnapshotNamespace(),
186                                                       m_local_image_ctx->size,
187                                                       {}, 0, &ctx);
188   request->send();
189   ASSERT_EQ(0, ctx.wait());
190 }
191
192 TEST_F(TestMockImageSyncSnapshotCreateRequest, RemoveParentError) {
193   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
194   librbd::MockExclusiveLock mock_exclusive_lock;
195   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
196
197   mock_local_image_ctx.parent_md.spec.pool_id = 213;
198
199   InSequence seq;
200   expect_start_op(mock_exclusive_lock);
201   expect_remove_parent(mock_local_image_ctx, -EINVAL);
202
203   C_SaferCond ctx;
204   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
205                                                       "snap1",
206                                                       cls::rbd::UserSnapshotNamespace(),
207                                                       m_local_image_ctx->size,
208                                                       {}, 0, &ctx);
209   request->send();
210   ASSERT_EQ(-EINVAL, ctx.wait());
211 }
212
213 TEST_F(TestMockImageSyncSnapshotCreateRequest, RemoveSetParent) {
214   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
215   librbd::MockExclusiveLock mock_exclusive_lock;
216   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
217
218   mock_local_image_ctx.parent_md.spec.pool_id = 213;
219
220   InSequence seq;
221   expect_start_op(mock_exclusive_lock);
222   expect_remove_parent(mock_local_image_ctx, 0);
223   expect_start_op(mock_exclusive_lock);
224   expect_set_parent(mock_local_image_ctx, 0);
225   expect_start_op(mock_exclusive_lock);
226   expect_snap_create(mock_local_image_ctx, "snap1", 10, 0);
227   expect_test_features(mock_local_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
228
229   C_SaferCond ctx;
230   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
231                                                       "snap1",
232                                                       cls::rbd::UserSnapshotNamespace(),
233                                                       m_local_image_ctx->size,
234                                                       {123, "test", 0}, 0,
235                                                       &ctx);
236   request->send();
237   ASSERT_EQ(0, ctx.wait());
238 }
239
240 TEST_F(TestMockImageSyncSnapshotCreateRequest, SetParentSpec) {
241   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
242   librbd::MockExclusiveLock mock_exclusive_lock;
243   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
244
245   InSequence seq;
246   expect_start_op(mock_exclusive_lock);
247   expect_set_parent(mock_local_image_ctx, 0);
248   expect_start_op(mock_exclusive_lock);
249   expect_snap_create(mock_local_image_ctx, "snap1", 10, 0);
250   expect_test_features(mock_local_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
251
252   C_SaferCond ctx;
253   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
254                                                       "snap1",
255                                                       cls::rbd::UserSnapshotNamespace(),
256                                                       m_local_image_ctx->size,
257                                                       {123, "test", 0}, 0,
258                                                       &ctx);
259   request->send();
260   ASSERT_EQ(0, ctx.wait());
261 }
262
263 TEST_F(TestMockImageSyncSnapshotCreateRequest, SetParentOverlap) {
264   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
265   librbd::MockExclusiveLock mock_exclusive_lock;
266   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
267
268   mock_local_image_ctx.parent_md.spec = {123, "test", 0};
269
270   InSequence seq;
271   expect_start_op(mock_exclusive_lock);
272   expect_set_parent(mock_local_image_ctx, 0);
273   expect_start_op(mock_exclusive_lock);
274   expect_snap_create(mock_local_image_ctx, "snap1", 10, 0);
275   expect_test_features(mock_local_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
276
277   C_SaferCond ctx;
278   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
279                                                       "snap1",
280                                                       cls::rbd::UserSnapshotNamespace(),
281                                                       m_local_image_ctx->size,
282                                                       mock_local_image_ctx.parent_md.spec,
283                                                       123, &ctx);
284   request->send();
285   ASSERT_EQ(0, ctx.wait());
286 }
287
288 TEST_F(TestMockImageSyncSnapshotCreateRequest, SetParentError) {
289   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
290   librbd::MockExclusiveLock mock_exclusive_lock;
291   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
292
293   InSequence seq;
294   expect_start_op(mock_exclusive_lock);
295   expect_set_parent(mock_local_image_ctx, -ESTALE);
296
297   C_SaferCond ctx;
298   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
299                                                       "snap1",
300                                                       cls::rbd::UserSnapshotNamespace(),
301                                                       m_local_image_ctx->size,
302                                                       {123, "test", 0}, 0,
303                                                       &ctx);
304   request->send();
305   ASSERT_EQ(-ESTALE, ctx.wait());
306 }
307
308 TEST_F(TestMockImageSyncSnapshotCreateRequest, SnapCreate) {
309   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
310   librbd::MockExclusiveLock mock_exclusive_lock;
311   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
312
313   InSequence seq;
314   expect_start_op(mock_exclusive_lock);
315   expect_snap_create(mock_local_image_ctx, "snap1", 10, 0);
316   expect_test_features(mock_local_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
317
318   C_SaferCond ctx;
319   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
320                                                       "snap1",
321                                                       cls::rbd::UserSnapshotNamespace(),
322                                                       m_local_image_ctx->size,
323                                                       {}, 0, &ctx);
324   request->send();
325   ASSERT_EQ(0, ctx.wait());
326 }
327
328 TEST_F(TestMockImageSyncSnapshotCreateRequest, SnapCreateError) {
329   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
330   librbd::MockExclusiveLock mock_exclusive_lock;
331   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
332
333   InSequence seq;
334   expect_start_op(mock_exclusive_lock);
335   expect_snap_create(mock_local_image_ctx, "snap1", 10, -EINVAL);
336
337   C_SaferCond ctx;
338   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
339                                                       "snap1",
340                                                       cls::rbd::UserSnapshotNamespace(),
341                                                       m_local_image_ctx->size,
342                                                       {}, 0, &ctx);
343   request->send();
344   ASSERT_EQ(-EINVAL, ctx.wait());
345 }
346
347 TEST_F(TestMockImageSyncSnapshotCreateRequest, ResizeObjectMap) {
348   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
349   librbd::MockExclusiveLock mock_exclusive_lock;
350   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
351
352   InSequence seq;
353   expect_start_op(mock_exclusive_lock);
354   expect_snap_create(mock_local_image_ctx, "snap1", 10, 0);
355   expect_test_features(mock_local_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
356   expect_start_op(mock_exclusive_lock);
357   expect_object_map_resize(mock_local_image_ctx, 10, 0);
358
359   C_SaferCond ctx;
360   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
361                                                       "snap1",
362                                                       cls::rbd::UserSnapshotNamespace(),
363                                                       m_local_image_ctx->size,
364                                                       {}, 0, &ctx);
365   request->send();
366   ASSERT_EQ(0, ctx.wait());
367 }
368
369 TEST_F(TestMockImageSyncSnapshotCreateRequest, ResizeObjectMapError) {
370   librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
371   librbd::MockExclusiveLock mock_exclusive_lock;
372   mock_local_image_ctx.exclusive_lock = &mock_exclusive_lock;
373
374   InSequence seq;
375   expect_start_op(mock_exclusive_lock);
376   expect_snap_create(mock_local_image_ctx, "snap1", 10, 0);
377   expect_test_features(mock_local_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
378   expect_start_op(mock_exclusive_lock);
379   expect_object_map_resize(mock_local_image_ctx, 10, -EINVAL);
380
381   C_SaferCond ctx;
382   MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
383                                                       "snap1",
384                                                       cls::rbd::UserSnapshotNamespace(),
385                                                       m_local_image_ctx->size,
386                                                       {}, 0, &ctx);
387   request->send();
388   ASSERT_EQ(-EINVAL, ctx.wait());
389 }
390
391 } // namespace image_sync
392 } // namespace mirror
393 } // namespace rbd