Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / librbd / managed_lock / test_mock_AcquireRequest.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/librados_test_stub/MockTestMemIoCtxImpl.h"
7 #include "test/librados_test_stub/MockTestMemRadosClient.h"
8 #include "cls/lock/cls_lock_ops.h"
9 #include "librbd/managed_lock/AcquireRequest.h"
10 #include "librbd/managed_lock/BreakRequest.h"
11 #include "librbd/managed_lock/GetLockerRequest.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14 #include <arpa/inet.h>
15 #include <list>
16
17 namespace librbd {
18 namespace watcher {
19 template <>
20 struct Traits<MockImageCtx> {
21   typedef librbd::MockImageWatcher Watcher;
22 };
23 }
24
25 namespace managed_lock {
26
27 template<>
28 struct BreakRequest<librbd::MockImageCtx> {
29   Context *on_finish = nullptr;
30   static BreakRequest *s_instance;
31   static BreakRequest* create(librados::IoCtx& ioctx, ContextWQ *work_queue,
32                               const std::string& oid, const Locker &locker,
33                               bool exclusive, bool blacklist_locker,
34                               uint32_t blacklist_expire_seconds,
35                               bool force_break_lock, Context *on_finish) {
36     CephContext *cct = reinterpret_cast<CephContext *>(ioctx.cct());
37     EXPECT_EQ(cct->_conf->get_val<bool>("rbd_blacklist_on_break_lock"),
38               blacklist_locker);
39     EXPECT_EQ(cct->_conf->get_val<int64_t>("rbd_blacklist_expire_seconds"),
40               (int)blacklist_expire_seconds);
41     EXPECT_FALSE(force_break_lock);
42     assert(s_instance != nullptr);
43     s_instance->on_finish = on_finish;
44     return s_instance;
45   }
46
47   BreakRequest() {
48     s_instance = this;
49   }
50   MOCK_METHOD0(send, void());
51 };
52
53 template <>
54 struct GetLockerRequest<librbd::MockImageCtx> {
55   Locker *locker;
56   Context *on_finish;
57
58   static GetLockerRequest *s_instance;
59   static GetLockerRequest* create(librados::IoCtx& ioctx,
60                                   const std::string& oid, bool exclusive,
61                                   Locker *locker, Context *on_finish) {
62     assert(s_instance != nullptr);
63     s_instance->locker = locker;
64     s_instance->on_finish = on_finish;
65     return s_instance;
66   }
67
68   GetLockerRequest() {
69     s_instance = this;
70   }
71
72   MOCK_METHOD0(send, void());
73 };
74
75 BreakRequest<librbd::MockImageCtx> *BreakRequest<librbd::MockImageCtx>::s_instance = nullptr;
76 GetLockerRequest<librbd::MockImageCtx> *GetLockerRequest<librbd::MockImageCtx>::s_instance = nullptr;
77
78 } // namespace managed_lock
79 } // namespace librbd
80
81 // template definitions
82 #include "librbd/managed_lock/AcquireRequest.cc"
83 template class librbd::managed_lock::AcquireRequest<librbd::MockImageCtx>;
84
85 namespace {
86
87 MATCHER_P(IsLockType, exclusive, "") {
88   cls_lock_lock_op op;
89   bufferlist bl;
90   bl.share(arg);
91   bufferlist::iterator iter = bl.begin();
92   ::decode(op, iter);
93   return op.type == (exclusive ? LOCK_EXCLUSIVE : LOCK_SHARED);
94 }
95
96 } // anonymous namespace
97
98 namespace librbd {
99 namespace managed_lock {
100
101 using ::testing::_;
102 using ::testing::DoAll;
103 using ::testing::InSequence;
104 using ::testing::Invoke;
105 using ::testing::Return;
106 using ::testing::SetArgPointee;
107 using ::testing::StrEq;
108 using ::testing::WithArg;
109
110 static const std::string TEST_COOKIE("auto 123");
111
112 class TestMockManagedLockAcquireRequest : public TestMockFixture {
113 public:
114   typedef AcquireRequest<MockImageCtx> MockAcquireRequest;
115   typedef BreakRequest<MockImageCtx> MockBreakRequest;
116   typedef GetLockerRequest<MockImageCtx> MockGetLockerRequest;
117
118   void expect_lock(MockImageCtx &mock_image_ctx, int r,
119                              bool exclusive = true) {
120     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
121                 exec(mock_image_ctx.header_oid, _, StrEq("lock"),
122                      StrEq("lock"), IsLockType(exclusive), _, _))
123                   .WillOnce(Return(r));
124   }
125
126   void expect_get_locker(MockImageCtx &mock_image_ctx,
127                          MockGetLockerRequest &mock_get_locker_request,
128                          const Locker &locker, int r) {
129     EXPECT_CALL(mock_get_locker_request, send())
130       .WillOnce(Invoke([&mock_image_ctx, &mock_get_locker_request, locker, r]() {
131           *mock_get_locker_request.locker = locker;
132           mock_image_ctx.image_ctx->op_work_queue->queue(
133             mock_get_locker_request.on_finish, r);
134         }));
135   }
136
137   void expect_break_lock(MockImageCtx &mock_image_ctx,
138                          MockBreakRequest &mock_break_request, int r) {
139     EXPECT_CALL(mock_break_request, send())
140       .WillOnce(FinishRequest(&mock_break_request, r, &mock_image_ctx));
141   }
142 };
143
144 TEST_F(TestMockManagedLockAcquireRequest, SuccessExclusive) {
145
146   librbd::ImageCtx *ictx;
147   ASSERT_EQ(0, open_image(m_image_name, &ictx));
148
149   MockImageCtx mock_image_ctx(*ictx);
150   MockGetLockerRequest mock_get_locker_request;
151
152   InSequence seq;
153   expect_get_locker(mock_image_ctx, mock_get_locker_request, {}, 0);
154   expect_lock(mock_image_ctx, 0);
155
156   C_SaferCond ctx;
157   MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx.md_ctx,
158      mock_image_ctx.image_watcher, ictx->op_work_queue, mock_image_ctx.header_oid,
159      TEST_COOKIE, true, true, 0, &ctx);
160   req->send();
161   ASSERT_EQ(0, ctx.wait());
162 }
163
164 TEST_F(TestMockManagedLockAcquireRequest, SuccessShared) {
165
166   librbd::ImageCtx *ictx;
167   ASSERT_EQ(0, open_image(m_image_name, &ictx));
168
169   MockImageCtx mock_image_ctx(*ictx);
170   MockGetLockerRequest mock_get_locker_request;
171
172   InSequence seq;
173   expect_get_locker(mock_image_ctx, mock_get_locker_request, {}, 0);
174   expect_lock(mock_image_ctx, 0, false);
175
176   C_SaferCond ctx;
177   MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx.md_ctx,
178      mock_image_ctx.image_watcher, ictx->op_work_queue, mock_image_ctx.header_oid,
179      TEST_COOKIE, false, true, 0, &ctx);
180   req->send();
181   ASSERT_EQ(0, ctx.wait());
182 }
183
184 TEST_F(TestMockManagedLockAcquireRequest, LockBusy) {
185   librbd::ImageCtx *ictx;
186   ASSERT_EQ(0, open_image(m_image_name, &ictx));
187
188   MockImageCtx mock_image_ctx(*ictx);
189   MockGetLockerRequest mock_get_locker_request;
190   MockBreakRequest mock_break_request;
191   expect_op_work_queue(mock_image_ctx);
192
193   InSequence seq;
194   expect_get_locker(mock_image_ctx, mock_get_locker_request,
195                     {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123},
196                     0);
197   expect_lock(mock_image_ctx, -EBUSY);
198   expect_break_lock(mock_image_ctx, mock_break_request, 0);
199   expect_lock(mock_image_ctx, -ENOENT);
200
201   C_SaferCond ctx;
202   MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx.md_ctx,
203      mock_image_ctx.image_watcher, ictx->op_work_queue, mock_image_ctx.header_oid,
204      TEST_COOKIE, true, true, 0, &ctx);
205   req->send();
206   ASSERT_EQ(-ENOENT, ctx.wait());
207 }
208
209 TEST_F(TestMockManagedLockAcquireRequest, GetLockInfoError) {
210   librbd::ImageCtx *ictx;
211   ASSERT_EQ(0, open_image(m_image_name, &ictx));
212
213   MockImageCtx mock_image_ctx(*ictx);
214   MockGetLockerRequest mock_get_locker_request;
215
216   InSequence seq;
217   expect_get_locker(mock_image_ctx, mock_get_locker_request, {}, -EINVAL);
218
219   C_SaferCond ctx;
220   MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx.md_ctx,
221      mock_image_ctx.image_watcher, ictx->op_work_queue, mock_image_ctx.header_oid,
222      TEST_COOKIE, true, true, 0, &ctx);
223   req->send();
224   ASSERT_EQ(-EINVAL, ctx.wait());
225 }
226
227 TEST_F(TestMockManagedLockAcquireRequest, GetLockInfoEmpty) {
228   librbd::ImageCtx *ictx;
229   ASSERT_EQ(0, open_image(m_image_name, &ictx));
230
231   MockImageCtx mock_image_ctx(*ictx);
232   MockGetLockerRequest mock_get_locker_request;
233
234   InSequence seq;
235   expect_get_locker(mock_image_ctx, mock_get_locker_request, {}, -ENOENT);
236   expect_lock(mock_image_ctx, -EINVAL);
237
238   C_SaferCond ctx;
239   MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx.md_ctx,
240      mock_image_ctx.image_watcher, ictx->op_work_queue, mock_image_ctx.header_oid,
241      TEST_COOKIE, true, true, 0, &ctx);
242   req->send();
243   ASSERT_EQ(-EINVAL, ctx.wait());
244 }
245
246 TEST_F(TestMockManagedLockAcquireRequest, BreakLockError) {
247   librbd::ImageCtx *ictx;
248   ASSERT_EQ(0, open_image(m_image_name, &ictx));
249
250   MockImageCtx mock_image_ctx(*ictx);
251   MockGetLockerRequest mock_get_locker_request;
252   MockBreakRequest mock_break_request;
253
254   InSequence seq;
255   expect_get_locker(mock_image_ctx, mock_get_locker_request,
256                     {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123},
257                     0);
258   expect_lock(mock_image_ctx, -EBUSY);
259   expect_break_lock(mock_image_ctx, mock_break_request, -EINVAL);
260
261   C_SaferCond ctx;
262   MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx.md_ctx,
263      mock_image_ctx.image_watcher, ictx->op_work_queue, mock_image_ctx.header_oid,
264      TEST_COOKIE, true, true, 0, &ctx);
265   req->send();
266   ASSERT_EQ(-EINVAL, ctx.wait());
267 }
268
269 } // namespace managed_lock
270 } // namespace librbd