]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/managed_lock/test_mock_BreakRequest.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / test / librbd / managed_lock / test_mock_BreakRequest.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/librados_test_stub/MockTestMemIoCtxImpl.h"
8 #include "test/librados_test_stub/MockTestMemRadosClient.h"
9 #include "cls/lock/cls_lock_ops.h"
10 #include "librbd/managed_lock/BreakRequest.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13 #include <arpa/inet.h>
14 #include <list>
15
16 namespace librbd {
17 namespace {
18
19 struct MockTestImageCtx : public librbd::MockImageCtx {
20 MockTestImageCtx(librbd::ImageCtx &image_ctx)
21 : librbd::MockImageCtx(image_ctx) {
22 }
23 };
24
25 } // anonymous namespace
26 } // namespace librbd
27
28 // template definitions
29 #include "librbd/managed_lock/BreakRequest.cc"
30
31 namespace librbd {
32 namespace managed_lock {
33
34 using ::testing::_;
35 using ::testing::DoAll;
36 using ::testing::InSequence;
37 using ::testing::Return;
38 using ::testing::SetArgPointee;
39 using ::testing::StrEq;
40 using ::testing::WithArg;
41
42 class TestMockManagedLockBreakRequest : public TestMockFixture {
43 public:
44 typedef BreakRequest<MockTestImageCtx> MockBreakRequest;
45
46 void expect_list_watchers(MockTestImageCtx &mock_image_ctx, int r,
47 const std::string &address, uint64_t watch_handle) {
48 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
49 list_watchers(mock_image_ctx.header_oid, _));
50 if (r < 0) {
51 expect.WillOnce(Return(r));
52 } else {
53 obj_watch_t watcher;
54 strcpy(watcher.addr, (address + ":0/0").c_str());
55 watcher.cookie = watch_handle;
56
57 std::list<obj_watch_t> watchers;
58 watchers.push_back(watcher);
59
60 expect.WillOnce(DoAll(SetArgPointee<1>(watchers), Return(0)));
61 }
62 }
63
64 void expect_blacklist_add(MockTestImageCtx &mock_image_ctx, int r) {
65 EXPECT_CALL(*get_mock_io_ctx(mock_image_ctx.md_ctx).get_mock_rados_client(),
66 blacklist_add(_, _))
67 .WillOnce(Return(r));
68 }
69
70 void expect_break_lock(MockTestImageCtx &mock_image_ctx, int r) {
71 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
72 exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("break_lock"), _, _, _))
73 .WillOnce(Return(r));
74 }
75
76 void expect_get_instance_id(MockTestImageCtx &mock_image_ctx, uint64_t id) {
77 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), get_instance_id())
78 .WillOnce(Return(id));
79 }
80 };
81
82 TEST_F(TestMockManagedLockBreakRequest, DeadLockOwner) {
83 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
84
85 librbd::ImageCtx *ictx;
86 ASSERT_EQ(0, open_image(m_image_name, &ictx));
87
88 MockTestImageCtx mock_image_ctx(*ictx);
89 expect_op_work_queue(mock_image_ctx);
90
91 InSequence seq;
92 expect_list_watchers(mock_image_ctx, 0, "dead client", 123);
93 expect_blacklist_add(mock_image_ctx, 0);
94 expect_break_lock(mock_image_ctx, 0);
95
96 C_SaferCond ctx;
97 Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123};
98 MockBreakRequest *req = MockBreakRequest::create(
99 mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid,
100 locker, true, 0, false, &ctx);
101 req->send();
102 ASSERT_EQ(0, ctx.wait());
103 }
104
105 TEST_F(TestMockManagedLockBreakRequest, ForceBreak) {
106 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
107
108 librbd::ImageCtx *ictx;
109 ASSERT_EQ(0, open_image(m_image_name, &ictx));
110
111 MockTestImageCtx mock_image_ctx(*ictx);
112 expect_op_work_queue(mock_image_ctx);
113
114 InSequence seq;
115 expect_list_watchers(mock_image_ctx, 0, "1.2.3.4", 123);
116 expect_blacklist_add(mock_image_ctx, 0);
117 expect_break_lock(mock_image_ctx, 0);
118
119 C_SaferCond ctx;
120 Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123};
121 MockBreakRequest *req = MockBreakRequest::create(
122 mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid,
123 locker, true, 0, true, &ctx);
124 req->send();
125 ASSERT_EQ(0, ctx.wait());
126 }
127
128 TEST_F(TestMockManagedLockBreakRequest, GetWatchersError) {
129 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
130
131 librbd::ImageCtx *ictx;
132 ASSERT_EQ(0, open_image(m_image_name, &ictx));
133
134 MockTestImageCtx mock_image_ctx(*ictx);
135 expect_op_work_queue(mock_image_ctx);
136
137 InSequence seq;
138 expect_list_watchers(mock_image_ctx, -EINVAL, "dead client", 123);
139
140 C_SaferCond ctx;
141 Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123};
142 MockBreakRequest *req = MockBreakRequest::create(
143 mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid,
144 locker, true, 0, false, &ctx);
145 req->send();
146 ASSERT_EQ(-EINVAL, ctx.wait());
147 }
148
149 TEST_F(TestMockManagedLockBreakRequest, GetWatchersAlive) {
150 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
151
152 librbd::ImageCtx *ictx;
153 ASSERT_EQ(0, open_image(m_image_name, &ictx));
154
155 MockTestImageCtx mock_image_ctx(*ictx);
156 expect_op_work_queue(mock_image_ctx);
157
158 InSequence seq;
159 expect_list_watchers(mock_image_ctx, 0, "1.2.3.4", 123);
160
161 C_SaferCond ctx;
162 Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123};
163 MockBreakRequest *req = MockBreakRequest::create(
164 mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid,
165 locker, true, 0, false, &ctx);
166 req->send();
167 ASSERT_EQ(-EAGAIN, ctx.wait());
168 }
169
170 TEST_F(TestMockManagedLockBreakRequest, BlacklistDisabled) {
171 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
172
173 librbd::ImageCtx *ictx;
174 ASSERT_EQ(0, open_image(m_image_name, &ictx));
175
176 MockTestImageCtx mock_image_ctx(*ictx);
177 expect_op_work_queue(mock_image_ctx);
178
179 InSequence seq;
180 expect_list_watchers(mock_image_ctx, 0, "dead client", 123);
181 expect_break_lock(mock_image_ctx, 0);
182
183 C_SaferCond ctx;
184 Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123};
185 MockBreakRequest *req = MockBreakRequest::create(
186 mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid,
187 locker, false, 0, false, &ctx);
188 req->send();
189 ASSERT_EQ(0, ctx.wait());
190 }
191
192 TEST_F(TestMockManagedLockBreakRequest, BlacklistSelf) {
193 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
194
195 librbd::ImageCtx *ictx;
196 ASSERT_EQ(0, open_image(m_image_name, &ictx));
197
198 MockTestImageCtx mock_image_ctx(*ictx);
199 expect_op_work_queue(mock_image_ctx);
200
201 InSequence seq;
202 expect_list_watchers(mock_image_ctx, 0, "dead client", 456);
203 expect_get_instance_id(mock_image_ctx, 456);
204
205 C_SaferCond ctx;
206 Locker locker{entity_name_t::CLIENT(456), "auto 123", "1.2.3.4:0/0", 123};
207 MockBreakRequest *req = MockBreakRequest::create(
208 mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid,
209 locker, true, 0, false, &ctx);
210 req->send();
211 ASSERT_EQ(-EINVAL, ctx.wait());
212 }
213
214 TEST_F(TestMockManagedLockBreakRequest, BlacklistError) {
215 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
216
217 librbd::ImageCtx *ictx;
218 ASSERT_EQ(0, open_image(m_image_name, &ictx));
219
220 MockTestImageCtx mock_image_ctx(*ictx);
221 expect_op_work_queue(mock_image_ctx);
222
223 InSequence seq;
224 expect_list_watchers(mock_image_ctx, 0, "dead client", 123);
225 expect_blacklist_add(mock_image_ctx, -EINVAL);
226
227 C_SaferCond ctx;
228 Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123};
229 MockBreakRequest *req = MockBreakRequest::create(
230 mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid,
231 locker, true, 0, false, &ctx);
232 req->send();
233 ASSERT_EQ(-EINVAL, ctx.wait());
234 }
235
236 TEST_F(TestMockManagedLockBreakRequest, BreakLockMissing) {
237 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
238
239 librbd::ImageCtx *ictx;
240 ASSERT_EQ(0, open_image(m_image_name, &ictx));
241
242 MockTestImageCtx mock_image_ctx(*ictx);
243 expect_op_work_queue(mock_image_ctx);
244
245 InSequence seq;
246 expect_list_watchers(mock_image_ctx, 0, "dead client", 123);
247 expect_blacklist_add(mock_image_ctx, 0);
248 expect_break_lock(mock_image_ctx, -ENOENT);
249
250 C_SaferCond ctx;
251 Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123};
252 MockBreakRequest *req = MockBreakRequest::create(
253 mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid,
254 locker, true, 0, false, &ctx);
255 req->send();
256 ASSERT_EQ(0, ctx.wait());
257 }
258
259 TEST_F(TestMockManagedLockBreakRequest, BreakLockError) {
260 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
261
262 librbd::ImageCtx *ictx;
263 ASSERT_EQ(0, open_image(m_image_name, &ictx));
264
265 MockTestImageCtx mock_image_ctx(*ictx);
266 expect_op_work_queue(mock_image_ctx);
267
268 InSequence seq;
269 expect_list_watchers(mock_image_ctx, 0, "dead client", 123);
270 expect_blacklist_add(mock_image_ctx, 0);
271 expect_break_lock(mock_image_ctx, -EINVAL);
272
273 C_SaferCond ctx;
274 Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123};
275 MockBreakRequest *req = MockBreakRequest::create(
276 mock_image_ctx.md_ctx, ictx->op_work_queue, mock_image_ctx.header_oid,
277 locker, true, 0, false, &ctx);
278 req->send();
279 ASSERT_EQ(-EINVAL, ctx.wait());
280 }
281
282 } // namespace managed_lock
283 } // namespace librbd
284