]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librbd/image/test_mock_RefreshRequest.cc
update sources to v12.2.3
[ceph.git] / ceph / src / test / librbd / image / test_mock_RefreshRequest.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/librbd/mock/MockImageCtx.h"
7#include "test/librbd/mock/MockJournal.h"
8#include "test/librbd/mock/MockJournalPolicy.h"
9#include "test/librbd/mock/MockObjectMap.h"
10#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
11#include "test/librados_test_stub/MockTestMemRadosClient.h"
12#include "librbd/ImageState.h"
13#include "librbd/internal.h"
14#include "librbd/Operations.h"
15#include "librbd/image/RefreshRequest.h"
16#include "librbd/image/RefreshParentRequest.h"
17#include "gmock/gmock.h"
18#include "gtest/gtest.h"
19#include <arpa/inet.h>
20#include <list>
21#include <boost/scope_exit.hpp>
22
23namespace librbd {
24
25namespace {
26
27struct MockRefreshImageCtx : public MockImageCtx {
28 MockRefreshImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
29 }
30};
31
32} // anonymous namespace
33
34namespace image {
35
36template <>
37struct RefreshParentRequest<MockRefreshImageCtx> {
38 static RefreshParentRequest* s_instance;
39 static RefreshParentRequest* create(MockRefreshImageCtx &mock_image_ctx,
40 const ParentInfo& parent_md,
41 Context *on_finish) {
42 assert(s_instance != nullptr);
43 s_instance->on_finish = on_finish;
44 return s_instance;
45 }
46 static bool is_refresh_required(MockRefreshImageCtx &mock_image_ctx,
47 const ParentInfo& parent_md) {
48 assert(s_instance != nullptr);
49 return s_instance->is_refresh_required();
50 }
51
52 Context *on_finish = nullptr;
53
54 RefreshParentRequest() {
55 s_instance = this;
56 }
57
58 MOCK_CONST_METHOD0(is_refresh_required, bool());
59 MOCK_METHOD0(send, void());
60 MOCK_METHOD0(apply, void());
61 MOCK_METHOD1(finalize, void(Context *));
62};
63
64RefreshParentRequest<MockRefreshImageCtx>* RefreshParentRequest<MockRefreshImageCtx>::s_instance = nullptr;
65
66} // namespace image
67} // namespace librbd
68
69// template definitions
70#include "librbd/image/RefreshRequest.cc"
71template class librbd::image::RefreshRequest<librbd::MockRefreshImageCtx>;
72
73ACTION_P(TestFeatures, image_ctx) {
74 return ((image_ctx->features & arg0) != 0);
75}
76
77ACTION_P(ShutDownExclusiveLock, image_ctx) {
78 // shutting down exclusive lock will close object map and journal
79 image_ctx->exclusive_lock = nullptr;
80 image_ctx->object_map = nullptr;
81 image_ctx->journal = nullptr;
82}
83
84namespace librbd {
85namespace image {
86
87using ::testing::_;
88using ::testing::DoAll;
89using ::testing::DoDefault;
90using ::testing::InSequence;
91using ::testing::Return;
92using ::testing::WithArg;
93using ::testing::StrEq;
94
95class TestMockImageRefreshRequest : public TestMockFixture {
96public:
97 typedef RefreshRequest<MockRefreshImageCtx> MockRefreshRequest;
98 typedef RefreshParentRequest<MockRefreshImageCtx> MockRefreshParentRequest;
99
224ce89b
WB
100 void expect_set_require_lock(MockRefreshImageCtx &mock_image_ctx,
101 librbd::io::Direction direction, bool enabled) {
102 EXPECT_CALL(*mock_image_ctx.io_work_queue, set_require_lock(direction,
103 enabled));
7c673cae
FG
104 }
105
106 void expect_v1_read_header(MockRefreshImageCtx &mock_image_ctx, int r) {
107 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
108 read(mock_image_ctx.header_oid, _, _, _));
109 if (r < 0) {
110 expect.WillOnce(Return(r));
111 } else {
112 expect.WillOnce(DoDefault());
113 }
114 }
115
116 void expect_v1_get_snapshots(MockRefreshImageCtx &mock_image_ctx, int r) {
117 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
118 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("snap_list"), _, _, _));
119 if (r < 0) {
120 expect.WillOnce(Return(r));
121 } else {
122 expect.WillOnce(DoDefault());
123 }
124 }
125
126 void expect_v1_get_locks(MockRefreshImageCtx &mock_image_ctx, int r) {
127 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
128 exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("get_info"), _, _, _));
129 if (r < 0) {
130 expect.WillOnce(Return(r));
131 } else {
132 expect.WillOnce(DoDefault());
133 }
134 }
135
136 void expect_get_mutable_metadata(MockRefreshImageCtx &mock_image_ctx, int r) {
137 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
138 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_size"), _, _, _));
139 if (r < 0) {
140 expect.WillOnce(Return(r));
141 } else {
142 expect.WillOnce(DoDefault());
143 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
144 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_features"), _, _, _))
145 .WillOnce(DoDefault());
146 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
147 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapcontext"), _, _, _))
148 .WillOnce(DoDefault());
149 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
150 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
151 .WillOnce(DoDefault());
152 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
153 exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("get_info"), _, _, _))
154 .WillOnce(DoDefault());
155 }
156 }
157
b32b8144
FG
158 void expect_get_metadata(MockRefreshImageCtx &mock_image_ctx, int r) {
159 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
160 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("metadata_list"), _, _, _));
161 if (r < 0) {
162 expect.WillOnce(Return(r));
163 } else {
164 expect.WillOnce(DoDefault());
165 }
166 }
167
7c673cae
FG
168 void expect_get_flags(MockRefreshImageCtx &mock_image_ctx, int r) {
169 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
170 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_flags"), _, _, _));
171 if (r < 0) {
172 expect.WillOnce(Return(r));
173 } else {
174 expect.WillOnce(DoDefault());
175 }
176 }
177
178 void expect_get_group(MockRefreshImageCtx &mock_image_ctx, int r) {
179 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
180 exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
181 StrEq("image_get_group"), _, _, _));
182 if (r < 0) {
183 expect.WillOnce(Return(r));
184 } else {
185 expect.WillOnce(DoDefault());
186 }
187 }
188
189
190 void expect_get_snapshots(MockRefreshImageCtx &mock_image_ctx, int r) {
191 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
192 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_name"), _, _, _));
193 if (r < 0) {
194 expect.WillOnce(Return(r));
195 } else {
196 expect.WillOnce(DoDefault());
197 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
198 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_size"), _, _, _))
199 .WillOnce(DoDefault());
200 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
201 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
202 .WillOnce(DoDefault());
203 EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
204 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_protection_status"), _, _, _))
205 .WillOnce(DoDefault());
206 }
207 }
208
209 void expect_snap_timestamp_list(MockRefreshImageCtx &mock_image_ctx, int r) {
210 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
211 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_timestamp"), _, _, _));
212 if (r < 0) {
213 expect.WillOnce(Return(r));
214 } else {
215 expect.WillOnce(DoDefault());
216 }
217 }
218
219 void expect_snap_namespace_list(MockRefreshImageCtx &mock_image_ctx, int r) {
220 auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
221 exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_namespace"), _, _, _));
222 if (r < 0) {
223 expect.WillOnce(Return(r));
224 } else {
225 expect.WillOnce(DoDefault());
226 }
227 }
228
b32b8144
FG
229 void expect_apply_metadata(MockRefreshImageCtx &mock_image_ctx,
230 int r) {
231 EXPECT_CALL(mock_image_ctx, apply_metadata(_, false))
232 .WillOnce(Return(r));
233 }
234
7c673cae
FG
235 void expect_add_snap(MockRefreshImageCtx &mock_image_ctx,
236 const std::string &snap_name, uint64_t snap_id) {
237 EXPECT_CALL(mock_image_ctx, add_snap(_, snap_name, snap_id, _, _, _, _, _));
238 }
239
240 void expect_init_exclusive_lock(MockRefreshImageCtx &mock_image_ctx,
241 MockExclusiveLock &mock_exclusive_lock,
242 int r) {
243 EXPECT_CALL(mock_image_ctx, create_exclusive_lock())
244 .WillOnce(Return(&mock_exclusive_lock));
245 EXPECT_CALL(mock_exclusive_lock, init(mock_image_ctx.features, _))
246 .WillOnce(WithArg<1>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)));
247 }
248
249 void expect_shut_down_exclusive_lock(MockRefreshImageCtx &mock_image_ctx,
250 MockExclusiveLock &mock_exclusive_lock,
251 int r) {
252 EXPECT_CALL(mock_exclusive_lock, shut_down(_))
253 .WillOnce(DoAll(ShutDownExclusiveLock(&mock_image_ctx),
254 CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)));
255 }
256
257 void expect_init_layout(MockRefreshImageCtx &mock_image_ctx) {
258 EXPECT_CALL(mock_image_ctx, init_layout());
259 }
260
261 void expect_test_features(MockRefreshImageCtx &mock_image_ctx) {
262 EXPECT_CALL(mock_image_ctx, test_features(_, _))
263 .WillRepeatedly(TestFeatures(&mock_image_ctx));
264 }
265
266 void expect_refresh_parent_is_required(MockRefreshParentRequest &mock_refresh_parent_request,
267 bool required) {
268 EXPECT_CALL(mock_refresh_parent_request, is_refresh_required())
269 .WillRepeatedly(Return(required));
270 }
271
272 void expect_refresh_parent_send(MockRefreshImageCtx &mock_image_ctx,
273 MockRefreshParentRequest &mock_refresh_parent_request,
274 int r) {
275 EXPECT_CALL(mock_refresh_parent_request, send())
276 .WillOnce(FinishRequest(&mock_refresh_parent_request, r,
277 &mock_image_ctx));
278 }
279
280 void expect_refresh_parent_apply(MockRefreshParentRequest &mock_refresh_parent_request) {
281 EXPECT_CALL(mock_refresh_parent_request, apply());
282 }
283
284 void expect_refresh_parent_finalize(MockRefreshImageCtx &mock_image_ctx,
285 MockRefreshParentRequest &mock_refresh_parent_request,
286 int r) {
287 EXPECT_CALL(mock_refresh_parent_request, finalize(_))
288 .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
289 }
290
291 void expect_is_exclusive_lock_owner(MockExclusiveLock &mock_exclusive_lock,
292 bool is_owner) {
293 EXPECT_CALL(mock_exclusive_lock, is_lock_owner()).WillOnce(Return(is_owner));
294 }
295
296 void expect_get_journal_policy(MockImageCtx &mock_image_ctx,
297 MockJournalPolicy &mock_journal_policy) {
298 EXPECT_CALL(mock_image_ctx, get_journal_policy())
299 .WillOnce(Return(&mock_journal_policy));
300 }
301
302 void expect_journal_disabled(MockJournalPolicy &mock_journal_policy,
303 bool disabled) {
304 EXPECT_CALL(mock_journal_policy, journal_disabled())
305 .WillOnce(Return(disabled));
306 }
307
308 void expect_open_journal(MockRefreshImageCtx &mock_image_ctx,
309 MockJournal &mock_journal, int r) {
310 EXPECT_CALL(mock_image_ctx, create_journal())
311 .WillOnce(Return(&mock_journal));
312 EXPECT_CALL(mock_journal, open(_))
313 .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
314 }
315
316 void expect_close_journal(MockRefreshImageCtx &mock_image_ctx,
317 MockJournal &mock_journal, int r) {
318 EXPECT_CALL(mock_journal, close(_))
319 .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
320 }
321
322 void expect_open_object_map(MockRefreshImageCtx &mock_image_ctx,
323 MockObjectMap *mock_object_map, int r) {
324 EXPECT_CALL(mock_image_ctx, create_object_map(_))
325 .WillOnce(Return(mock_object_map));
326 EXPECT_CALL(*mock_object_map, open(_))
327 .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
328 }
329
330 void expect_close_object_map(MockRefreshImageCtx &mock_image_ctx,
331 MockObjectMap &mock_object_map, int r) {
332 EXPECT_CALL(mock_object_map, close(_))
333 .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
334 }
335
336 void expect_get_snap_id(MockRefreshImageCtx &mock_image_ctx,
337 const std::string &snap_name,
338 uint64_t snap_id) {
339 EXPECT_CALL(mock_image_ctx,
340 get_snap_id(_, snap_name)).WillOnce(Return(snap_id));
341 }
342
343 void expect_block_writes(MockImageCtx &mock_image_ctx, int r) {
344 EXPECT_CALL(*mock_image_ctx.io_work_queue, block_writes(_))
345 .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
346 }
347
348 void expect_unblock_writes(MockImageCtx &mock_image_ctx) {
349 EXPECT_CALL(*mock_image_ctx.io_work_queue, unblock_writes())
350 .Times(1);
351 }
352
353};
354
355TEST_F(TestMockImageRefreshRequest, SuccessV1) {
356 REQUIRE_FORMAT_V1();
357
358 librbd::ImageCtx *ictx;
359 ASSERT_EQ(0, open_image(m_image_name, &ictx));
360
361 MockRefreshImageCtx mock_image_ctx(*ictx);
362 expect_op_work_queue(mock_image_ctx);
363 expect_test_features(mock_image_ctx);
364
365 InSequence seq;
366 expect_v1_read_header(mock_image_ctx, 0);
367 expect_v1_get_snapshots(mock_image_ctx, 0);
368 expect_v1_get_locks(mock_image_ctx, 0);
369 expect_init_layout(mock_image_ctx);
370
371 C_SaferCond ctx;
372 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
373 req->send();
374
375 ASSERT_EQ(0, ctx.wait());
376}
377
378TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV1) {
379 REQUIRE_FORMAT_V1();
380 librbd::ImageCtx *ictx;
381 ASSERT_EQ(0, open_image(m_image_name, &ictx));
382 ASSERT_EQ(0, snap_create(*ictx, "snap"));
383 ASSERT_EQ(0, ictx->state->refresh());
384
385 MockRefreshImageCtx mock_image_ctx(*ictx);
386 expect_op_work_queue(mock_image_ctx);
387 expect_test_features(mock_image_ctx);
388
389 InSequence seq;
390 expect_v1_read_header(mock_image_ctx, 0);
391 expect_v1_get_snapshots(mock_image_ctx, 0);
392 expect_v1_get_locks(mock_image_ctx, 0);
393 expect_init_layout(mock_image_ctx);
394 expect_add_snap(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
395
396 C_SaferCond ctx;
397 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
398 req->send();
399
400 ASSERT_EQ(0, ctx.wait());
401}
402
403TEST_F(TestMockImageRefreshRequest, SuccessV2) {
404 REQUIRE_FORMAT_V2();
405
406 librbd::ImageCtx *ictx;
407 ASSERT_EQ(0, open_image(m_image_name, &ictx));
408
409 MockRefreshImageCtx mock_image_ctx(*ictx);
410 MockRefreshParentRequest mock_refresh_parent_request;
411 MockExclusiveLock mock_exclusive_lock;
412 expect_op_work_queue(mock_image_ctx);
413 expect_test_features(mock_image_ctx);
414
415 InSequence seq;
416 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
417 expect_get_metadata(mock_image_ctx, 0);
418 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
419 expect_get_flags(mock_image_ctx, 0);
420 expect_get_group(mock_image_ctx, 0);
421 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
422 if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
423 expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
424 }
425
426 C_SaferCond ctx;
427 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
428 req->send();
429
430 ASSERT_EQ(0, ctx.wait());
431}
432
433TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV2) {
434 REQUIRE_FORMAT_V2();
435
436 librbd::ImageCtx *ictx;
437 ASSERT_EQ(0, open_image(m_image_name, &ictx));
438 ASSERT_EQ(0, snap_create(*ictx, "snap"));
439
440 MockRefreshImageCtx mock_image_ctx(*ictx);
441 MockRefreshParentRequest mock_refresh_parent_request;
442 MockExclusiveLock mock_exclusive_lock;
443 expect_op_work_queue(mock_image_ctx);
444 expect_test_features(mock_image_ctx);
445
446 InSequence seq;
447 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
448 expect_get_metadata(mock_image_ctx, 0);
449 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
450 expect_get_flags(mock_image_ctx, 0);
451 expect_get_flags(mock_image_ctx, 0);
452 expect_get_group(mock_image_ctx, 0);
453 expect_get_snapshots(mock_image_ctx, 0);
454 expect_snap_timestamp_list(mock_image_ctx, 0);
455 expect_snap_namespace_list(mock_image_ctx, 0);
456 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
457 if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
458 expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
459 }
460 expect_add_snap(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
461
462 C_SaferCond ctx;
463 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
464 req->send();
465
466 ASSERT_EQ(0, ctx.wait());
467}
468
469TEST_F(TestMockImageRefreshRequest, SuccessSetSnapshotV2) {
470 REQUIRE_FORMAT_V2();
471
472 librbd::ImageCtx *ictx;
473 ASSERT_EQ(0, open_image(m_image_name, &ictx));
474 ASSERT_EQ(0, snap_create(*ictx, "snap"));
475 ASSERT_EQ(0, librbd::snap_set(ictx, cls::rbd::UserSnapshotNamespace(), "snap"));
476
477 MockRefreshImageCtx mock_image_ctx(*ictx);
478 MockRefreshParentRequest mock_refresh_parent_request;
479 MockObjectMap mock_object_map;
480 expect_op_work_queue(mock_image_ctx);
481 expect_test_features(mock_image_ctx);
482
483 InSequence seq;
484 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
485 expect_get_metadata(mock_image_ctx, 0);
486 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
487 expect_get_flags(mock_image_ctx, 0);
488 expect_get_flags(mock_image_ctx, 0);
489 expect_get_group(mock_image_ctx, 0);
490 expect_get_snapshots(mock_image_ctx, 0);
491 expect_snap_timestamp_list(mock_image_ctx, 0);
492 expect_snap_namespace_list(mock_image_ctx, 0);
493 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
494 if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
495 expect_open_object_map(mock_image_ctx, &mock_object_map, 0);
496 }
497 expect_add_snap(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
498 expect_get_snap_id(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
499
500 C_SaferCond ctx;
501 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
502 req->send();
503
504 ASSERT_EQ(0, ctx.wait());
505}
506
507TEST_F(TestMockImageRefreshRequest, SuccessChild) {
508 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
509
510 librbd::ImageCtx *ictx;
511 librbd::ImageCtx *ictx2 = nullptr;
512 std::string clone_name = get_temp_image_name();
513
514 ASSERT_EQ(0, open_image(m_image_name, &ictx));
515 ASSERT_EQ(0, snap_create(*ictx, "snap"));
516 ASSERT_EQ(0, snap_protect(*ictx, "snap"));
517 BOOST_SCOPE_EXIT_ALL((&)) {
518 if (ictx2 != nullptr) {
519 close_image(ictx2);
520 }
521
522 librbd::NoOpProgressContext no_op;
523 ASSERT_EQ(0, librbd::remove(m_ioctx, clone_name, "", no_op));
524 ASSERT_EQ(0, ictx->operations->snap_unprotect(cls::rbd::UserSnapshotNamespace(), "snap"));
525 };
526
527 int order = ictx->order;
528 ASSERT_EQ(0, librbd::clone(m_ioctx, m_image_name.c_str(), "snap", m_ioctx,
529 clone_name.c_str(), ictx->features, &order, 0, 0));
530
531 ASSERT_EQ(0, open_image(clone_name, &ictx2));
532
533 MockRefreshImageCtx mock_image_ctx(*ictx2);
534 MockRefreshParentRequest *mock_refresh_parent_request = new MockRefreshParentRequest();
535 MockExclusiveLock mock_exclusive_lock;
536 expect_op_work_queue(mock_image_ctx);
537 expect_test_features(mock_image_ctx);
538
539 InSequence seq;
540 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
541 expect_get_metadata(mock_image_ctx, 0);
542 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
543 expect_get_flags(mock_image_ctx, 0);
544 expect_get_group(mock_image_ctx, 0);
545 expect_refresh_parent_is_required(*mock_refresh_parent_request, true);
546 expect_refresh_parent_send(mock_image_ctx, *mock_refresh_parent_request, 0);
547 if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
548 expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
549 }
550 expect_refresh_parent_apply(*mock_refresh_parent_request);
551 expect_refresh_parent_finalize(mock_image_ctx, *mock_refresh_parent_request, 0);
552
553 C_SaferCond ctx;
554 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
555 req->send();
556
557 ASSERT_EQ(0, ctx.wait());
558}
559
560TEST_F(TestMockImageRefreshRequest, SuccessChildDontOpenParent) {
561 REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
562
563 librbd::ImageCtx *ictx;
564 librbd::ImageCtx *ictx2 = nullptr;
565 std::string clone_name = get_temp_image_name();
566
567 ASSERT_EQ(0, open_image(m_image_name, &ictx));
568 ASSERT_EQ(0, snap_create(*ictx, "snap"));
569 ASSERT_EQ(0, snap_protect(*ictx, "snap"));
570 BOOST_SCOPE_EXIT_ALL((&)) {
571 if (ictx2 != nullptr) {
572 close_image(ictx2);
573 }
574
575 librbd::NoOpProgressContext no_op;
576 ASSERT_EQ(0, librbd::remove(m_ioctx, clone_name, "", no_op));
577 ASSERT_EQ(0, ictx->operations->snap_unprotect(cls::rbd::UserSnapshotNamespace(), "snap"));
578 };
579
580 int order = ictx->order;
581 ASSERT_EQ(0, librbd::clone(m_ioctx, m_image_name.c_str(), "snap", m_ioctx,
582 clone_name.c_str(), ictx->features, &order, 0, 0));
583
584 ASSERT_EQ(0, open_image(clone_name, &ictx2));
585
586 MockRefreshImageCtx mock_image_ctx(*ictx2);
587 MockExclusiveLock mock_exclusive_lock;
588 expect_op_work_queue(mock_image_ctx);
589 expect_test_features(mock_image_ctx);
590
591 InSequence seq;
592 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
593 expect_get_metadata(mock_image_ctx, 0);
594 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
595 expect_get_flags(mock_image_ctx, 0);
596 expect_get_group(mock_image_ctx, 0);
597 if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
598 expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
599 }
600
601 C_SaferCond ctx;
602 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, true, &ctx);
603 req->send();
604
605 ASSERT_EQ(0, ctx.wait());
606}
607
608TEST_F(TestMockImageRefreshRequest, DisableExclusiveLock) {
609 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
610
611 librbd::ImageCtx *ictx;
612 ASSERT_EQ(0, open_image(m_image_name, &ictx));
613
614 MockRefreshImageCtx mock_image_ctx(*ictx);
615 MockRefreshParentRequest mock_refresh_parent_request;
616
617 MockExclusiveLock *mock_exclusive_lock = new MockExclusiveLock();
618 mock_image_ctx.exclusive_lock = mock_exclusive_lock;
619
620 MockObjectMap mock_object_map;
621 if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
622 mock_image_ctx.object_map = &mock_object_map;
623 }
624
625 MockJournal mock_journal;
626 if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
627 mock_image_ctx.journal = &mock_journal;
628 }
629
630 if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
631 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_JOURNALING,
632 false));
633 }
634
635 if (ictx->test_features(RBD_FEATURE_FAST_DIFF)) {
636 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_FAST_DIFF,
637 false));
638 }
639
640 if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
641 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_OBJECT_MAP,
642 false));
643 }
644
645 if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
646 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_EXCLUSIVE_LOCK,
647 false));
648 }
649
650 expect_op_work_queue(mock_image_ctx);
651 expect_test_features(mock_image_ctx);
652
653 // verify that exclusive lock is properly handled when object map
654 // and journaling were never enabled (or active)
655 InSequence seq;
656 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
657 expect_get_metadata(mock_image_ctx, 0);
658 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
659 expect_get_flags(mock_image_ctx, 0);
660 expect_get_group(mock_image_ctx, 0);
661 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
7c673cae
FG
662 expect_shut_down_exclusive_lock(mock_image_ctx, *mock_exclusive_lock, 0);
663
664 C_SaferCond ctx;
665 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
666 req->send();
667
668 ASSERT_EQ(0, ctx.wait());
669}
670
671TEST_F(TestMockImageRefreshRequest, DisableExclusiveLockWhileAcquiringLock) {
672 REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
673
674 librbd::ImageCtx *ictx;
675 ASSERT_EQ(0, open_image(m_image_name, &ictx));
676
677 MockRefreshImageCtx mock_image_ctx(*ictx);
678 MockRefreshParentRequest mock_refresh_parent_request;
679
680 MockExclusiveLock mock_exclusive_lock;
681 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
682
683 if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
684 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_JOURNALING,
685 false));
686 }
687
688 if (ictx->test_features(RBD_FEATURE_FAST_DIFF)) {
689 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_FAST_DIFF,
690 false));
691 }
692
693 if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
694 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_OBJECT_MAP,
695 false));
696 }
697
698 if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
699 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_EXCLUSIVE_LOCK,
700 false));
701 }
702
703 expect_op_work_queue(mock_image_ctx);
704 expect_test_features(mock_image_ctx);
705
706 // verify that exclusive lock is properly handled when object map
707 // and journaling were never enabled (or active)
708 InSequence seq;
709 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
710 expect_get_metadata(mock_image_ctx, 0);
711 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
712 expect_get_flags(mock_image_ctx, 0);
713 expect_get_group(mock_image_ctx, 0);
714 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
715
716 C_SaferCond ctx;
717 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, true, false, &ctx);
718 req->send();
719
720 ASSERT_EQ(-ERESTART, ctx.wait());
721}
722
723TEST_F(TestMockImageRefreshRequest, JournalDisabledByPolicy) {
724 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
725
726 librbd::ImageCtx *ictx;
727 ASSERT_EQ(0, open_image(m_image_name, &ictx));
728
729 if (ictx->test_features(RBD_FEATURE_FAST_DIFF)) {
730 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_FAST_DIFF,
731 false));
732 }
733
734 if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
735 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_OBJECT_MAP,
736 false));
737 }
738
739 MockRefreshImageCtx mock_image_ctx(*ictx);
740 MockRefreshParentRequest mock_refresh_parent_request;
741
742 MockExclusiveLock mock_exclusive_lock;
743 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
744
745 MockJournal mock_journal;
746
747 expect_op_work_queue(mock_image_ctx);
748 expect_test_features(mock_image_ctx);
749 expect_is_exclusive_lock_owner(mock_exclusive_lock, true);
750
751 InSequence seq;
752 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
753 expect_get_metadata(mock_image_ctx, 0);
754 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
755 expect_get_flags(mock_image_ctx, 0);
756 expect_get_group(mock_image_ctx, 0);
757 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
758
759 MockJournalPolicy mock_journal_policy;
760 expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
761 expect_journal_disabled(mock_journal_policy, true);
762
763 C_SaferCond ctx;
764 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
765 req->send();
766
767 ASSERT_EQ(0, ctx.wait());
768}
769
7c673cae
FG
770TEST_F(TestMockImageRefreshRequest, EnableJournalWithExclusiveLock) {
771 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
772
773 librbd::ImageCtx *ictx;
774 ASSERT_EQ(0, open_image(m_image_name, &ictx));
775
776 if (ictx->test_features(RBD_FEATURE_FAST_DIFF)) {
777 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_FAST_DIFF,
778 false));
779 }
780
781 if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
782 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_OBJECT_MAP,
783 false));
784 }
785
786 MockRefreshImageCtx mock_image_ctx(*ictx);
787 MockRefreshParentRequest mock_refresh_parent_request;
788
789 MockExclusiveLock mock_exclusive_lock;
790 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
791
792 MockJournal mock_journal;
793
794 expect_op_work_queue(mock_image_ctx);
795 expect_test_features(mock_image_ctx);
796 expect_is_exclusive_lock_owner(mock_exclusive_lock, true);
797
798 // journal should be immediately opened if exclusive lock owned
799 InSequence seq;
800 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
801 expect_get_metadata(mock_image_ctx, 0);
802 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
803 expect_get_flags(mock_image_ctx, 0);
804 expect_get_group(mock_image_ctx, 0);
805 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
806
807 MockJournalPolicy mock_journal_policy;
808 expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
809 expect_journal_disabled(mock_journal_policy, false);
810 expect_open_journal(mock_image_ctx, mock_journal, 0);
811
812 C_SaferCond ctx;
813 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
814 req->send();
815
816 ASSERT_EQ(0, ctx.wait());
817}
818
819TEST_F(TestMockImageRefreshRequest, EnableJournalWithoutExclusiveLock) {
820 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
821
822 librbd::ImageCtx *ictx;
823 ASSERT_EQ(0, open_image(m_image_name, &ictx));
824
825 if (ictx->test_features(RBD_FEATURE_FAST_DIFF)) {
826 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_FAST_DIFF,
827 false));
828 }
829
830 if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
831 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_OBJECT_MAP,
832 false));
833 }
834
835 MockRefreshImageCtx mock_image_ctx(*ictx);
836 MockRefreshParentRequest mock_refresh_parent_request;
837
838 MockExclusiveLock mock_exclusive_lock;
839 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
840
841 expect_op_work_queue(mock_image_ctx);
842 expect_test_features(mock_image_ctx);
843 expect_is_exclusive_lock_owner(mock_exclusive_lock, false);
844
845 // do not open the journal if exclusive lock is not owned
846 InSequence seq;
847 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
848 expect_get_metadata(mock_image_ctx, 0);
849 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
850 expect_get_flags(mock_image_ctx, 0);
851 expect_get_group(mock_image_ctx, 0);
852 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
224ce89b 853 expect_set_require_lock(mock_image_ctx, librbd::io::DIRECTION_BOTH, true);
7c673cae
FG
854
855 C_SaferCond ctx;
856 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
857 req->send();
858
859 ASSERT_EQ(0, ctx.wait());
860}
861
862TEST_F(TestMockImageRefreshRequest, DisableJournal) {
863 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
864
865 librbd::ImageCtx *ictx;
866 ASSERT_EQ(0, open_image(m_image_name, &ictx));
867
868 MockRefreshImageCtx mock_image_ctx(*ictx);
869 MockRefreshParentRequest mock_refresh_parent_request;
870
871 MockExclusiveLock mock_exclusive_lock;
872 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
873
874 MockObjectMap mock_object_map;
875 if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
876 mock_image_ctx.object_map = &mock_object_map;
877 }
878
879 MockJournal *mock_journal = new MockJournal();
880 mock_image_ctx.journal = mock_journal;
881
882 if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
883 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_JOURNALING,
884 false));
885 }
886
887 expect_op_work_queue(mock_image_ctx);
888 expect_test_features(mock_image_ctx);
889
890 // verify journal is closed if feature disabled
891 InSequence seq;
892 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
893 expect_get_metadata(mock_image_ctx, 0);
894 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
895 expect_get_flags(mock_image_ctx, 0);
896 expect_get_group(mock_image_ctx, 0);
897 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
898 expect_block_writes(mock_image_ctx, 0);
224ce89b
WB
899 if (!mock_image_ctx.clone_copy_on_read) {
900 expect_set_require_lock(mock_image_ctx, librbd::io::DIRECTION_READ, false);
901 }
7c673cae
FG
902 expect_close_journal(mock_image_ctx, *mock_journal, 0);
903 expect_unblock_writes(mock_image_ctx);
904
905 C_SaferCond ctx;
906 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
907 req->send();
908
909 ASSERT_EQ(0, ctx.wait());
910}
911
912TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithExclusiveLock) {
913 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
914
915 librbd::ImageCtx *ictx;
916 ASSERT_EQ(0, open_image(m_image_name, &ictx));
917
918 if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
919 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_JOURNALING,
920 false));
921 }
922
923 MockRefreshImageCtx mock_image_ctx(*ictx);
924 MockRefreshParentRequest mock_refresh_parent_request;
925
926 MockExclusiveLock mock_exclusive_lock;
927 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
928
929 MockObjectMap mock_object_map;
930
931 expect_op_work_queue(mock_image_ctx);
932 expect_test_features(mock_image_ctx);
933 expect_is_exclusive_lock_owner(mock_exclusive_lock, true);
934
935 // object map should be immediately opened if exclusive lock owned
936 InSequence seq;
937 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
938 expect_get_metadata(mock_image_ctx, 0);
939 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
940 expect_get_flags(mock_image_ctx, 0);
941 expect_get_group(mock_image_ctx, 0);
942 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
943 expect_open_object_map(mock_image_ctx, &mock_object_map, 0);
944
945 C_SaferCond ctx;
946 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
947 req->send();
948
949 ASSERT_EQ(0, ctx.wait());
950}
951
952TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithoutExclusiveLock) {
953 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
954
955 librbd::ImageCtx *ictx;
956 ASSERT_EQ(0, open_image(m_image_name, &ictx));
957
958 if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
959 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_JOURNALING,
960 false));
961 }
962
963 MockRefreshImageCtx mock_image_ctx(*ictx);
964 MockRefreshParentRequest mock_refresh_parent_request;
965
966 MockExclusiveLock mock_exclusive_lock;
967 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
968
969 expect_op_work_queue(mock_image_ctx);
970 expect_test_features(mock_image_ctx);
971 expect_is_exclusive_lock_owner(mock_exclusive_lock, false);
972
973 // do not open the object map if exclusive lock is not owned
974 InSequence seq;
975 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
976 expect_get_metadata(mock_image_ctx, 0);
977 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
978 expect_get_flags(mock_image_ctx, 0);
979 expect_get_group(mock_image_ctx, 0);
980 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
981
982 C_SaferCond ctx;
983 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
984 req->send();
985
986 ASSERT_EQ(0, ctx.wait());
987}
988
989TEST_F(TestMockImageRefreshRequest, DisableObjectMap) {
990 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
991
992 librbd::ImageCtx *ictx;
993 ASSERT_EQ(0, open_image(m_image_name, &ictx));
994
995 MockRefreshImageCtx mock_image_ctx(*ictx);
996 MockRefreshParentRequest mock_refresh_parent_request;
997
998 MockExclusiveLock mock_exclusive_lock;
999 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1000
1001 MockObjectMap *mock_object_map = new MockObjectMap();
1002 mock_image_ctx.object_map = mock_object_map;
1003
1004 MockJournal mock_journal;
1005 if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
1006 mock_image_ctx.journal = &mock_journal;
1007 }
1008
1009 if (ictx->test_features(RBD_FEATURE_FAST_DIFF)) {
1010 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_FAST_DIFF,
1011 false));
1012 }
1013
1014 if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
1015 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_OBJECT_MAP,
1016 false));
1017 }
1018
1019 expect_op_work_queue(mock_image_ctx);
1020 expect_test_features(mock_image_ctx);
1021
1022 // verify object map is closed if feature disabled
1023 InSequence seq;
1024 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
1025 expect_get_metadata(mock_image_ctx, 0);
1026 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
1027 expect_get_flags(mock_image_ctx, 0);
1028 expect_get_group(mock_image_ctx, 0);
1029 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
1030 expect_close_object_map(mock_image_ctx, *mock_object_map, 0);
1031
1032 C_SaferCond ctx;
1033 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
1034 req->send();
1035
1036 ASSERT_EQ(0, ctx.wait());
1037}
1038
1039TEST_F(TestMockImageRefreshRequest, OpenObjectMapError) {
1040 REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
1041
1042 librbd::ImageCtx *ictx;
1043 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1044
1045 if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
1046 ASSERT_EQ(0, ictx->operations->update_features(RBD_FEATURE_JOURNALING,
1047 false));
1048 }
1049
1050 MockRefreshImageCtx mock_image_ctx(*ictx);
1051 MockRefreshParentRequest mock_refresh_parent_request;
1052
1053 MockExclusiveLock mock_exclusive_lock;
1054 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1055
1056 MockObjectMap *mock_object_map = new MockObjectMap();
1057
1058 expect_op_work_queue(mock_image_ctx);
1059 expect_test_features(mock_image_ctx);
1060 expect_is_exclusive_lock_owner(mock_exclusive_lock, true);
1061
1062 // object map should be immediately opened if exclusive lock owned
1063 InSequence seq;
1064 expect_get_mutable_metadata(mock_image_ctx, 0);
b32b8144
FG
1065 expect_get_metadata(mock_image_ctx, 0);
1066 expect_apply_metadata(mock_image_ctx, 0);
7c673cae
FG
1067 expect_get_flags(mock_image_ctx, 0);
1068 expect_get_group(mock_image_ctx, 0);
1069 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
1070 expect_open_object_map(mock_image_ctx, mock_object_map, -EFBIG);
1071
1072 C_SaferCond ctx;
1073 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
1074 req->send();
1075
1076 ASSERT_EQ(0, ctx.wait());
1077 ASSERT_EQ(nullptr, mock_image_ctx.object_map);
1078}
1079
b32b8144
FG
1080TEST_F(TestMockImageRefreshRequest, ApplyMetadataError) {
1081 REQUIRE_FORMAT_V2();
1082
1083 librbd::ImageCtx *ictx;
1084 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1085
1086 MockRefreshImageCtx mock_image_ctx(*ictx);
1087 MockRefreshParentRequest mock_refresh_parent_request;
1088 MockExclusiveLock mock_exclusive_lock;
1089 expect_op_work_queue(mock_image_ctx);
1090 expect_test_features(mock_image_ctx);
1091
1092 InSequence seq;
1093 expect_get_mutable_metadata(mock_image_ctx, 0);
1094 expect_get_metadata(mock_image_ctx, 0);
1095 expect_apply_metadata(mock_image_ctx, -EINVAL);
1096 expect_get_flags(mock_image_ctx, 0);
1097 expect_get_group(mock_image_ctx, 0);
1098 expect_refresh_parent_is_required(mock_refresh_parent_request, false);
1099 if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
1100 expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
1101 }
1102
1103 C_SaferCond ctx;
1104 MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
1105 req->send();
1106
1107 ASSERT_EQ(0, ctx.wait());
1108}
1109
7c673cae
FG
1110} // namespace image
1111} // namespace librbd