Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / librbd / exclusive_lock / test_mock_PostAcquireRequest.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/MockImageState.h"
8 #include "test/librbd/mock/MockJournal.h"
9 #include "test/librbd/mock/MockJournalPolicy.h"
10 #include "test/librbd/mock/MockObjectMap.h"
11 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
12 #include "test/librados_test_stub/MockTestMemRadosClient.h"
13 #include "librbd/exclusive_lock/PostAcquireRequest.h"
14 #include "librbd/image/RefreshRequest.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
17 #include <arpa/inet.h>
18 #include <list>
19
20 namespace librbd {
21 namespace {
22
23 struct MockTestImageCtx : public librbd::MockImageCtx {
24   MockTestImageCtx(librbd::ImageCtx &image_ctx)
25     : librbd::MockImageCtx(image_ctx) {
26   }
27 };
28
29 inline ImageCtx &get_image_ctx(MockTestImageCtx &image_ctx) {
30   return *(image_ctx.image_ctx);
31 }
32
33 } // anonymous namespace
34
35 namespace image {
36
37 template<>
38 struct RefreshRequest<librbd::MockTestImageCtx> {
39   static RefreshRequest *s_instance;
40   Context *on_finish;
41
42   static RefreshRequest *create(librbd::MockTestImageCtx &image_ctx,
43                                 bool acquire_lock_refresh,
44                                 bool skip_open_parent, Context *on_finish) {
45     EXPECT_TRUE(acquire_lock_refresh);
46     assert(s_instance != nullptr);
47     s_instance->on_finish = on_finish;
48     return s_instance;
49   }
50
51   RefreshRequest() {
52     s_instance = this;
53   }
54   MOCK_METHOD0(send, void());
55 };
56
57 RefreshRequest<librbd::MockTestImageCtx> *RefreshRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
58
59 } // namespace image
60 } // namespace librbd
61
62 // template definitions
63 #include "librbd/Journal.cc"
64
65 #include "librbd/exclusive_lock/PostAcquireRequest.cc"
66 template class librbd::exclusive_lock::PostAcquireRequest<librbd::MockTestImageCtx>;
67
68 ACTION_P3(FinishRequest2, request, r, mock) {
69   mock->image_ctx->op_work_queue->queue(request->on_finish, r);
70 }
71
72
73 namespace librbd {
74 namespace exclusive_lock {
75
76 using ::testing::_;
77 using ::testing::DoAll;
78 using ::testing::InSequence;
79 using ::testing::Invoke;
80 using ::testing::Return;
81 using ::testing::SetArgPointee;
82 using ::testing::StrEq;
83 using ::testing::WithArg;
84
85 static const std::string TEST_COOKIE("auto 123");
86
87 class TestMockExclusiveLockPostAcquireRequest : public TestMockFixture {
88 public:
89   typedef PostAcquireRequest<MockTestImageCtx> MockPostAcquireRequest;
90   typedef librbd::image::RefreshRequest<MockTestImageCtx> MockRefreshRequest;
91
92   void expect_test_features(MockTestImageCtx &mock_image_ctx, uint64_t features,
93                             bool enabled) {
94     EXPECT_CALL(mock_image_ctx, test_features(features))
95                   .WillOnce(Return(enabled));
96   }
97
98   void expect_test_features(MockTestImageCtx &mock_image_ctx, uint64_t features,
99                             RWLock &lock, bool enabled) {
100     EXPECT_CALL(mock_image_ctx, test_features(features, _))
101                   .WillOnce(Return(enabled));
102   }
103
104   void expect_is_refresh_required(MockTestImageCtx &mock_image_ctx, bool required) {
105     EXPECT_CALL(*mock_image_ctx.state, is_refresh_required())
106       .WillOnce(Return(required));
107   }
108
109   void expect_refresh(MockTestImageCtx &mock_image_ctx,
110                       MockRefreshRequest &mock_refresh_request, int r) {
111     EXPECT_CALL(mock_refresh_request, send())
112                   .WillOnce(FinishRequest2(&mock_refresh_request, r,
113                                            &mock_image_ctx));
114   }
115
116   void expect_create_object_map(MockTestImageCtx &mock_image_ctx,
117                                 MockObjectMap *mock_object_map) {
118     EXPECT_CALL(mock_image_ctx, create_object_map(_))
119                   .WillOnce(Return(mock_object_map));
120   }
121
122   void expect_open_object_map(MockTestImageCtx &mock_image_ctx,
123                               MockObjectMap &mock_object_map, int r) {
124     EXPECT_CALL(mock_object_map, open(_))
125                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
126   }
127
128   void expect_close_object_map(MockTestImageCtx &mock_image_ctx,
129                               MockObjectMap &mock_object_map) {
130     EXPECT_CALL(mock_object_map, close(_))
131                   .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
132   }
133
134   void expect_create_journal(MockTestImageCtx &mock_image_ctx,
135                              MockJournal *mock_journal) {
136     EXPECT_CALL(mock_image_ctx, create_journal())
137                   .WillOnce(Return(mock_journal));
138   }
139
140   void expect_open_journal(MockTestImageCtx &mock_image_ctx,
141                            MockJournal &mock_journal, int r) {
142     EXPECT_CALL(mock_journal, open(_))
143                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
144   }
145
146   void expect_close_journal(MockTestImageCtx &mock_image_ctx,
147                             MockJournal &mock_journal) {
148     EXPECT_CALL(mock_journal, close(_))
149                   .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
150   }
151
152   void expect_get_journal_policy(MockTestImageCtx &mock_image_ctx,
153                                  MockJournalPolicy &mock_journal_policy) {
154     EXPECT_CALL(mock_image_ctx, get_journal_policy())
155                   .WillOnce(Return(&mock_journal_policy));
156   }
157
158   void expect_journal_disabled(MockJournalPolicy &mock_journal_policy,
159                                bool disabled) {
160     EXPECT_CALL(mock_journal_policy, journal_disabled())
161       .WillOnce(Return(disabled));
162   }
163
164   void expect_allocate_journal_tag(MockTestImageCtx &mock_image_ctx,
165                                    MockJournalPolicy &mock_journal_policy,
166                                    int r) {
167     EXPECT_CALL(mock_journal_policy, allocate_tag_on_lock(_))
168                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
169   }
170
171   void expect_handle_prepare_lock_complete(MockTestImageCtx &mock_image_ctx) {
172     EXPECT_CALL(*mock_image_ctx.state, handle_prepare_lock_complete());
173   }
174
175 };
176
177 TEST_F(TestMockExclusiveLockPostAcquireRequest, Success) {
178   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
179
180   librbd::ImageCtx *ictx;
181   ASSERT_EQ(0, open_image(m_image_name, &ictx));
182
183   MockTestImageCtx mock_image_ctx(*ictx);
184   expect_op_work_queue(mock_image_ctx);
185
186   InSequence seq;
187   expect_is_refresh_required(mock_image_ctx, false);
188
189   MockObjectMap mock_object_map;
190   expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
191   expect_create_object_map(mock_image_ctx, &mock_object_map);
192   expect_open_object_map(mock_image_ctx, mock_object_map, 0);
193
194   MockJournal mock_journal;
195   MockJournalPolicy mock_journal_policy;
196   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
197                        mock_image_ctx.snap_lock, true);
198   expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
199   expect_journal_disabled(mock_journal_policy, false);
200   expect_create_journal(mock_image_ctx, &mock_journal);
201   expect_handle_prepare_lock_complete(mock_image_ctx);
202   expect_open_journal(mock_image_ctx, mock_journal, 0);
203   expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
204   expect_allocate_journal_tag(mock_image_ctx, mock_journal_policy, 0);
205
206   C_SaferCond acquire_ctx;
207   C_SaferCond ctx;
208   MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
209                                                                &acquire_ctx,
210                                                                &ctx);
211   req->send();
212   ASSERT_EQ(0, acquire_ctx.wait());
213   ASSERT_EQ(0, ctx.wait());
214  }
215
216 TEST_F(TestMockExclusiveLockPostAcquireRequest, SuccessRefresh) {
217   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
218
219   librbd::ImageCtx *ictx;
220   ASSERT_EQ(0, open_image(m_image_name, &ictx));
221
222   MockTestImageCtx mock_image_ctx(*ictx);
223   MockRefreshRequest mock_refresh_request;
224   expect_op_work_queue(mock_image_ctx);
225
226   InSequence seq;
227   expect_is_refresh_required(mock_image_ctx, true);
228   expect_refresh(mock_image_ctx, mock_refresh_request, 0);
229
230   MockObjectMap mock_object_map;
231   expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
232   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
233                        mock_image_ctx.snap_lock, false);
234   expect_handle_prepare_lock_complete(mock_image_ctx);
235
236   C_SaferCond acquire_ctx;
237   C_SaferCond ctx;
238   MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
239                                                                &acquire_ctx,
240                                                                &ctx);
241   req->send();
242   ASSERT_EQ(0, acquire_ctx.wait());
243   ASSERT_EQ(0, ctx.wait());
244 }
245
246 TEST_F(TestMockExclusiveLockPostAcquireRequest, SuccessJournalDisabled) {
247   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
248
249   librbd::ImageCtx *ictx;
250   ASSERT_EQ(0, open_image(m_image_name, &ictx));
251
252   MockTestImageCtx mock_image_ctx(*ictx);
253   expect_op_work_queue(mock_image_ctx);
254
255   InSequence seq;
256   expect_is_refresh_required(mock_image_ctx, false);
257
258   MockObjectMap mock_object_map;
259   expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
260   expect_create_object_map(mock_image_ctx, &mock_object_map);
261   expect_open_object_map(mock_image_ctx, mock_object_map, 0);
262
263   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
264                        mock_image_ctx.snap_lock, false);
265   expect_handle_prepare_lock_complete(mock_image_ctx);
266
267   C_SaferCond acquire_ctx;
268   C_SaferCond ctx;
269   MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
270                                                                &acquire_ctx,
271                                                                &ctx);
272   req->send();
273   ASSERT_EQ(0, acquire_ctx.wait());
274   ASSERT_EQ(0, ctx.wait());
275 }
276
277 TEST_F(TestMockExclusiveLockPostAcquireRequest, SuccessObjectMapDisabled) {
278   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
279
280   librbd::ImageCtx *ictx;
281   ASSERT_EQ(0, open_image(m_image_name, &ictx));
282
283   MockTestImageCtx mock_image_ctx(*ictx);
284   expect_op_work_queue(mock_image_ctx);
285
286   InSequence seq;
287   expect_is_refresh_required(mock_image_ctx, false);
288
289   expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
290
291   MockJournal mock_journal;
292   MockJournalPolicy mock_journal_policy;
293   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
294                        mock_image_ctx.snap_lock, true);
295   expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
296   expect_journal_disabled(mock_journal_policy, false);
297   expect_create_journal(mock_image_ctx, &mock_journal);
298   expect_handle_prepare_lock_complete(mock_image_ctx);
299   expect_open_journal(mock_image_ctx, mock_journal, 0);
300   expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
301   expect_allocate_journal_tag(mock_image_ctx, mock_journal_policy, 0);
302
303   C_SaferCond acquire_ctx;
304   C_SaferCond ctx;
305   MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
306                                                                &acquire_ctx,
307                                                                &ctx);
308   req->send();
309   ASSERT_EQ(0, acquire_ctx.wait());
310   ASSERT_EQ(0, ctx.wait());
311 }
312
313 TEST_F(TestMockExclusiveLockPostAcquireRequest, RefreshError) {
314   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
315
316   librbd::ImageCtx *ictx;
317   ASSERT_EQ(0, open_image(m_image_name, &ictx));
318
319   MockTestImageCtx mock_image_ctx(*ictx);
320   MockRefreshRequest mock_refresh_request;
321   expect_op_work_queue(mock_image_ctx);
322
323   InSequence seq;
324   expect_is_refresh_required(mock_image_ctx, true);
325   expect_refresh(mock_image_ctx, mock_refresh_request, -EINVAL);
326   expect_handle_prepare_lock_complete(mock_image_ctx);
327
328   C_SaferCond *acquire_ctx = new C_SaferCond();
329   C_SaferCond ctx;
330   MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
331                                                                acquire_ctx,
332                                                                &ctx);
333   req->send();
334   ASSERT_EQ(-EINVAL, ctx.wait());
335 }
336
337 TEST_F(TestMockExclusiveLockPostAcquireRequest, RefreshLockDisabled) {
338   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
339
340   librbd::ImageCtx *ictx;
341   ASSERT_EQ(0, open_image(m_image_name, &ictx));
342
343   MockTestImageCtx mock_image_ctx(*ictx);
344   MockRefreshRequest mock_refresh_request;
345   expect_op_work_queue(mock_image_ctx);
346
347   InSequence seq;
348   expect_is_refresh_required(mock_image_ctx, true);
349   expect_refresh(mock_image_ctx, mock_refresh_request, -ERESTART);
350
351   MockObjectMap mock_object_map;
352   expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
353   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
354                        mock_image_ctx.snap_lock, false);
355   expect_handle_prepare_lock_complete(mock_image_ctx);
356
357   C_SaferCond acquire_ctx;
358   C_SaferCond ctx;
359   MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
360                                                                &acquire_ctx,
361                                                                &ctx);
362   req->send();
363   ASSERT_EQ(0, acquire_ctx.wait());
364   ASSERT_EQ(0, ctx.wait());
365 }
366
367 TEST_F(TestMockExclusiveLockPostAcquireRequest, JournalError) {
368   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
369
370   librbd::ImageCtx *ictx;
371   ASSERT_EQ(0, open_image(m_image_name, &ictx));
372
373   MockTestImageCtx mock_image_ctx(*ictx);
374   expect_op_work_queue(mock_image_ctx);
375
376   InSequence seq;
377   expect_is_refresh_required(mock_image_ctx, false);
378
379   MockObjectMap *mock_object_map = new MockObjectMap();
380   expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
381   expect_create_object_map(mock_image_ctx, mock_object_map);
382   expect_open_object_map(mock_image_ctx, *mock_object_map, 0);
383
384   MockJournal *mock_journal = new MockJournal();
385   MockJournalPolicy mock_journal_policy;
386   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
387                        mock_image_ctx.snap_lock, true);
388   expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
389   expect_journal_disabled(mock_journal_policy, false);
390   expect_create_journal(mock_image_ctx, mock_journal);
391   expect_handle_prepare_lock_complete(mock_image_ctx);
392   expect_open_journal(mock_image_ctx, *mock_journal, -EINVAL);
393   expect_close_journal(mock_image_ctx, *mock_journal);
394   expect_close_object_map(mock_image_ctx, *mock_object_map);
395
396   C_SaferCond acquire_ctx;
397   C_SaferCond ctx;
398   MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
399                                                                &acquire_ctx,
400                                                                &ctx);
401   req->send();
402   ASSERT_EQ(-EINVAL, ctx.wait());
403 }
404
405 TEST_F(TestMockExclusiveLockPostAcquireRequest, AllocateJournalTagError) {
406   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
407
408   librbd::ImageCtx *ictx;
409   ASSERT_EQ(0, open_image(m_image_name, &ictx));
410
411   MockTestImageCtx mock_image_ctx(*ictx);
412   expect_op_work_queue(mock_image_ctx);
413
414   InSequence seq;
415   expect_is_refresh_required(mock_image_ctx, false);
416
417   MockObjectMap *mock_object_map = new MockObjectMap();
418   expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
419   expect_create_object_map(mock_image_ctx, mock_object_map);
420   expect_open_object_map(mock_image_ctx, *mock_object_map, 0);
421
422   MockJournal *mock_journal = new MockJournal();
423   MockJournalPolicy mock_journal_policy;
424   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
425                        mock_image_ctx.snap_lock, true);
426   expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
427   expect_journal_disabled(mock_journal_policy, false);
428   expect_create_journal(mock_image_ctx, mock_journal);
429   expect_handle_prepare_lock_complete(mock_image_ctx);
430   expect_open_journal(mock_image_ctx, *mock_journal, 0);
431   expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
432   expect_allocate_journal_tag(mock_image_ctx, mock_journal_policy, -EPERM);
433   expect_close_journal(mock_image_ctx, *mock_journal);
434   expect_close_object_map(mock_image_ctx, *mock_object_map);
435
436   C_SaferCond acquire_ctx;
437   C_SaferCond ctx;
438   MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
439                                                                &acquire_ctx,
440                                                                &ctx);
441   req->send();
442   ASSERT_EQ(-EPERM, ctx.wait());
443 }
444
445 TEST_F(TestMockExclusiveLockPostAcquireRequest, OpenObjectMapError) {
446   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
447
448   librbd::ImageCtx *ictx;
449   ASSERT_EQ(0, open_image(m_image_name, &ictx));
450
451   MockTestImageCtx mock_image_ctx(*ictx);
452   expect_op_work_queue(mock_image_ctx);
453
454   InSequence seq;
455   expect_is_refresh_required(mock_image_ctx, false);
456
457   MockObjectMap *mock_object_map = new MockObjectMap();
458   expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
459   expect_create_object_map(mock_image_ctx, mock_object_map);
460   expect_open_object_map(mock_image_ctx, *mock_object_map, -EFBIG);
461
462   MockJournal mock_journal;
463   MockJournalPolicy mock_journal_policy;
464   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
465                        mock_image_ctx.snap_lock, true);
466   expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
467   expect_journal_disabled(mock_journal_policy, false);
468   expect_create_journal(mock_image_ctx, &mock_journal);
469   expect_handle_prepare_lock_complete(mock_image_ctx);
470   expect_open_journal(mock_image_ctx, mock_journal, 0);
471   expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
472   expect_allocate_journal_tag(mock_image_ctx, mock_journal_policy, 0);
473
474   C_SaferCond acquire_ctx;
475   C_SaferCond ctx;
476   MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
477                                                                &acquire_ctx,
478                                                                &ctx);
479   req->send();
480   ASSERT_EQ(0, acquire_ctx.wait());
481   ASSERT_EQ(0, ctx.wait());
482   ASSERT_EQ(nullptr, mock_image_ctx.object_map);
483 }
484
485 } // namespace exclusive_lock
486 } // namespace librbd