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