Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / librbd / journal / test_mock_PromoteRequest.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/journal/mock/MockJournaler.h"
8 #include "librbd/journal/OpenRequest.h"
9 #include "librbd/journal/PromoteRequest.h"
10
11 namespace librbd {
12
13 namespace {
14
15 struct MockTestImageCtx : public MockImageCtx {
16   MockTestImageCtx(librbd::ImageCtx& image_ctx) : MockImageCtx(image_ctx) {
17   }
18 };
19
20 } // anonymous namespace
21
22 namespace journal {
23
24 template <>
25 struct TypeTraits<MockTestImageCtx> {
26   typedef ::journal::MockJournalerProxy Journaler;
27   typedef ::journal::MockFutureProxy  Future;
28 };
29
30 template <>
31 struct OpenRequest<MockTestImageCtx> {
32   Context *on_finish = nullptr;
33   static OpenRequest *s_instance;
34   static OpenRequest *create(MockTestImageCtx *image_ctx,
35                              ::journal::MockJournalerProxy *journaler,
36                              Mutex *lock, ImageClientMeta *client_meta,
37                              uint64_t *tag_tid, journal::TagData *tag_data,
38                              Context *on_finish) {
39     assert(s_instance != nullptr);
40     client_meta->tag_class = 456;
41     tag_data->mirror_uuid = Journal<>::ORPHAN_MIRROR_UUID;
42     *tag_tid = 567;
43     s_instance->on_finish = on_finish;
44     return s_instance;
45   }
46
47   OpenRequest() {
48     s_instance = this;
49   }
50
51   MOCK_METHOD0(send, void());
52 };
53
54 OpenRequest<MockTestImageCtx> *OpenRequest<MockTestImageCtx>::s_instance = nullptr;
55
56 } // namespace journal
57 } // namespace librbd
58
59 // template definitions
60 #include "librbd/journal/PromoteRequest.cc"
61 template class librbd::journal::PromoteRequest<librbd::MockTestImageCtx>;
62
63 namespace librbd {
64 namespace journal {
65
66 using ::testing::_;
67 using ::testing::A;
68 using ::testing::InSequence;
69 using ::testing::Return;
70 using ::testing::WithArg;
71
72 class TestMockJournalPromoteRequest : public TestMockFixture {
73 public:
74   typedef PromoteRequest<MockTestImageCtx> MockPromoteRequest;
75   typedef OpenRequest<MockTestImageCtx> MockOpenRequest;
76
77   void expect_construct_journaler(::journal::MockJournaler &mock_journaler) {
78     EXPECT_CALL(mock_journaler, construct());
79   }
80
81   void expect_open_journaler(MockTestImageCtx &mock_image_ctx,
82                              MockOpenRequest &mock_open_request, int r) {
83     EXPECT_CALL(mock_open_request, send())
84       .WillOnce(FinishRequest(&mock_open_request, r, &mock_image_ctx));
85   }
86
87   void expect_allocate_tag(::journal::MockJournaler &mock_journaler,
88                            const journal::TagPredecessor &predecessor, int r) {
89     TagData tag_data;
90     tag_data.mirror_uuid = Journal<>::LOCAL_MIRROR_UUID;
91     tag_data.predecessor = predecessor;
92
93     bufferlist tag_data_bl;
94     ::encode(tag_data, tag_data_bl);
95
96     EXPECT_CALL(mock_journaler, allocate_tag(456, ContentsEqual(tag_data_bl),
97                                              _, _))
98       .WillOnce(WithArg<3>(CompleteContext(r, static_cast<ContextWQ*>(NULL))));
99   }
100
101   void expect_append_journaler(::journal::MockJournaler &mock_journaler) {
102     EXPECT_CALL(mock_journaler, append(_, _))
103                   .WillOnce(Return(::journal::MockFutureProxy()));
104   }
105
106   void expect_future_flush(::journal::MockFuture &mock_future, int r) {
107     EXPECT_CALL(mock_future, flush(_))
108                   .WillOnce(CompleteContext(r, static_cast<ContextWQ*>(NULL)));
109   }
110
111   void expect_future_committed(::journal::MockJournaler &mock_journaler) {
112     EXPECT_CALL(mock_journaler, committed(A<const ::journal::MockFutureProxy &>()));
113   }
114
115   void expect_flush_commit_position(::journal::MockJournaler &mock_journaler,
116                                     int r) {
117     EXPECT_CALL(mock_journaler, flush_commit_position(_))
118                   .WillOnce(CompleteContext(r, static_cast<ContextWQ*>(NULL)));
119   }
120
121   void expect_start_append(::journal::MockJournaler &mock_journaler) {
122     EXPECT_CALL(mock_journaler, start_append(_, _, _));
123   }
124
125   void expect_stop_append(::journal::MockJournaler &mock_journaler, int r) {
126     EXPECT_CALL(mock_journaler, stop_append(_))
127                   .WillOnce(CompleteContext(r, static_cast<ContextWQ*>(NULL)));
128   }
129
130   void expect_shut_down_journaler(::journal::MockJournaler &mock_journaler,
131                                   int r) {
132     EXPECT_CALL(mock_journaler, shut_down(_))
133       .WillOnce(CompleteContext(r, static_cast<ContextWQ*>(NULL)));
134   }
135
136 };
137
138 TEST_F(TestMockJournalPromoteRequest, SuccessOrderly) {
139   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
140
141   librbd::ImageCtx *ictx;
142   ASSERT_EQ(0, open_image(m_image_name, &ictx));
143
144   MockTestImageCtx mock_image_ctx(*ictx);
145   ::journal::MockJournaler mock_journaler;
146   MockOpenRequest mock_open_request;
147
148   expect_op_work_queue(mock_image_ctx);
149
150   InSequence seq;
151   expect_construct_journaler(mock_journaler);
152   expect_open_journaler(mock_image_ctx, mock_open_request, 0);
153   expect_allocate_tag(mock_journaler,
154                       {Journal<>::ORPHAN_MIRROR_UUID, true, 567, 1}, 0);
155
156   ::journal::MockFuture mock_future;
157   expect_start_append(mock_journaler);
158   expect_append_journaler(mock_journaler);
159   expect_future_flush(mock_future, 0);
160   expect_future_committed(mock_journaler);
161   expect_flush_commit_position(mock_journaler, 0);
162   expect_stop_append(mock_journaler, 0);
163
164   expect_shut_down_journaler(mock_journaler, 0);
165
166   C_SaferCond ctx;
167   auto req = MockPromoteRequest::create(&mock_image_ctx, false, &ctx);
168   req->send();
169   ASSERT_EQ(0, ctx.wait());
170 }
171
172 TEST_F(TestMockJournalPromoteRequest, SuccessForced) {
173   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
174
175   librbd::ImageCtx *ictx;
176   ASSERT_EQ(0, open_image(m_image_name, &ictx));
177
178   MockTestImageCtx mock_image_ctx(*ictx);
179   ::journal::MockJournaler mock_journaler;
180   MockOpenRequest mock_open_request;
181
182   expect_op_work_queue(mock_image_ctx);
183
184   InSequence seq;
185   expect_construct_journaler(mock_journaler);
186   expect_open_journaler(mock_image_ctx, mock_open_request, 0);
187   expect_allocate_tag(mock_journaler,
188                       {Journal<>::LOCAL_MIRROR_UUID, true, 567, 0}, 0);
189
190   ::journal::MockFuture mock_future;
191   expect_start_append(mock_journaler);
192   expect_append_journaler(mock_journaler);
193   expect_future_flush(mock_future, 0);
194   expect_future_committed(mock_journaler);
195   expect_flush_commit_position(mock_journaler, 0);
196   expect_stop_append(mock_journaler, 0);
197
198   expect_shut_down_journaler(mock_journaler, 0);
199
200   C_SaferCond ctx;
201   auto req = MockPromoteRequest::create(&mock_image_ctx, true, &ctx);
202   req->send();
203   ASSERT_EQ(0, ctx.wait());
204 }
205
206 TEST_F(TestMockJournalPromoteRequest, OpenError) {
207   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
208
209   librbd::ImageCtx *ictx;
210   ASSERT_EQ(0, open_image(m_image_name, &ictx));
211
212   MockTestImageCtx mock_image_ctx(*ictx);
213   ::journal::MockJournaler mock_journaler;
214   MockOpenRequest mock_open_request;
215
216   expect_op_work_queue(mock_image_ctx);
217
218   InSequence seq;
219   expect_construct_journaler(mock_journaler);
220   expect_open_journaler(mock_image_ctx, mock_open_request, -ENOENT);
221   expect_shut_down_journaler(mock_journaler, -EINVAL);
222
223   C_SaferCond ctx;
224   auto req = MockPromoteRequest::create(&mock_image_ctx, false, &ctx);
225   req->send();
226   ASSERT_EQ(-ENOENT, ctx.wait());
227 }
228
229 TEST_F(TestMockJournalPromoteRequest, AllocateTagError) {
230   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
231
232   librbd::ImageCtx *ictx;
233   ASSERT_EQ(0, open_image(m_image_name, &ictx));
234
235   MockTestImageCtx mock_image_ctx(*ictx);
236   ::journal::MockJournaler mock_journaler;
237   MockOpenRequest mock_open_request;
238
239   expect_op_work_queue(mock_image_ctx);
240
241   InSequence seq;
242   expect_construct_journaler(mock_journaler);
243   expect_open_journaler(mock_image_ctx, mock_open_request, 0);
244   expect_allocate_tag(mock_journaler,
245                       {Journal<>::LOCAL_MIRROR_UUID, true, 567, 0}, -EBADMSG);
246   expect_shut_down_journaler(mock_journaler, -EINVAL);
247
248   C_SaferCond ctx;
249   auto req = MockPromoteRequest::create(&mock_image_ctx, true, &ctx);
250   req->send();
251   ASSERT_EQ(-EBADMSG, ctx.wait());
252 }
253
254 TEST_F(TestMockJournalPromoteRequest, AppendEventError) {
255   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
256
257   librbd::ImageCtx *ictx;
258   ASSERT_EQ(0, open_image(m_image_name, &ictx));
259
260   MockTestImageCtx mock_image_ctx(*ictx);
261   ::journal::MockJournaler mock_journaler;
262   MockOpenRequest mock_open_request;
263
264   expect_op_work_queue(mock_image_ctx);
265
266   InSequence seq;
267   expect_construct_journaler(mock_journaler);
268   expect_open_journaler(mock_image_ctx, mock_open_request, 0);
269   expect_allocate_tag(mock_journaler,
270                       {Journal<>::ORPHAN_MIRROR_UUID, true, 567, 1}, 0);
271
272   ::journal::MockFuture mock_future;
273   expect_start_append(mock_journaler);
274   expect_append_journaler(mock_journaler);
275   expect_future_flush(mock_future, -EPERM);
276   expect_stop_append(mock_journaler, 0);
277
278   expect_shut_down_journaler(mock_journaler, 0);
279
280   C_SaferCond ctx;
281   auto req = MockPromoteRequest::create(&mock_image_ctx, false, &ctx);
282   req->send();
283   ASSERT_EQ(-EPERM, ctx.wait());
284 }
285
286 TEST_F(TestMockJournalPromoteRequest, CommitEventError) {
287   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
288
289   librbd::ImageCtx *ictx;
290   ASSERT_EQ(0, open_image(m_image_name, &ictx));
291
292   MockTestImageCtx mock_image_ctx(*ictx);
293   ::journal::MockJournaler mock_journaler;
294   MockOpenRequest mock_open_request;
295
296   expect_op_work_queue(mock_image_ctx);
297
298   InSequence seq;
299   expect_construct_journaler(mock_journaler);
300   expect_open_journaler(mock_image_ctx, mock_open_request, 0);
301   expect_allocate_tag(mock_journaler,
302                       {Journal<>::ORPHAN_MIRROR_UUID, true, 567, 1}, 0);
303
304   ::journal::MockFuture mock_future;
305   expect_start_append(mock_journaler);
306   expect_append_journaler(mock_journaler);
307   expect_future_flush(mock_future, 0);
308   expect_future_committed(mock_journaler);
309   expect_flush_commit_position(mock_journaler, -EINVAL);
310   expect_stop_append(mock_journaler, 0);
311
312   expect_shut_down_journaler(mock_journaler, 0);
313
314   C_SaferCond ctx;
315   auto req = MockPromoteRequest::create(&mock_image_ctx, false, &ctx);
316   req->send();
317   ASSERT_EQ(-EINVAL, ctx.wait());
318 }
319
320 TEST_F(TestMockJournalPromoteRequest, ShutDownError) {
321   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
322
323   librbd::ImageCtx *ictx;
324   ASSERT_EQ(0, open_image(m_image_name, &ictx));
325
326   MockTestImageCtx mock_image_ctx(*ictx);
327   ::journal::MockJournaler mock_journaler;
328   MockOpenRequest mock_open_request;
329
330   expect_op_work_queue(mock_image_ctx);
331
332   InSequence seq;
333   expect_construct_journaler(mock_journaler);
334   expect_open_journaler(mock_image_ctx, mock_open_request, 0);
335   expect_allocate_tag(mock_journaler,
336                       {Journal<>::LOCAL_MIRROR_UUID, true, 567, 0}, 0);
337
338   ::journal::MockFuture mock_future;
339   expect_start_append(mock_journaler);
340   expect_append_journaler(mock_journaler);
341   expect_future_flush(mock_future, 0);
342   expect_future_committed(mock_journaler);
343   expect_flush_commit_position(mock_journaler, 0);
344   expect_stop_append(mock_journaler, 0);
345
346   expect_shut_down_journaler(mock_journaler, -EINVAL);
347
348   C_SaferCond ctx;
349   auto req = MockPromoteRequest::create(&mock_image_ctx, true, &ctx);
350   req->send();
351   ASSERT_EQ(-EINVAL, ctx.wait());
352 }
353
354 } // namespace journal
355 } // namespace librbd