Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / librbd / image / test_mock_RemoveRequest.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/librbd/test_mock_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "test/librbd/mock/MockImageCtx.h"
7 #include "test/librbd/mock/MockContextWQ.h"
8 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
9 #include "test/librados_test_stub/MockTestMemRadosClient.h"
10 #include "librbd/ImageState.h"
11 #include "librbd/internal.h"
12 #include "librbd/journal/RemoveRequest.h"
13 #include "librbd/Operations.h"
14 #include "librbd/operation/TrimRequest.h"
15 #include "librbd/image/TypeTraits.h"
16 #include "librbd/image/RemoveRequest.h"
17 #include "librbd/image/RefreshParentRequest.h"
18 #include "librbd/mirror/DisableRequest.h"
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
21 #include <arpa/inet.h>
22 #include <list>
23 #include <boost/scope_exit.hpp>
24
25 namespace librbd {
26 namespace image {
27 template <>
28 struct TypeTraits<MockImageCtx> {
29   typedef librbd::MockContextWQ ContextWQ;
30 };
31 }
32
33 namespace operation {
34
35 template <>
36 class TrimRequest<MockImageCtx> {
37 public:
38   static TrimRequest *s_instance;
39   static TrimRequest *create(MockImageCtx &image_ctx, Context *on_finish,
40                              uint64_t original_size, uint64_t new_size,
41                              ProgressContext &prog_ctx) {
42     assert(s_instance != nullptr);
43     s_instance->on_finish = on_finish;
44     return s_instance;
45   }
46
47   Context *on_finish = nullptr;
48
49   TrimRequest() {
50     s_instance = this;
51   }
52
53   MOCK_METHOD0(send, void());
54 };
55
56 } // namespace operation
57
58 namespace journal {
59 template <>
60 class RemoveRequest<MockImageCtx> {
61 private:
62   typedef ::librbd::image::TypeTraits<MockImageCtx> TypeTraits;
63   typedef typename TypeTraits::ContextWQ ContextWQ;
64 public:
65   static RemoveRequest *s_instance;
66   static RemoveRequest *create(IoCtx &ioctx, const std::string &imageid,
67                                       const std::string &client_id,
68                                       ContextWQ *op_work_queue, Context *on_finish) {
69     assert(s_instance != nullptr);
70     s_instance->on_finish = on_finish;
71     return s_instance;
72   }
73
74   Context *on_finish = nullptr;
75
76   RemoveRequest() {
77     s_instance = this;
78   }
79
80   MOCK_METHOD0(send, void());
81 };
82 RemoveRequest<MockImageCtx> *RemoveRequest<MockImageCtx>::s_instance = nullptr;
83 } // namespace journal
84
85 namespace mirror {
86
87 template<>
88 class DisableRequest<MockImageCtx> {
89 public:
90   static DisableRequest *s_instance;
91   Context *on_finish = nullptr;
92
93   static DisableRequest *create(MockImageCtx *image_ctx, bool force,
94                                 bool remove, Context *on_finish) {
95     assert(s_instance != nullptr);
96     s_instance->on_finish = on_finish;
97     return s_instance;
98   }
99
100   DisableRequest() {
101     s_instance = this;
102   }
103
104   MOCK_METHOD0(send, void());
105 };
106
107 DisableRequest<MockImageCtx> *DisableRequest<MockImageCtx>::s_instance;
108
109 } // namespace mirror
110 } // namespace librbd
111
112 // template definitions
113 #include "librbd/image/RemoveRequest.cc"
114 template class librbd::image::RemoveRequest<librbd::MockImageCtx>;
115
116 namespace librbd {
117 namespace image {
118
119 using ::testing::_;
120 using ::testing::DoAll;
121 using ::testing::DoDefault;
122 using ::testing::Invoke;
123 using ::testing::InSequence;
124 using ::testing::Return;
125 using ::testing::WithArg;
126 using ::testing::SetArgPointee;
127 using ::testing::StrEq;
128
129 class TestMockImageRemoveRequest : public TestMockFixture {
130 public:
131   typedef ::librbd::image::TypeTraits<MockImageCtx> TypeTraits;
132   typedef typename TypeTraits::ContextWQ ContextWQ;
133   typedef RemoveRequest<MockImageCtx> MockRemoveRequest;
134   typedef librbd::operation::TrimRequest<MockImageCtx> MockTrimRequest;
135   typedef librbd::journal::RemoveRequest<MockImageCtx> MockJournalRemoveRequest;
136   typedef librbd::mirror::DisableRequest<MockImageCtx> MockMirrorDisableRequest;
137
138   librbd::ImageCtx *m_test_imctx = NULL;
139   MockImageCtx *m_mock_imctx = NULL;
140
141
142   void TestImageRemoveSetUp() {
143     ASSERT_EQ(0, open_image(m_image_name, &m_test_imctx));
144     m_mock_imctx = new MockImageCtx(*m_test_imctx);
145     librbd::MockImageCtx::s_instance = m_mock_imctx;
146   }
147   void TestImageRemoveTearDown() {
148     librbd::MockImageCtx::s_instance = NULL;
149     delete m_mock_imctx;
150   }
151
152   void expect_state_open(MockImageCtx &mock_image_ctx, int r) {
153     EXPECT_CALL(*mock_image_ctx.state, open(_, _))
154       .WillOnce(Invoke([r](bool open_parent, Context *on_ready) {
155                   on_ready->complete(r);
156                 }));
157     if (r < 0) {
158       EXPECT_CALL(mock_image_ctx, destroy());
159     }
160   }
161
162   void expect_state_close(MockImageCtx &mock_image_ctx) {
163     EXPECT_CALL(*mock_image_ctx.state, close(_))
164       .WillOnce(Invoke([](Context *on_ready) {
165                   on_ready->complete(0);
166                 }));
167     EXPECT_CALL(mock_image_ctx, destroy());
168   }
169
170   void expect_wq_queue(ContextWQ &wq, int r) {
171     EXPECT_CALL(wq, queue(_, r))
172       .WillRepeatedly(Invoke([](Context *on_ready, int r) {
173                   on_ready->complete(r);
174                 }));
175   }
176
177   void expect_get_group(MockImageCtx &mock_image_ctx, int r) {
178     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
179                                exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
180                                     StrEq("image_get_group"), _, _, _));
181     if (r < 0) {
182       expect.WillOnce(Return(r));
183     } else {
184       expect.WillOnce(DoDefault());
185     }
186   }
187
188   void expect_trim(MockImageCtx &mock_image_ctx,
189                    MockTrimRequest &mock_trim_request, int r) {
190     EXPECT_CALL(mock_trim_request, send())
191                   .WillOnce(FinishRequest(&mock_trim_request, r, &mock_image_ctx));
192   }
193
194   void expect_journal_remove(MockImageCtx &mock_image_ctx,
195                    MockJournalRemoveRequest &mock_journal_remove_request, int r) {
196     EXPECT_CALL(mock_journal_remove_request, send())
197                   .WillOnce(FinishRequest(&mock_journal_remove_request, r, &mock_image_ctx));
198   }
199
200   void expect_mirror_disable(MockImageCtx &mock_image_ctx,
201                    MockMirrorDisableRequest &mock_mirror_disable_request, int r) {
202     EXPECT_CALL(mock_mirror_disable_request, send())
203                   .WillOnce(FinishRequest(&mock_mirror_disable_request, r, &mock_image_ctx));
204   }
205
206   void expect_remove_child(MockImageCtx &mock_image_ctx, int r) {
207     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
208                                exec(RBD_CHILDREN, _, StrEq("rbd"), StrEq("remove_child"), _,
209                                     _, _))
210       .WillOnce(Return(r));
211   }
212
213   void expect_remove_mirror_image(librados::IoCtx &ioctx, int r) {
214     EXPECT_CALL(get_mock_io_ctx(ioctx),
215                 exec(StrEq("rbd_mirroring"), _, StrEq("rbd"), StrEq("mirror_image_remove"),
216                      _, _, _))
217       .WillOnce(Return(r));
218   }
219
220   void expect_mirror_image_get(MockImageCtx &mock_image_ctx, int r) {
221     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
222                 exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_image_get"),
223                      _, _, _))
224       .WillOnce(Return(r));
225   }
226
227   void expect_dir_remove_image(librados::IoCtx &ioctx, int r) {
228     EXPECT_CALL(get_mock_io_ctx(ioctx),
229                 exec(RBD_DIRECTORY, _, StrEq("rbd"), StrEq("dir_remove_image"),
230                      _, _, _))
231       .WillOnce(Return(r));
232   }
233 };
234
235 TEST_F(TestMockImageRemoveRequest, SuccessV1) {
236   REQUIRE_FORMAT_V1();
237   TestImageRemoveSetUp();
238
239   C_SaferCond ctx;
240   librbd::NoOpProgressContext no_op;
241   ContextWQ op_work_queue;
242   MockTrimRequest mock_trim_request;
243   MockJournalRemoveRequest mock_journal_remove_request;
244
245   InSequence seq;
246   expect_state_open(*m_mock_imctx, 0);
247   expect_get_group(*m_mock_imctx, 0);
248   expect_trim(*m_mock_imctx, mock_trim_request, 0);
249   expect_op_work_queue(*m_mock_imctx);
250   expect_state_close(*m_mock_imctx);
251   expect_wq_queue(op_work_queue, 0);
252
253   MockRemoveRequest *req = MockRemoveRequest::create(m_ioctx, m_image_name, "",
254                                               true, false, no_op, &op_work_queue, &ctx);
255   req->send();
256
257   ASSERT_EQ(0, ctx.wait());
258
259   TestImageRemoveTearDown();
260 }
261
262 TEST_F(TestMockImageRemoveRequest, OpenFailV1) {
263   REQUIRE_FORMAT_V1();
264   TestImageRemoveSetUp();
265
266   C_SaferCond ctx;
267   librbd::NoOpProgressContext no_op;
268   ContextWQ op_work_queue;
269   MockTrimRequest mock_trim_request;
270
271   InSequence seq;
272   expect_state_open(*m_mock_imctx, -ENOENT);
273   expect_wq_queue(op_work_queue, 0);
274
275   MockRemoveRequest *req = MockRemoveRequest::create(m_ioctx, m_image_name, "",
276                                               true, false, no_op, &op_work_queue, &ctx);
277   req->send();
278
279   ASSERT_EQ(0, ctx.wait());
280
281   TestImageRemoveTearDown();
282 }
283
284 TEST_F(TestMockImageRemoveRequest, SuccessV2) {
285   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
286   TestImageRemoveSetUp();
287
288   C_SaferCond ctx;
289   librbd::NoOpProgressContext no_op;
290   ContextWQ op_work_queue;
291   MockTrimRequest mock_trim_request;
292   MockJournalRemoveRequest mock_journal_remove_request;
293   MockMirrorDisableRequest mock_mirror_disable_request;
294
295   InSequence seq;
296   expect_state_open(*m_mock_imctx, 0);
297   expect_mirror_image_get(*m_mock_imctx, 0);
298   expect_get_group(*m_mock_imctx, 0);
299   expect_trim(*m_mock_imctx, mock_trim_request, 0);
300   expect_op_work_queue(*m_mock_imctx);
301   expect_remove_child(*m_mock_imctx, 0);
302   expect_mirror_disable(*m_mock_imctx, mock_mirror_disable_request, 0);
303   expect_state_close(*m_mock_imctx);
304   expect_wq_queue(op_work_queue, 0);
305   expect_journal_remove(*m_mock_imctx, mock_journal_remove_request, 0);
306   expect_remove_mirror_image(m_ioctx, 0);
307   expect_dir_remove_image(m_ioctx, 0);
308
309   MockRemoveRequest *req = MockRemoveRequest::create(m_ioctx, m_image_name, "",
310                                               true, false, no_op, &op_work_queue, &ctx);
311   req->send();
312
313   ASSERT_EQ(0, ctx.wait());
314
315   TestImageRemoveTearDown();
316 }
317
318 TEST_F(TestMockImageRemoveRequest, NotExistsV2) {
319   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
320   TestImageRemoveSetUp();
321
322   C_SaferCond ctx;
323   librbd::NoOpProgressContext no_op;
324   ContextWQ op_work_queue;
325   MockTrimRequest mock_trim_request;
326   MockJournalRemoveRequest mock_journal_remove_request;
327   MockMirrorDisableRequest mock_mirror_disable_request;
328
329   InSequence seq;
330   expect_state_open(*m_mock_imctx, 0);
331   expect_mirror_image_get(*m_mock_imctx, 0);
332   expect_get_group(*m_mock_imctx, 0);
333   expect_trim(*m_mock_imctx, mock_trim_request, 0);
334   expect_op_work_queue(*m_mock_imctx);
335   expect_remove_child(*m_mock_imctx, 0);
336   expect_mirror_disable(*m_mock_imctx, mock_mirror_disable_request, 0);
337   expect_state_close(*m_mock_imctx);
338   expect_wq_queue(op_work_queue, 0);
339   expect_journal_remove(*m_mock_imctx, mock_journal_remove_request, 0);
340   expect_remove_mirror_image(m_ioctx, 0);
341   expect_dir_remove_image(m_ioctx, -ENOENT);
342
343   MockRemoveRequest *req = MockRemoveRequest::create(m_ioctx, m_image_name, "",
344                                               true, false, no_op, &op_work_queue, &ctx);
345   req->send();
346   ASSERT_EQ(-ENOENT, ctx.wait());
347
348   TestImageRemoveTearDown();
349 }
350
351 } // namespace image
352 } // namespace librbd