]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/managed_lock/test_mock_AcquireRequest.cc
update sources to v12.2.1
[ceph.git] / 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