1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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>
20 struct Traits
<MockImageCtx
> {
21 typedef librbd::MockImageWatcher Watcher
;
25 namespace managed_lock
{
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"),
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
;
50 MOCK_METHOD0(send
, void());
54 struct GetLockerRequest
<librbd::MockImageCtx
> {
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
;
72 MOCK_METHOD0(send
, void());
75 BreakRequest
<librbd::MockImageCtx
> *BreakRequest
<librbd::MockImageCtx
>::s_instance
= nullptr;
76 GetLockerRequest
<librbd::MockImageCtx
> *GetLockerRequest
<librbd::MockImageCtx
>::s_instance
= nullptr;
78 } // namespace managed_lock
81 // template definitions
82 #include "librbd/managed_lock/AcquireRequest.cc"
83 template class librbd::managed_lock::AcquireRequest
<librbd::MockImageCtx
>;
87 MATCHER_P(IsLockType
, exclusive
, "") {
91 bufferlist::iterator iter
= bl
.begin();
93 return op
.type
== (exclusive
? LOCK_EXCLUSIVE
: LOCK_SHARED
);
96 } // anonymous namespace
99 namespace managed_lock
{
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
;
110 static const std::string
TEST_COOKIE("auto 123");
112 class TestMockManagedLockAcquireRequest
: public TestMockFixture
{
114 typedef AcquireRequest
<MockImageCtx
> MockAcquireRequest
;
115 typedef BreakRequest
<MockImageCtx
> MockBreakRequest
;
116 typedef GetLockerRequest
<MockImageCtx
> MockGetLockerRequest
;
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
));
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
);
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
));
144 TEST_F(TestMockManagedLockAcquireRequest
, SuccessExclusive
) {
146 librbd::ImageCtx
*ictx
;
147 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
149 MockImageCtx
mock_image_ctx(*ictx
);
150 MockGetLockerRequest mock_get_locker_request
;
153 expect_get_locker(mock_image_ctx
, mock_get_locker_request
, {}, 0);
154 expect_lock(mock_image_ctx
, 0);
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
);
161 ASSERT_EQ(0, ctx
.wait());
164 TEST_F(TestMockManagedLockAcquireRequest
, SuccessShared
) {
166 librbd::ImageCtx
*ictx
;
167 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
169 MockImageCtx
mock_image_ctx(*ictx
);
170 MockGetLockerRequest mock_get_locker_request
;
173 expect_get_locker(mock_image_ctx
, mock_get_locker_request
, {}, 0);
174 expect_lock(mock_image_ctx
, 0, false);
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
);
181 ASSERT_EQ(0, ctx
.wait());
184 TEST_F(TestMockManagedLockAcquireRequest
, LockBusy
) {
185 librbd::ImageCtx
*ictx
;
186 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
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
);
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},
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
);
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
);
206 ASSERT_EQ(-ENOENT
, ctx
.wait());
209 TEST_F(TestMockManagedLockAcquireRequest
, GetLockInfoError
) {
210 librbd::ImageCtx
*ictx
;
211 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
213 MockImageCtx
mock_image_ctx(*ictx
);
214 MockGetLockerRequest mock_get_locker_request
;
217 expect_get_locker(mock_image_ctx
, mock_get_locker_request
, {}, -EINVAL
);
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
);
224 ASSERT_EQ(-EINVAL
, ctx
.wait());
227 TEST_F(TestMockManagedLockAcquireRequest
, GetLockInfoEmpty
) {
228 librbd::ImageCtx
*ictx
;
229 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
231 MockImageCtx
mock_image_ctx(*ictx
);
232 MockGetLockerRequest mock_get_locker_request
;
235 expect_get_locker(mock_image_ctx
, mock_get_locker_request
, {}, -ENOENT
);
236 expect_lock(mock_image_ctx
, -EINVAL
);
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
);
243 ASSERT_EQ(-EINVAL
, ctx
.wait());
246 TEST_F(TestMockManagedLockAcquireRequest
, BreakLockError
) {
247 librbd::ImageCtx
*ictx
;
248 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
250 MockImageCtx
mock_image_ctx(*ictx
);
251 MockGetLockerRequest mock_get_locker_request
;
252 MockBreakRequest mock_break_request
;
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},
258 expect_lock(mock_image_ctx
, -EBUSY
);
259 expect_break_lock(mock_image_ctx
, mock_break_request
, -EINVAL
);
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
);
266 ASSERT_EQ(-EINVAL
, ctx
.wait());
269 } // namespace managed_lock
270 } // namespace librbd