]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "include/stringify.h" | |
5 | #include "test/librbd/test_mock_fixture.h" | |
6 | #include "test/librbd/test_support.h" | |
7 | #include "test/librbd/mock/MockImageCtx.h" | |
8 | #include "test/librbd/mock/MockOperations.h" | |
9 | #include "test/librados_test_stub/MockTestMemIoCtxImpl.h" | |
10 | #include "test/librados_test_stub/MockTestMemRadosClient.h" | |
11 | #include "librbd/mirror/snapshot/CreatePrimaryRequest.h" | |
12 | #include "librbd/mirror/snapshot/UnlinkPeerRequest.h" | |
13 | #include "librbd/mirror/snapshot/Utils.h" | |
14 | ||
15 | namespace librbd { | |
16 | ||
17 | namespace { | |
18 | ||
19 | struct MockTestImageCtx : public MockImageCtx { | |
20 | explicit MockTestImageCtx(librbd::ImageCtx& image_ctx) : MockImageCtx(image_ctx) { | |
21 | } | |
22 | }; | |
23 | ||
24 | } // anonymous namespace | |
25 | ||
26 | namespace mirror { | |
27 | namespace snapshot { | |
28 | namespace util { | |
29 | ||
30 | namespace { | |
31 | ||
32 | struct Mock { | |
33 | static Mock* s_instance; | |
34 | ||
35 | Mock() { | |
36 | s_instance = this; | |
37 | } | |
38 | ||
39 | MOCK_METHOD4(can_create_primary_snapshot, | |
40 | bool(librbd::MockTestImageCtx *, bool, bool, uint64_t *)); | |
41 | }; | |
42 | ||
43 | Mock *Mock::s_instance = nullptr; | |
44 | ||
45 | } // anonymous namespace | |
46 | ||
47 | template<> bool can_create_primary_snapshot(librbd::MockTestImageCtx *image_ctx, | |
48 | bool demoted, bool force, | |
49 | bool* requires_orphan, | |
50 | uint64_t *rollback_snap_id) { | |
51 | return Mock::s_instance->can_create_primary_snapshot(image_ctx, demoted, | |
52 | force, rollback_snap_id); | |
53 | } | |
54 | ||
55 | } // namespace util | |
56 | ||
57 | template <> | |
58 | struct UnlinkPeerRequest<MockTestImageCtx> { | |
59 | uint64_t snap_id = CEPH_NOSNAP; | |
60 | std::string mirror_peer_uuid; | |
1e59de90 | 61 | bool allow_remove; |
9f95a23c TL |
62 | Context* on_finish = nullptr; |
63 | static UnlinkPeerRequest* s_instance; | |
64 | static UnlinkPeerRequest *create(MockTestImageCtx *image_ctx, | |
65 | uint64_t snap_id, | |
66 | const std::string &mirror_peer_uuid, | |
1e59de90 | 67 | bool allow_remove, |
9f95a23c TL |
68 | Context *on_finish) { |
69 | ceph_assert(s_instance != nullptr); | |
70 | s_instance->snap_id = snap_id; | |
71 | s_instance->mirror_peer_uuid = mirror_peer_uuid; | |
1e59de90 | 72 | s_instance->allow_remove = allow_remove; |
9f95a23c TL |
73 | s_instance->on_finish = on_finish; |
74 | return s_instance; | |
75 | } | |
76 | ||
77 | MOCK_METHOD0(send, void()); | |
78 | ||
79 | UnlinkPeerRequest() { | |
80 | s_instance = this; | |
81 | } | |
82 | }; | |
83 | ||
84 | UnlinkPeerRequest<MockTestImageCtx>* UnlinkPeerRequest<MockTestImageCtx>::s_instance = nullptr; | |
85 | ||
86 | } // namespace snapshot | |
87 | } // namespace mirror | |
88 | } // namespace librbd | |
89 | ||
90 | // template definitions | |
91 | #include "librbd/mirror/snapshot/CreatePrimaryRequest.cc" | |
92 | template class librbd::mirror::snapshot::CreatePrimaryRequest<librbd::MockTestImageCtx>; | |
93 | ||
94 | namespace librbd { | |
95 | namespace mirror { | |
96 | namespace snapshot { | |
97 | ||
98 | using ::testing::_; | |
99 | using ::testing::DoAll; | |
100 | using ::testing::InSequence; | |
101 | using ::testing::Invoke; | |
102 | using ::testing::Return; | |
103 | using ::testing::StrEq; | |
104 | using ::testing::WithArg; | |
105 | ||
106 | class TestMockMirrorSnapshotCreatePrimaryRequest : public TestMockFixture { | |
107 | public: | |
108 | typedef CreatePrimaryRequest<MockTestImageCtx> MockCreatePrimaryRequest; | |
109 | typedef UnlinkPeerRequest<MockTestImageCtx> MockUnlinkPeerRequest; | |
110 | typedef util::Mock MockUtils; | |
111 | ||
112 | uint64_t m_snap_seq = 0; | |
113 | ||
114 | void snap_create(MockTestImageCtx &mock_image_ctx, | |
115 | const cls::rbd::SnapshotNamespace &ns, | |
116 | const std::string& snap_name) { | |
117 | ASSERT_TRUE(mock_image_ctx.snap_info.insert( | |
118 | {m_snap_seq++, | |
119 | SnapInfo{snap_name, ns, 0, {}, 0, 0, {}}}).second); | |
120 | } | |
121 | ||
122 | void expect_clone_md_ctx(MockTestImageCtx &mock_image_ctx) { | |
123 | EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), clone()) | |
124 | .WillOnce(Invoke([&mock_image_ctx]() { | |
125 | get_mock_io_ctx(mock_image_ctx.md_ctx).get(); | |
126 | return &get_mock_io_ctx(mock_image_ctx.md_ctx); | |
127 | })); | |
128 | } | |
129 | ||
130 | void expect_can_create_primary_snapshot(MockUtils &mock_utils, bool demoted, | |
131 | bool force, bool result) { | |
132 | EXPECT_CALL(mock_utils, | |
133 | can_create_primary_snapshot(_, demoted, force, nullptr)) | |
134 | .WillOnce(Return(result)); | |
135 | } | |
136 | ||
137 | void expect_get_mirror_peers(MockTestImageCtx &mock_image_ctx, | |
138 | const std::vector<cls::rbd::MirrorPeer> &peers, | |
139 | int r) { | |
140 | using ceph::encode; | |
141 | bufferlist bl; | |
142 | encode(peers, bl); | |
143 | ||
144 | EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), | |
145 | exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_peer_list"), | |
f67539c2 | 146 | _, _, _, _)) |
9f95a23c TL |
147 | .WillOnce(DoAll(WithArg<5>(CopyInBufferlist(bl)), |
148 | Return(r))); | |
149 | } | |
150 | ||
151 | void expect_create_snapshot(MockTestImageCtx &mock_image_ctx, int r) { | |
f67539c2 | 152 | EXPECT_CALL(*mock_image_ctx.operations, snap_create(_, _, _, _, _)) |
9f95a23c TL |
153 | .WillOnce(DoAll( |
154 | Invoke([this, &mock_image_ctx, r]( | |
155 | const cls::rbd::SnapshotNamespace &ns, | |
156 | const std::string& snap_name, | |
f67539c2 TL |
157 | uint64_t flags, |
158 | ProgressContext &prog_ctx, | |
9f95a23c TL |
159 | Context *on_finish) { |
160 | if (r != 0) { | |
161 | return; | |
162 | } | |
1e59de90 TL |
163 | auto mirror_ns = |
164 | std::get<cls::rbd::MirrorSnapshotNamespace>(ns); | |
165 | mirror_ns.complete = true; | |
166 | snap_create(mock_image_ctx, mirror_ns, snap_name); | |
9f95a23c | 167 | }), |
f67539c2 | 168 | WithArg<4>(CompleteContext( |
9f95a23c TL |
169 | r, mock_image_ctx.image_ctx->op_work_queue)) |
170 | )); | |
171 | } | |
172 | ||
1e59de90 TL |
173 | void expect_refresh_image(MockTestImageCtx &mock_image_ctx, int r) { |
174 | EXPECT_CALL(*mock_image_ctx.state, refresh(_)) | |
175 | .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)); | |
176 | } | |
177 | ||
9f95a23c TL |
178 | void expect_unlink_peer(MockTestImageCtx &mock_image_ctx, |
179 | MockUnlinkPeerRequest &mock_unlink_peer_request, | |
180 | uint64_t snap_id, const std::string &peer_uuid, | |
1e59de90 TL |
181 | bool is_linked, bool complete, bool allow_remove, |
182 | int r) { | |
9f95a23c | 183 | EXPECT_CALL(mock_unlink_peer_request, send()) |
b3b6e05e | 184 | .WillOnce(Invoke([&mock_image_ctx, &mock_unlink_peer_request, |
1e59de90 | 185 | snap_id, peer_uuid, is_linked, complete, allow_remove, r]() { |
9f95a23c TL |
186 | ASSERT_EQ(mock_unlink_peer_request.mirror_peer_uuid, |
187 | peer_uuid); | |
188 | ASSERT_EQ(mock_unlink_peer_request.snap_id, snap_id); | |
1e59de90 | 189 | ASSERT_EQ(mock_unlink_peer_request.allow_remove, allow_remove); |
9f95a23c TL |
190 | if (r == 0) { |
191 | auto it = mock_image_ctx.snap_info.find(snap_id); | |
192 | ASSERT_NE(it, mock_image_ctx.snap_info.end()); | |
193 | auto info = | |
1e59de90 | 194 | std::get_if<cls::rbd::MirrorSnapshotNamespace>( |
9f95a23c TL |
195 | &it->second.snap_namespace); |
196 | ASSERT_NE(nullptr, info); | |
1e59de90 | 197 | ASSERT_EQ(complete, info->complete); |
b3b6e05e TL |
198 | ASSERT_EQ(is_linked, info->mirror_peer_uuids.erase( |
199 | peer_uuid)); | |
9f95a23c TL |
200 | if (info->mirror_peer_uuids.empty()) { |
201 | mock_image_ctx.snap_info.erase(it); | |
202 | } | |
203 | } | |
204 | mock_image_ctx.image_ctx->op_work_queue->queue( | |
205 | mock_unlink_peer_request.on_finish, r); | |
206 | })); | |
207 | } | |
208 | }; | |
209 | ||
210 | TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, Success) { | |
211 | REQUIRE_FORMAT_V2(); | |
212 | ||
213 | librbd::ImageCtx *ictx; | |
214 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
215 | ||
216 | MockTestImageCtx mock_image_ctx(*ictx); | |
217 | ||
218 | InSequence seq; | |
219 | ||
220 | expect_clone_md_ctx(mock_image_ctx); | |
221 | MockUtils mock_utils; | |
222 | expect_can_create_primary_snapshot(mock_utils, false, false, true); | |
223 | expect_get_mirror_peers(mock_image_ctx, | |
224 | {{"uuid", cls::rbd::MIRROR_PEER_DIRECTION_TX, "ceph", | |
225 | "mirror", "mirror uuid"}}, 0); | |
226 | expect_create_snapshot(mock_image_ctx, 0); | |
1e59de90 | 227 | expect_refresh_image(mock_image_ctx, 0); |
9f95a23c TL |
228 | |
229 | C_SaferCond ctx; | |
1911f103 | 230 | auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP, |
f67539c2 | 231 | 0U, 0U, nullptr, &ctx); |
9f95a23c TL |
232 | req->send(); |
233 | ASSERT_EQ(0, ctx.wait()); | |
234 | } | |
235 | ||
236 | TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, CanNotError) { | |
237 | REQUIRE_FORMAT_V2(); | |
238 | ||
239 | librbd::ImageCtx *ictx; | |
240 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
241 | ||
242 | MockTestImageCtx mock_image_ctx(*ictx); | |
243 | ||
244 | InSequence seq; | |
245 | ||
246 | expect_clone_md_ctx(mock_image_ctx); | |
247 | MockUtils mock_utils; | |
248 | expect_can_create_primary_snapshot(mock_utils, false, false, false); | |
249 | ||
250 | C_SaferCond ctx; | |
1911f103 | 251 | auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP, |
f67539c2 | 252 | 0U, 0U, nullptr, &ctx); |
9f95a23c TL |
253 | req->send(); |
254 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
255 | } | |
256 | ||
257 | TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, GetMirrorPeersError) { | |
258 | REQUIRE_FORMAT_V2(); | |
259 | ||
260 | librbd::ImageCtx *ictx; | |
261 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
262 | ||
263 | MockTestImageCtx mock_image_ctx(*ictx); | |
264 | ||
265 | InSequence seq; | |
266 | ||
267 | expect_clone_md_ctx(mock_image_ctx); | |
268 | MockUtils mock_utils; | |
269 | expect_can_create_primary_snapshot(mock_utils, false, false, true); | |
270 | expect_get_mirror_peers(mock_image_ctx, | |
271 | {{"uuid", cls::rbd::MIRROR_PEER_DIRECTION_TX, "ceph", | |
272 | "mirror", "mirror uuid"}}, -EINVAL); | |
273 | ||
274 | C_SaferCond ctx; | |
1911f103 | 275 | auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP, |
f67539c2 | 276 | 0U, 0U, nullptr, &ctx); |
9f95a23c TL |
277 | req->send(); |
278 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
279 | } | |
280 | ||
281 | TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, CreateSnapshotError) { | |
282 | REQUIRE_FORMAT_V2(); | |
283 | ||
284 | librbd::ImageCtx *ictx; | |
285 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
286 | ||
287 | MockTestImageCtx mock_image_ctx(*ictx); | |
288 | ||
289 | InSequence seq; | |
290 | ||
291 | expect_clone_md_ctx(mock_image_ctx); | |
292 | MockUtils mock_utils; | |
293 | expect_can_create_primary_snapshot(mock_utils, false, false, true); | |
294 | expect_get_mirror_peers(mock_image_ctx, | |
295 | {{"uuid", cls::rbd::MIRROR_PEER_DIRECTION_TX, "ceph", | |
296 | "mirror", "mirror uuid"}}, 0); | |
297 | expect_create_snapshot(mock_image_ctx, -EINVAL); | |
298 | ||
299 | C_SaferCond ctx; | |
1911f103 | 300 | auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP, |
f67539c2 | 301 | 0U, 0U, nullptr, &ctx); |
9f95a23c TL |
302 | req->send(); |
303 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
304 | } | |
305 | ||
1e59de90 TL |
306 | TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, SuccessUnlinkIncomplete) { |
307 | REQUIRE_FORMAT_V2(); | |
308 | ||
309 | librbd::ImageCtx *ictx; | |
310 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
311 | ictx->config.set_val("rbd_mirroring_max_mirroring_snapshots", "3"); | |
312 | ||
313 | MockTestImageCtx mock_image_ctx(*ictx); | |
314 | cls::rbd::MirrorSnapshotNamespace ns{ | |
315 | cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {"uuid"}, "", CEPH_NOSNAP}; | |
316 | ns.complete = false; | |
317 | snap_create(mock_image_ctx, ns, "mirror_snap"); | |
318 | ||
319 | InSequence seq; | |
320 | ||
321 | expect_clone_md_ctx(mock_image_ctx); | |
322 | MockUtils mock_utils; | |
323 | expect_can_create_primary_snapshot(mock_utils, false, false, true); | |
324 | expect_get_mirror_peers(mock_image_ctx, | |
325 | {{"uuid", cls::rbd::MIRROR_PEER_DIRECTION_TX, "ceph", | |
326 | "mirror", "mirror uuid"}}, 0); | |
327 | expect_create_snapshot(mock_image_ctx, 0); | |
328 | expect_refresh_image(mock_image_ctx, 0); | |
329 | MockUnlinkPeerRequest mock_unlink_peer_request; | |
330 | auto it = mock_image_ctx.snap_info.rbegin(); | |
331 | auto snap_id = it->first; | |
332 | expect_unlink_peer(mock_image_ctx, mock_unlink_peer_request, snap_id, "uuid", | |
333 | true, false, true, 0); | |
334 | C_SaferCond ctx; | |
335 | auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP, | |
336 | 0U, 0U, nullptr, &ctx); | |
337 | req->send(); | |
338 | ASSERT_EQ(0, ctx.wait()); | |
339 | } | |
340 | ||
9f95a23c TL |
341 | TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, SuccessUnlinkPeer) { |
342 | REQUIRE_FORMAT_V2(); | |
343 | ||
344 | librbd::ImageCtx *ictx; | |
345 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
2a845540 | 346 | ictx->config.set_val("rbd_mirroring_max_mirroring_snapshots", "3"); |
9f95a23c TL |
347 | |
348 | MockTestImageCtx mock_image_ctx(*ictx); | |
349 | for (int i = 0; i < 3; i++) { | |
350 | cls::rbd::MirrorSnapshotNamespace ns{ | |
351 | cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {"uuid"}, "", CEPH_NOSNAP}; | |
1e59de90 | 352 | ns.complete = true; |
9f95a23c TL |
353 | snap_create(mock_image_ctx, ns, "mirror_snap"); |
354 | } | |
355 | ||
356 | InSequence seq; | |
357 | ||
358 | expect_clone_md_ctx(mock_image_ctx); | |
359 | MockUtils mock_utils; | |
360 | expect_can_create_primary_snapshot(mock_utils, false, false, true); | |
361 | expect_get_mirror_peers(mock_image_ctx, | |
362 | {{"uuid", cls::rbd::MIRROR_PEER_DIRECTION_TX, "ceph", | |
363 | "mirror", "mirror uuid"}}, 0); | |
364 | expect_create_snapshot(mock_image_ctx, 0); | |
1e59de90 | 365 | expect_refresh_image(mock_image_ctx, 0); |
9f95a23c TL |
366 | MockUnlinkPeerRequest mock_unlink_peer_request; |
367 | auto it = mock_image_ctx.snap_info.rbegin(); | |
f67539c2 | 368 | auto snap_id = it->first; |
9f95a23c | 369 | expect_unlink_peer(mock_image_ctx, mock_unlink_peer_request, snap_id, "uuid", |
1e59de90 | 370 | true, true, true, 0); |
b3b6e05e TL |
371 | C_SaferCond ctx; |
372 | auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP, | |
373 | 0U, 0U, nullptr, &ctx); | |
374 | req->send(); | |
375 | ASSERT_EQ(0, ctx.wait()); | |
376 | } | |
377 | ||
378 | TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, SuccessUnlinkNoPeer) { | |
379 | REQUIRE_FORMAT_V2(); | |
380 | ||
381 | librbd::ImageCtx *ictx; | |
382 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
2a845540 | 383 | ictx->config.set_val("rbd_mirroring_max_mirroring_snapshots", "3"); |
b3b6e05e TL |
384 | |
385 | MockTestImageCtx mock_image_ctx(*ictx); | |
386 | cls::rbd::MirrorSnapshotNamespace ns{ | |
387 | cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {}, "", CEPH_NOSNAP}; | |
1e59de90 | 388 | ns.complete = true; |
b3b6e05e TL |
389 | snap_create(mock_image_ctx, ns, "mirror_snap"); |
390 | ||
391 | InSequence seq; | |
392 | ||
393 | expect_clone_md_ctx(mock_image_ctx); | |
394 | MockUtils mock_utils; | |
395 | expect_can_create_primary_snapshot(mock_utils, false, false, true); | |
396 | expect_get_mirror_peers(mock_image_ctx, | |
397 | {{"uuid", cls::rbd::MIRROR_PEER_DIRECTION_TX, "ceph", | |
398 | "mirror", "mirror uuid"}}, 0); | |
399 | expect_create_snapshot(mock_image_ctx, 0); | |
1e59de90 | 400 | expect_refresh_image(mock_image_ctx, 0); |
b3b6e05e TL |
401 | MockUnlinkPeerRequest mock_unlink_peer_request; |
402 | auto it = mock_image_ctx.snap_info.rbegin(); | |
403 | auto snap_id = it->first; | |
b3b6e05e | 404 | expect_unlink_peer(mock_image_ctx, mock_unlink_peer_request, snap_id, "uuid", |
1e59de90 | 405 | false, true, true, 0); |
b3b6e05e TL |
406 | |
407 | C_SaferCond ctx; | |
408 | auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP, | |
409 | 0U, 0U, nullptr, &ctx); | |
410 | req->send(); | |
411 | ASSERT_EQ(0, ctx.wait()); | |
412 | } | |
413 | ||
414 | TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, SuccessUnlinkMultiplePeers) { | |
415 | REQUIRE_FORMAT_V2(); | |
416 | ||
417 | librbd::ImageCtx *ictx; | |
418 | ASSERT_EQ(0, open_image(m_image_name, &ictx)); | |
2a845540 | 419 | ictx->config.set_val("rbd_mirroring_max_mirroring_snapshots", "3"); |
b3b6e05e TL |
420 | |
421 | MockTestImageCtx mock_image_ctx(*ictx); | |
422 | for (int i = 0; i < 3; i++) { | |
423 | cls::rbd::MirrorSnapshotNamespace ns{ | |
424 | cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY, {"uuid1", "uuid2"}, "", | |
425 | CEPH_NOSNAP}; | |
1e59de90 | 426 | ns.complete = true; |
b3b6e05e TL |
427 | snap_create(mock_image_ctx, ns, "mirror_snap"); |
428 | } | |
429 | ||
430 | InSequence seq; | |
431 | ||
432 | expect_clone_md_ctx(mock_image_ctx); | |
433 | MockUtils mock_utils; | |
434 | expect_can_create_primary_snapshot(mock_utils, false, false, true); | |
435 | expect_get_mirror_peers(mock_image_ctx, | |
436 | {{"uuid1", cls::rbd::MIRROR_PEER_DIRECTION_TX, "ceph", | |
437 | "mirror", "mirror uuid"}, | |
438 | {"uuid2", cls::rbd::MIRROR_PEER_DIRECTION_TX, "ceph", | |
439 | "mirror", "mirror uuid"}}, 0); | |
440 | expect_create_snapshot(mock_image_ctx, 0); | |
1e59de90 | 441 | expect_refresh_image(mock_image_ctx, 0); |
b3b6e05e TL |
442 | MockUnlinkPeerRequest mock_unlink_peer_request; |
443 | auto it = mock_image_ctx.snap_info.rbegin(); | |
444 | auto snap_id = it->first; | |
445 | expect_unlink_peer(mock_image_ctx, mock_unlink_peer_request, snap_id, "uuid1", | |
1e59de90 | 446 | true, true, true, 0); |
b3b6e05e | 447 | expect_unlink_peer(mock_image_ctx, mock_unlink_peer_request, snap_id, "uuid2", |
1e59de90 | 448 | true, true, true, 0); |
9f95a23c | 449 | C_SaferCond ctx; |
1911f103 | 450 | auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP, |
f67539c2 | 451 | 0U, 0U, nullptr, &ctx); |
9f95a23c TL |
452 | req->send(); |
453 | ASSERT_EQ(0, ctx.wait()); | |
454 | } | |
455 | ||
456 | } // namespace snapshot | |
457 | } // namespace mirror | |
458 | } // namespace librbd | |
459 |