]>
Commit | Line | Data |
---|---|---|
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/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" | |
31f18b77 | 11 | #include "librbd/managed_lock/GetLockerRequest.h" |
7c673cae FG |
12 | #include "gmock/gmock.h" |
13 | #include "gtest/gtest.h" | |
14 | #include <arpa/inet.h> | |
15 | #include <list> | |
16 | ||
17 | namespace librbd { | |
18 | namespace { | |
19 | ||
20 | struct MockTestImageCtx : public librbd::MockImageCtx { | |
21 | MockTestImageCtx(librbd::ImageCtx &image_ctx) | |
22 | : librbd::MockImageCtx(image_ctx) { | |
23 | } | |
24 | }; | |
25 | ||
26 | } // anonymous namespace | |
31f18b77 FG |
27 | |
28 | namespace managed_lock { | |
29 | ||
30 | template <> | |
31 | struct GetLockerRequest<librbd::MockTestImageCtx> { | |
32 | Locker *locker; | |
33 | Context *on_finish = nullptr; | |
34 | static GetLockerRequest *s_instance; | |
35 | static GetLockerRequest* create(librados::IoCtx& ioctx, | |
36 | const std::string& oid, bool exclusive, | |
37 | Locker *locker, Context *on_finish) { | |
11fdf7f2 | 38 | ceph_assert(s_instance != nullptr); |
31f18b77 FG |
39 | s_instance->locker = locker; |
40 | s_instance->on_finish = on_finish; | |
41 | return s_instance; | |
42 | } | |
43 | ||
44 | ||
45 | GetLockerRequest() { | |
46 | s_instance = this; | |
47 | } | |
48 | MOCK_METHOD0(send, void()); | |
49 | }; | |
50 | ||
51 | GetLockerRequest<librbd::MockTestImageCtx> *GetLockerRequest<librbd::MockTestImageCtx>::s_instance = nullptr; | |
52 | ||
53 | } // namespace managed_lock | |
7c673cae FG |
54 | } // namespace librbd |
55 | ||
56 | // template definitions | |
57 | #include "librbd/managed_lock/BreakRequest.cc" | |
58 | ||
59 | namespace librbd { | |
60 | namespace managed_lock { | |
61 | ||
62 | using ::testing::_; | |
63 | using ::testing::DoAll; | |
64 | using ::testing::InSequence; | |
31f18b77 | 65 | using ::testing::Invoke; |
7c673cae FG |
66 | using ::testing::Return; |
67 | using ::testing::SetArgPointee; | |
68 | using ::testing::StrEq; | |
69 | using ::testing::WithArg; | |
70 | ||
71 | class TestMockManagedLockBreakRequest : public TestMockFixture { | |
72 | public: | |
73 | typedef BreakRequest<MockTestImageCtx> MockBreakRequest; | |
31f18b77 | 74 | typedef GetLockerRequest<MockTestImageCtx> MockGetLockerRequest; |
7c673cae FG |
75 | |
76 | void expect_list_watchers(MockTestImageCtx &mock_image_ctx, int r, | |
77 | const std::string &address, uint64_t watch_handle) { | |
78 | auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), | |
79 | list_watchers(mock_image_ctx.header_oid, _)); | |
80 | if (r < 0) { | |
81 | expect.WillOnce(Return(r)); | |
82 | } else { | |
83 | obj_watch_t watcher; | |
9f95a23c TL |
84 | strncpy(watcher.addr, (address + ":0/0").c_str(), sizeof(watcher.addr) - 1); |
85 | watcher.addr[sizeof(watcher.addr) - 1] = '\0'; | |
11fdf7f2 | 86 | watcher.watcher_id = 0; |
7c673cae FG |
87 | watcher.cookie = watch_handle; |
88 | ||
89 | std::list<obj_watch_t> watchers; | |
90 | watchers.push_back(watcher); | |
91 | ||
92 | expect.WillOnce(DoAll(SetArgPointee<1>(watchers), Return(0))); | |
93 | } | |
94 | } | |
95 | ||
31f18b77 FG |
96 | void expect_get_locker(MockImageCtx &mock_image_ctx, |
97 | MockGetLockerRequest &mock_get_locker_request, | |
98 | const Locker &locker, int r) { | |
99 | EXPECT_CALL(mock_get_locker_request, send()) | |
100 | .WillOnce(Invoke([&mock_image_ctx, &mock_get_locker_request, locker, r]() { | |
101 | *mock_get_locker_request.locker = locker; | |
102 | mock_image_ctx.image_ctx->op_work_queue->queue( | |
103 | mock_get_locker_request.on_finish, r); | |
104 | })); | |
105 | } | |
106 | ||
107 | ||
f67539c2 TL |
108 | void expect_blocklist_add(MockTestImageCtx &mock_image_ctx, int r) { |
109 | auto& mock_rados_client = librados::get_mock_rados_client( | |
110 | mock_image_ctx.rados_api); | |
111 | EXPECT_CALL(mock_rados_client, blocklist_add(_, _)).WillOnce(Return(r)); | |
112 | } | |
113 | ||
114 | void expect_wait_for_latest_osd_map(MockTestImageCtx &mock_image_ctx, int r) { | |
115 | auto& mock_rados_client = librados::get_mock_rados_client( | |
116 | mock_image_ctx.rados_api); | |
117 | EXPECT_CALL(mock_rados_client, wait_for_latest_osd_map()) | |
118 | .WillOnce(Return(r)); | |
7c673cae FG |
119 | } |
120 | ||
121 | void expect_break_lock(MockTestImageCtx &mock_image_ctx, int r) { | |
122 | EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), | |
f67539c2 TL |
123 | exec(mock_image_ctx.header_oid, _, StrEq("lock"), |
124 | StrEq("break_lock"), _, _, _, _)) | |
7c673cae FG |
125 | .WillOnce(Return(r)); |
126 | } | |
127 | ||
128 | void expect_get_instance_id(MockTestImageCtx &mock_image_ctx, uint64_t id) { | |
129 | EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), get_instance_id()) | |
130 | .WillOnce(Return(id)); | |
131 | } | |
132 | }; | |
133 | ||
134 | TEST_F(TestMockManagedLockBreakRequest, DeadLockOwner) { | |
135 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); | |
136 | ||
137 | librbd::ImageCtx *ictx; | |
138 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
139 | ||
140 | MockTestImageCtx mock_image_ctx(*ictx); | |
141 | expect_op_work_queue(mock_image_ctx); | |
142 | ||
143 | InSequence seq; | |
144 | expect_list_watchers(mock_image_ctx, 0, "dead client", 123); | |
31f18b77 FG |
145 | |
146 | MockGetLockerRequest mock_get_locker_request; | |
147 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
148 | {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, | |
149 | 0); | |
150 | ||
f67539c2 TL |
151 | expect_blocklist_add(mock_image_ctx, 0); |
152 | expect_wait_for_latest_osd_map(mock_image_ctx, 0); | |
7c673cae FG |
153 | expect_break_lock(mock_image_ctx, 0); |
154 | ||
155 | C_SaferCond ctx; | |
156 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
157 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 158 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 | 159 | locker, true, true, 0, false, &ctx); |
7c673cae FG |
160 | req->send(); |
161 | ASSERT_EQ(0, ctx.wait()); | |
162 | } | |
163 | ||
164 | TEST_F(TestMockManagedLockBreakRequest, ForceBreak) { | |
165 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); | |
166 | ||
167 | librbd::ImageCtx *ictx; | |
168 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
169 | ||
170 | MockTestImageCtx mock_image_ctx(*ictx); | |
171 | expect_op_work_queue(mock_image_ctx); | |
172 | ||
173 | InSequence seq; | |
174 | expect_list_watchers(mock_image_ctx, 0, "1.2.3.4", 123); | |
31f18b77 FG |
175 | |
176 | MockGetLockerRequest mock_get_locker_request; | |
177 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
178 | {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, | |
179 | 0); | |
180 | ||
f67539c2 TL |
181 | expect_blocklist_add(mock_image_ctx, 0); |
182 | expect_wait_for_latest_osd_map(mock_image_ctx, 0); | |
7c673cae FG |
183 | expect_break_lock(mock_image_ctx, 0); |
184 | ||
185 | C_SaferCond ctx; | |
186 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
187 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 188 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 | 189 | locker, true, true, 0, true, &ctx); |
7c673cae FG |
190 | req->send(); |
191 | ASSERT_EQ(0, ctx.wait()); | |
192 | } | |
193 | ||
194 | TEST_F(TestMockManagedLockBreakRequest, GetWatchersError) { | |
195 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); | |
196 | ||
197 | librbd::ImageCtx *ictx; | |
198 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
199 | ||
200 | MockTestImageCtx mock_image_ctx(*ictx); | |
201 | expect_op_work_queue(mock_image_ctx); | |
202 | ||
203 | InSequence seq; | |
204 | expect_list_watchers(mock_image_ctx, -EINVAL, "dead client", 123); | |
205 | ||
206 | C_SaferCond ctx; | |
207 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
208 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 209 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 | 210 | locker, true, true, 0, false, &ctx); |
7c673cae FG |
211 | req->send(); |
212 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
213 | } | |
214 | ||
215 | TEST_F(TestMockManagedLockBreakRequest, GetWatchersAlive) { | |
216 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); | |
217 | ||
218 | librbd::ImageCtx *ictx; | |
219 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
220 | ||
221 | MockTestImageCtx mock_image_ctx(*ictx); | |
222 | expect_op_work_queue(mock_image_ctx); | |
223 | ||
224 | InSequence seq; | |
225 | expect_list_watchers(mock_image_ctx, 0, "1.2.3.4", 123); | |
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( | |
f67539c2 | 230 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 FG |
231 | locker, true, true, 0, false, &ctx); |
232 | req->send(); | |
233 | ASSERT_EQ(-EAGAIN, ctx.wait()); | |
234 | } | |
235 | ||
236 | TEST_F(TestMockManagedLockBreakRequest, GetLockerUpdated) { | |
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 | ||
248 | MockGetLockerRequest mock_get_locker_request; | |
249 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
250 | {entity_name_t::CLIENT(2), "auto 123", "1.2.3.4:0/0", 123}, | |
251 | 0); | |
252 | ||
253 | C_SaferCond ctx; | |
254 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
255 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 256 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 FG |
257 | locker, true, false, 0, false, &ctx); |
258 | req->send(); | |
259 | ASSERT_EQ(-EAGAIN, ctx.wait()); | |
260 | } | |
261 | ||
262 | TEST_F(TestMockManagedLockBreakRequest, GetLockerBusy) { | |
263 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); | |
264 | ||
265 | librbd::ImageCtx *ictx; | |
266 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
267 | ||
268 | MockTestImageCtx mock_image_ctx(*ictx); | |
269 | expect_op_work_queue(mock_image_ctx); | |
270 | ||
271 | InSequence seq; | |
272 | expect_list_watchers(mock_image_ctx, 0, "dead client", 123); | |
273 | ||
274 | MockGetLockerRequest mock_get_locker_request; | |
275 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
276 | {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, | |
277 | -EBUSY); | |
278 | ||
279 | C_SaferCond ctx; | |
280 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
281 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 282 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 | 283 | locker, true, false, 0, false, &ctx); |
7c673cae FG |
284 | req->send(); |
285 | ASSERT_EQ(-EAGAIN, ctx.wait()); | |
286 | } | |
287 | ||
31f18b77 FG |
288 | TEST_F(TestMockManagedLockBreakRequest, GetLockerMissing) { |
289 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); | |
290 | ||
291 | librbd::ImageCtx *ictx; | |
292 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
293 | ||
294 | MockTestImageCtx mock_image_ctx(*ictx); | |
295 | expect_op_work_queue(mock_image_ctx); | |
296 | ||
297 | InSequence seq; | |
298 | expect_list_watchers(mock_image_ctx, 0, "dead client", 123); | |
299 | ||
300 | MockGetLockerRequest mock_get_locker_request; | |
301 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
302 | {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, | |
303 | -ENOENT); | |
304 | ||
305 | C_SaferCond ctx; | |
306 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
307 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 308 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 FG |
309 | locker, true, false, 0, false, &ctx); |
310 | req->send(); | |
311 | ASSERT_EQ(0, ctx.wait()); | |
312 | } | |
313 | ||
314 | TEST_F(TestMockManagedLockBreakRequest, GetLockerError) { | |
315 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); | |
316 | ||
317 | librbd::ImageCtx *ictx; | |
318 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
319 | ||
320 | MockTestImageCtx mock_image_ctx(*ictx); | |
321 | expect_op_work_queue(mock_image_ctx); | |
322 | ||
323 | InSequence seq; | |
324 | expect_list_watchers(mock_image_ctx, 0, "dead client", 123); | |
325 | ||
326 | MockGetLockerRequest mock_get_locker_request; | |
327 | expect_get_locker(mock_image_ctx, mock_get_locker_request, {}, -EINVAL); | |
328 | ||
329 | C_SaferCond ctx; | |
330 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
331 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 332 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 FG |
333 | locker, true, false, 0, false, &ctx); |
334 | req->send(); | |
335 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
336 | } | |
337 | ||
f67539c2 | 338 | TEST_F(TestMockManagedLockBreakRequest, BlocklistDisabled) { |
7c673cae FG |
339 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); |
340 | ||
341 | librbd::ImageCtx *ictx; | |
342 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
343 | ||
344 | MockTestImageCtx mock_image_ctx(*ictx); | |
345 | expect_op_work_queue(mock_image_ctx); | |
346 | ||
347 | InSequence seq; | |
348 | expect_list_watchers(mock_image_ctx, 0, "dead client", 123); | |
31f18b77 FG |
349 | |
350 | MockGetLockerRequest mock_get_locker_request; | |
351 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
352 | {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, | |
353 | 0); | |
354 | ||
7c673cae FG |
355 | expect_break_lock(mock_image_ctx, 0); |
356 | ||
357 | C_SaferCond ctx; | |
358 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
359 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 360 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 | 361 | locker, true, false, 0, false, &ctx); |
7c673cae FG |
362 | req->send(); |
363 | ASSERT_EQ(0, ctx.wait()); | |
364 | } | |
365 | ||
f67539c2 | 366 | TEST_F(TestMockManagedLockBreakRequest, BlocklistSelf) { |
7c673cae FG |
367 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); |
368 | ||
369 | librbd::ImageCtx *ictx; | |
370 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
371 | ||
372 | MockTestImageCtx mock_image_ctx(*ictx); | |
373 | expect_op_work_queue(mock_image_ctx); | |
374 | ||
375 | InSequence seq; | |
376 | expect_list_watchers(mock_image_ctx, 0, "dead client", 456); | |
31f18b77 FG |
377 | |
378 | MockGetLockerRequest mock_get_locker_request; | |
379 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
380 | {entity_name_t::CLIENT(456), "auto 123", "1.2.3.4:0/0", | |
381 | 123}, 0); | |
382 | ||
7c673cae FG |
383 | expect_get_instance_id(mock_image_ctx, 456); |
384 | ||
385 | C_SaferCond ctx; | |
386 | Locker locker{entity_name_t::CLIENT(456), "auto 123", "1.2.3.4:0/0", 123}; | |
387 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 388 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 | 389 | locker, true, true, 0, false, &ctx); |
7c673cae FG |
390 | req->send(); |
391 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
392 | } | |
393 | ||
f67539c2 | 394 | TEST_F(TestMockManagedLockBreakRequest, BlocklistError) { |
7c673cae FG |
395 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); |
396 | ||
397 | librbd::ImageCtx *ictx; | |
398 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
399 | ||
400 | MockTestImageCtx mock_image_ctx(*ictx); | |
401 | expect_op_work_queue(mock_image_ctx); | |
402 | ||
403 | InSequence seq; | |
404 | expect_list_watchers(mock_image_ctx, 0, "dead client", 123); | |
31f18b77 FG |
405 | |
406 | MockGetLockerRequest mock_get_locker_request; | |
407 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
408 | {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, | |
409 | 0); | |
410 | ||
f67539c2 | 411 | expect_blocklist_add(mock_image_ctx, -EINVAL); |
7c673cae FG |
412 | |
413 | C_SaferCond ctx; | |
414 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
415 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 416 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 | 417 | locker, true, true, 0, false, &ctx); |
7c673cae FG |
418 | req->send(); |
419 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
420 | } | |
421 | ||
422 | TEST_F(TestMockManagedLockBreakRequest, BreakLockMissing) { | |
423 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); | |
424 | ||
425 | librbd::ImageCtx *ictx; | |
426 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
427 | ||
428 | MockTestImageCtx mock_image_ctx(*ictx); | |
429 | expect_op_work_queue(mock_image_ctx); | |
430 | ||
431 | InSequence seq; | |
432 | expect_list_watchers(mock_image_ctx, 0, "dead client", 123); | |
31f18b77 FG |
433 | |
434 | MockGetLockerRequest mock_get_locker_request; | |
435 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
436 | {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, | |
437 | 0); | |
438 | ||
f67539c2 TL |
439 | expect_blocklist_add(mock_image_ctx, 0); |
440 | expect_wait_for_latest_osd_map(mock_image_ctx, 0); | |
7c673cae FG |
441 | expect_break_lock(mock_image_ctx, -ENOENT); |
442 | ||
443 | C_SaferCond ctx; | |
444 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
445 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 446 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 | 447 | locker, true, true, 0, false, &ctx); |
7c673cae FG |
448 | req->send(); |
449 | ASSERT_EQ(0, ctx.wait()); | |
450 | } | |
451 | ||
452 | TEST_F(TestMockManagedLockBreakRequest, BreakLockError) { | |
453 | REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK); | |
454 | ||
455 | librbd::ImageCtx *ictx; | |
456 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
457 | ||
458 | MockTestImageCtx mock_image_ctx(*ictx); | |
459 | expect_op_work_queue(mock_image_ctx); | |
460 | ||
461 | InSequence seq; | |
462 | expect_list_watchers(mock_image_ctx, 0, "dead client", 123); | |
31f18b77 FG |
463 | |
464 | MockGetLockerRequest mock_get_locker_request; | |
465 | expect_get_locker(mock_image_ctx, mock_get_locker_request, | |
466 | {entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}, | |
467 | 0); | |
468 | ||
f67539c2 TL |
469 | expect_blocklist_add(mock_image_ctx, 0); |
470 | expect_wait_for_latest_osd_map(mock_image_ctx, 0); | |
7c673cae FG |
471 | expect_break_lock(mock_image_ctx, -EINVAL); |
472 | ||
473 | C_SaferCond ctx; | |
474 | Locker locker{entity_name_t::CLIENT(1), "auto 123", "1.2.3.4:0/0", 123}; | |
475 | MockBreakRequest *req = MockBreakRequest::create( | |
f67539c2 | 476 | mock_image_ctx.md_ctx, *ictx->asio_engine, mock_image_ctx.header_oid, |
31f18b77 | 477 | locker, true, true, 0, false, &ctx); |
7c673cae FG |
478 | req->send(); |
479 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
480 | } | |
481 | ||
482 | } // namespace managed_lock | |
483 | } // namespace librbd | |
484 |