]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/journal/test_mock_Replay.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / test / librbd / journal / test_mock_Replay.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 "librbd/io/ImageRequest.h"
8 #include "librbd/journal/Replay.h"
9 #include "librbd/journal/Types.h"
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
12 #include <boost/scope_exit.hpp>
13
14 namespace librbd {
15
16 namespace {
17
18 struct MockReplayImageCtx : public MockImageCtx {
19 explicit MockReplayImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
20 }
21 };
22
23 } // anonymous namespace
24
25 namespace io {
26
27 template <>
28 struct ImageRequest<MockReplayImageCtx> {
29 static ImageRequest *s_instance;
30
31 MOCK_METHOD4(aio_write, void(AioCompletion *c, const Extents &image_extents,
32 const bufferlist &bl, int op_flags));
33 static void aio_write(MockReplayImageCtx *ictx, AioCompletion *c,
34 Extents&& image_extents, ImageArea area,
35 bufferlist&& bl, int op_flags,
36 const ZTracer::Trace &parent_trace) {
37 ceph_assert(s_instance != nullptr);
38 s_instance->aio_write(c, image_extents, bl, op_flags);
39 }
40
41 MOCK_METHOD3(aio_discard, void(AioCompletion *c, const Extents& image_extents,
42 uint32_t discard_granularity_bytes));
43 static void aio_discard(MockReplayImageCtx *ictx, AioCompletion *c,
44 Extents&& image_extents, ImageArea area,
45 uint32_t discard_granularity_bytes,
46 const ZTracer::Trace &parent_trace) {
47 ceph_assert(s_instance != nullptr);
48 s_instance->aio_discard(c, image_extents, discard_granularity_bytes);
49 }
50
51 MOCK_METHOD1(aio_flush, void(AioCompletion *c));
52 static void aio_flush(MockReplayImageCtx *ictx, AioCompletion *c,
53 FlushSource, const ZTracer::Trace &parent_trace) {
54 ceph_assert(s_instance != nullptr);
55 s_instance->aio_flush(c);
56 }
57
58 MOCK_METHOD4(aio_writesame, void(AioCompletion *c,
59 const Extents& image_extents,
60 const bufferlist &bl,
61 int op_flags));
62 static void aio_writesame(MockReplayImageCtx *ictx, AioCompletion *c,
63 Extents&& image_extents, ImageArea area,
64 bufferlist&& bl, int op_flags,
65 const ZTracer::Trace &parent_trace) {
66 ceph_assert(s_instance != nullptr);
67 s_instance->aio_writesame(c, image_extents, bl, op_flags);
68 }
69
70 MOCK_METHOD6(aio_compare_and_write, void(AioCompletion *c, const Extents &image_extents,
71 const bufferlist &cmp_bl, const bufferlist &bl,
72 uint64_t *mismatch_offset,
73 int op_flags));
74 static void aio_compare_and_write(MockReplayImageCtx *ictx, AioCompletion *c,
75 Extents&& image_extents, ImageArea area,
76 bufferlist&& cmp_bl, bufferlist&& bl,
77 uint64_t* mismatch_offset, int op_flags,
78 const ZTracer::Trace &parent_trace) {
79 ceph_assert(s_instance != nullptr);
80 s_instance->aio_compare_and_write(c, image_extents, cmp_bl, bl,
81 mismatch_offset, op_flags);
82 }
83
84 ImageRequest() {
85 s_instance = this;
86 }
87 };
88
89 ImageRequest<MockReplayImageCtx> *ImageRequest<MockReplayImageCtx>::s_instance = nullptr;
90
91 } // namespace io
92
93 namespace util {
94
95 inline ImageCtx *get_image_ctx(librbd::MockReplayImageCtx *image_ctx) {
96 return image_ctx->image_ctx;
97 }
98
99 } // namespace util
100
101 } // namespace librbd
102
103 // template definitions
104 #include "librbd/journal/Replay.cc"
105 template class librbd::journal::Replay<librbd::MockReplayImageCtx>;
106
107 using ::testing::_;
108 using ::testing::DoAll;
109 using ::testing::InSequence;
110 using ::testing::Return;
111 using ::testing::SaveArg;
112 using ::testing::StrEq;
113 using ::testing::WithArgs;
114
115 MATCHER_P(BufferlistEqual, str, "") {
116 bufferlist bl(arg);
117 return (strncmp(bl.c_str(), str, strlen(str)) == 0);
118 }
119
120 MATCHER_P(CStrEq, str, "") {
121 return (strncmp(arg, str, strlen(str)) == 0);
122 }
123
124 ACTION_P2(NotifyInvoke, lock, cond) {
125 std::lock_guard locker{*lock};
126 cond->notify_all();
127 }
128
129 ACTION_P2(CompleteAioCompletion, r, image_ctx) {
130 image_ctx->op_work_queue->queue(new LambdaContext([this, arg0](int r) {
131 arg0->get();
132 arg0->init_time(image_ctx, librbd::io::AIO_TYPE_NONE);
133 arg0->set_request_count(1);
134 arg0->complete_request(r);
135 }), r);
136 }
137
138 namespace librbd {
139 namespace journal {
140
141 class TestMockJournalReplay : public TestMockFixture {
142 public:
143 typedef io::ImageRequest<MockReplayImageCtx> MockIoImageRequest;
144 typedef Replay<MockReplayImageCtx> MockJournalReplay;
145
146 TestMockJournalReplay() = default;
147
148 void expect_accept_ops(MockExclusiveLock &mock_exclusive_lock, bool accept) {
149 EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillRepeatedly(
150 Return(accept));
151 }
152
153 void expect_aio_discard(MockIoImageRequest &mock_io_image_request,
154 io::AioCompletion **aio_comp, uint64_t off,
155 uint64_t len, uint32_t discard_granularity_bytes) {
156 EXPECT_CALL(mock_io_image_request, aio_discard(_, io::Extents{{off, len}},
157 discard_granularity_bytes))
158 .WillOnce(SaveArg<0>(aio_comp));
159 }
160
161 void expect_aio_flush(MockIoImageRequest &mock_io_image_request,
162 io::AioCompletion **aio_comp) {
163 EXPECT_CALL(mock_io_image_request, aio_flush(_))
164 .WillOnce(SaveArg<0>(aio_comp));
165 }
166
167 void expect_aio_flush(MockReplayImageCtx &mock_image_ctx,
168 MockIoImageRequest &mock_io_image_request, int r) {
169 EXPECT_CALL(mock_io_image_request, aio_flush(_))
170 .WillOnce(CompleteAioCompletion(r, mock_image_ctx.image_ctx));
171 }
172
173 void expect_aio_write(MockIoImageRequest &mock_io_image_request,
174 io::AioCompletion **aio_comp, uint64_t off,
175 uint64_t len, const char *data) {
176 EXPECT_CALL(mock_io_image_request,
177 aio_write(_, io::Extents{{off, len}}, BufferlistEqual(data), _))
178 .WillOnce(SaveArg<0>(aio_comp));
179 }
180
181 void expect_aio_writesame(MockIoImageRequest &mock_io_image_request,
182 io::AioCompletion **aio_comp, uint64_t off,
183 uint64_t len, const char *data) {
184 EXPECT_CALL(mock_io_image_request,
185 aio_writesame(_, io::Extents{{off, len}},
186 BufferlistEqual(data), _))
187 .WillOnce(SaveArg<0>(aio_comp));
188 }
189
190 void expect_aio_compare_and_write(MockIoImageRequest &mock_io_image_request,
191 io::AioCompletion **aio_comp, uint64_t off,
192 uint64_t len, const char *cmp_data,
193 const char *data,
194 uint64_t *mismatch_offset) {
195 EXPECT_CALL(mock_io_image_request,
196 aio_compare_and_write(_, io::Extents{{off, len}},
197 BufferlistEqual(cmp_data),
198 BufferlistEqual(data),
199 mismatch_offset, _))
200 .WillOnce(SaveArg<0>(aio_comp));
201 }
202
203 void expect_flatten(MockReplayImageCtx &mock_image_ctx, Context **on_finish) {
204 EXPECT_CALL(*mock_image_ctx.operations, execute_flatten(_, _))
205 .WillOnce(DoAll(SaveArg<1>(on_finish),
206 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
207 }
208
209 void expect_rename(MockReplayImageCtx &mock_image_ctx, Context **on_finish,
210 const char *image_name) {
211 EXPECT_CALL(*mock_image_ctx.operations, execute_rename(StrEq(image_name), _))
212 .WillOnce(DoAll(SaveArg<1>(on_finish),
213 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
214 }
215
216 void expect_resize(MockReplayImageCtx &mock_image_ctx, Context **on_finish,
217 uint64_t size, uint64_t op_tid) {
218 EXPECT_CALL(*mock_image_ctx.operations, execute_resize(size, _, _, _, op_tid))
219 .WillOnce(DoAll(SaveArg<3>(on_finish),
220 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
221 }
222
223 void expect_snap_create(MockReplayImageCtx &mock_image_ctx,
224 Context **on_finish, const char *snap_name,
225 uint64_t op_tid) {
226 EXPECT_CALL(*mock_image_ctx.operations,
227 execute_snap_create(_, StrEq(snap_name), _, op_tid,
228 SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE, _))
229 .WillOnce(DoAll(SaveArg<2>(on_finish),
230 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
231 }
232
233 void expect_snap_remove(MockReplayImageCtx &mock_image_ctx,
234 Context **on_finish, const char *snap_name) {
235 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_remove(_, StrEq(snap_name), _))
236 .WillOnce(DoAll(SaveArg<2>(on_finish),
237 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
238 }
239
240 void expect_snap_rename(MockReplayImageCtx &mock_image_ctx,
241 Context **on_finish, uint64_t snap_id,
242 const char *snap_name) {
243 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_rename(snap_id, StrEq(snap_name), _))
244 .WillOnce(DoAll(SaveArg<2>(on_finish),
245 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
246 }
247
248 void expect_snap_protect(MockReplayImageCtx &mock_image_ctx,
249 Context **on_finish, const char *snap_name) {
250 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_protect(_, StrEq(snap_name), _))
251 .WillOnce(DoAll(SaveArg<2>(on_finish),
252 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
253 }
254
255 void expect_snap_unprotect(MockReplayImageCtx &mock_image_ctx,
256 Context **on_finish, const char *snap_name) {
257 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_unprotect(_, StrEq(snap_name), _))
258 .WillOnce(DoAll(SaveArg<2>(on_finish),
259 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
260 }
261
262 void expect_snap_rollback(MockReplayImageCtx &mock_image_ctx,
263 Context **on_finish, const char *snap_name) {
264 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_rollback(_, StrEq(snap_name), _, _))
265 .WillOnce(DoAll(SaveArg<3>(on_finish),
266 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
267 }
268
269 void expect_update_features(MockReplayImageCtx &mock_image_ctx, Context **on_finish,
270 uint64_t features, bool enabled, uint64_t op_tid) {
271 EXPECT_CALL(*mock_image_ctx.operations, execute_update_features(features, enabled, _, op_tid))
272 .WillOnce(DoAll(SaveArg<2>(on_finish),
273 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
274 }
275
276 void expect_metadata_set(MockReplayImageCtx &mock_image_ctx,
277 Context **on_finish, const char *key,
278 const char *value) {
279 EXPECT_CALL(*mock_image_ctx.operations, execute_metadata_set(StrEq(key),
280 StrEq(value), _))
281 .WillOnce(DoAll(SaveArg<2>(on_finish),
282 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
283 }
284
285 void expect_metadata_remove(MockReplayImageCtx &mock_image_ctx,
286 Context **on_finish, const char *key) {
287 EXPECT_CALL(*mock_image_ctx.operations, execute_metadata_remove(StrEq(key), _))
288 .WillOnce(DoAll(SaveArg<1>(on_finish),
289 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
290 }
291
292 void expect_refresh_image(MockReplayImageCtx &mock_image_ctx, bool required,
293 int r) {
294 EXPECT_CALL(*mock_image_ctx.state, is_refresh_required())
295 .WillOnce(Return(required));
296 if (required) {
297 EXPECT_CALL(*mock_image_ctx.state, refresh(_))
298 .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
299 }
300 }
301
302 void when_process(MockJournalReplay &mock_journal_replay,
303 EventEntry &&event_entry, Context *on_ready,
304 Context *on_safe) {
305 bufferlist bl;
306 encode(event_entry, bl);
307
308 auto it = bl.cbegin();
309 when_process(mock_journal_replay, &it, on_ready, on_safe);
310 }
311
312 void when_process(MockJournalReplay &mock_journal_replay,
313 bufferlist::const_iterator *it, Context *on_ready,
314 Context *on_safe) {
315 EventEntry event_entry;
316 int r = mock_journal_replay.decode(it, &event_entry);
317 ASSERT_EQ(0, r);
318
319 mock_journal_replay.process(event_entry, on_ready, on_safe);
320 }
321
322 void when_complete(MockReplayImageCtx &mock_image_ctx,
323 io::AioCompletion *aio_comp, int r) {
324 aio_comp->get();
325 aio_comp->init_time(mock_image_ctx.image_ctx, librbd::io::AIO_TYPE_NONE);
326 aio_comp->set_request_count(1);
327 aio_comp->complete_request(r);
328 }
329
330 int when_flush(MockJournalReplay &mock_journal_replay) {
331 C_SaferCond ctx;
332 mock_journal_replay.flush(&ctx);
333 return ctx.wait();
334 }
335
336 int when_shut_down(MockJournalReplay &mock_journal_replay, bool cancel_ops) {
337 C_SaferCond ctx;
338 mock_journal_replay.shut_down(cancel_ops, &ctx);
339 return ctx.wait();
340 }
341
342 void when_replay_op_ready(MockJournalReplay &mock_journal_replay,
343 uint64_t op_tid, Context *on_resume) {
344 mock_journal_replay.replay_op_ready(op_tid, on_resume);
345 }
346
347 void wait_for_op_invoked(Context **on_finish, int r) {
348 {
349 std::unique_lock locker{m_invoke_lock};
350 m_invoke_cond.wait(locker, [on_finish] { return *on_finish != nullptr; });
351 }
352 (*on_finish)->complete(r);
353 }
354
355 bufferlist to_bl(const std::string &str) {
356 bufferlist bl;
357 bl.append(str);
358 return bl;
359 }
360
361 ceph::mutex m_invoke_lock = ceph::make_mutex("m_invoke_lock");
362 ceph::condition_variable m_invoke_cond;
363 };
364
365 TEST_F(TestMockJournalReplay, AioDiscard) {
366 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
367
368 librbd::ImageCtx *ictx;
369 ASSERT_EQ(0, open_image(m_image_name, &ictx));
370
371 MockReplayImageCtx mock_image_ctx(*ictx);
372
373 MockExclusiveLock mock_exclusive_lock;
374 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
375 expect_accept_ops(mock_exclusive_lock, true);
376
377 MockJournalReplay mock_journal_replay(mock_image_ctx);
378 MockIoImageRequest mock_io_image_request;
379 expect_op_work_queue(mock_image_ctx);
380
381 InSequence seq;
382 io::AioCompletion *aio_comp;
383 C_SaferCond on_ready;
384 C_SaferCond on_safe;
385 expect_aio_discard(mock_io_image_request, &aio_comp, 123, 456,
386 ictx->discard_granularity_bytes);
387 when_process(mock_journal_replay,
388 EventEntry{AioDiscardEvent(123, 456,
389 ictx->discard_granularity_bytes)},
390 &on_ready, &on_safe);
391
392 when_complete(mock_image_ctx, aio_comp, 0);
393 ASSERT_EQ(0, on_ready.wait());
394
395 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
396 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
397 ASSERT_EQ(0, on_safe.wait());
398 }
399
400 TEST_F(TestMockJournalReplay, AioWrite) {
401 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
402
403 librbd::ImageCtx *ictx;
404 ASSERT_EQ(0, open_image(m_image_name, &ictx));
405
406 MockReplayImageCtx mock_image_ctx(*ictx);
407
408 MockExclusiveLock mock_exclusive_lock;
409 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
410 expect_accept_ops(mock_exclusive_lock, true);
411
412 MockJournalReplay mock_journal_replay(mock_image_ctx);
413 MockIoImageRequest mock_io_image_request;
414 expect_op_work_queue(mock_image_ctx);
415
416 InSequence seq;
417 io::AioCompletion *aio_comp;
418 C_SaferCond on_ready;
419 C_SaferCond on_safe;
420 expect_aio_write(mock_io_image_request, &aio_comp, 123, 456, "test");
421 when_process(mock_journal_replay,
422 EventEntry{AioWriteEvent(123, 456, to_bl("test"))},
423 &on_ready, &on_safe);
424
425 when_complete(mock_image_ctx, aio_comp, 0);
426 ASSERT_EQ(0, on_ready.wait());
427
428 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
429 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
430 ASSERT_EQ(0, on_safe.wait());
431 }
432
433 TEST_F(TestMockJournalReplay, AioFlush) {
434 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
435
436 librbd::ImageCtx *ictx;
437 ASSERT_EQ(0, open_image(m_image_name, &ictx));
438
439 MockReplayImageCtx mock_image_ctx(*ictx);
440
441 MockExclusiveLock mock_exclusive_lock;
442 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
443 expect_accept_ops(mock_exclusive_lock, true);
444
445 MockJournalReplay mock_journal_replay(mock_image_ctx);
446 MockIoImageRequest mock_io_image_request;
447 expect_op_work_queue(mock_image_ctx);
448
449 InSequence seq;
450 io::AioCompletion *aio_comp;
451 C_SaferCond on_ready;
452 C_SaferCond on_safe;
453 expect_aio_flush(mock_io_image_request, &aio_comp);
454 when_process(mock_journal_replay, EventEntry{AioFlushEvent()},
455 &on_ready, &on_safe);
456
457 when_complete(mock_image_ctx, aio_comp, 0);
458 ASSERT_EQ(0, on_safe.wait());
459
460 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
461 ASSERT_EQ(0, on_ready.wait());
462 }
463
464 TEST_F(TestMockJournalReplay, AioWriteSame) {
465 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
466
467 librbd::ImageCtx *ictx;
468 ASSERT_EQ(0, open_image(m_image_name, &ictx));
469
470 MockReplayImageCtx mock_image_ctx(*ictx);
471
472 MockExclusiveLock mock_exclusive_lock;
473 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
474 expect_accept_ops(mock_exclusive_lock, true);
475
476 MockJournalReplay mock_journal_replay(mock_image_ctx);
477 MockIoImageRequest mock_io_image_request;
478 expect_op_work_queue(mock_image_ctx);
479
480 InSequence seq;
481 io::AioCompletion *aio_comp;
482 C_SaferCond on_ready;
483 C_SaferCond on_safe;
484 expect_aio_writesame(mock_io_image_request, &aio_comp, 123, 456, "333");
485 when_process(mock_journal_replay,
486 EventEntry{AioWriteSameEvent(123, 456, to_bl("333"))},
487 &on_ready, &on_safe);
488
489 when_complete(mock_image_ctx, aio_comp, 0);
490 ASSERT_EQ(0, on_ready.wait());
491
492 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
493 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
494 ASSERT_EQ(0, on_safe.wait());
495 }
496
497
498 TEST_F(TestMockJournalReplay, AioCompareAndWrite) {
499 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
500
501 librbd::ImageCtx *ictx;
502 ASSERT_EQ(0, open_image(m_image_name, &ictx));
503
504 MockReplayImageCtx mock_image_ctx(*ictx);
505
506 MockExclusiveLock mock_exclusive_lock;
507 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
508 expect_accept_ops(mock_exclusive_lock, true);
509
510 MockJournalReplay mock_write_journal_replay(mock_image_ctx);
511 MockJournalReplay mock_compare_and_write_journal_replay(mock_image_ctx);
512 MockJournalReplay mock_mis_compare_and_write_journal_replay(mock_image_ctx);
513 MockIoImageRequest mock_io_image_request;
514 expect_op_work_queue(mock_image_ctx);
515
516 InSequence seq;
517 io::AioCompletion *aio_comp;
518 C_SaferCond on_ready;
519 C_SaferCond on_safe;
520 expect_aio_write(mock_io_image_request, &aio_comp, 512, 512, "test");
521 when_process(mock_write_journal_replay,
522 EventEntry{AioWriteEvent(512, 512, to_bl("test"))},
523 &on_ready, &on_safe);
524
525 when_complete(mock_image_ctx, aio_comp, 0);
526 ASSERT_EQ(0, on_ready.wait());
527
528 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
529 ASSERT_EQ(0, when_shut_down(mock_write_journal_replay, false));
530 ASSERT_EQ(0, on_safe.wait());
531
532 expect_aio_compare_and_write(mock_io_image_request, &aio_comp,
533 512, 512, "test", "test", nullptr);
534 when_process(mock_compare_and_write_journal_replay,
535 EventEntry{AioCompareAndWriteEvent(512, 512, to_bl("test"),
536 to_bl("test"))}, &on_ready, &on_safe);
537
538 when_complete(mock_image_ctx, aio_comp, 0);
539 ASSERT_EQ(0, on_ready.wait());
540
541 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
542 ASSERT_EQ(0, when_shut_down(mock_compare_and_write_journal_replay, false));
543 ASSERT_EQ(0, on_safe.wait());
544
545 expect_aio_compare_and_write(mock_io_image_request, &aio_comp,
546 512, 512, "111", "test", nullptr);
547 when_process(mock_mis_compare_and_write_journal_replay,
548 EventEntry{AioCompareAndWriteEvent(512, 512, to_bl("111"),
549 to_bl("test"))}, &on_ready, &on_safe);
550
551 when_complete(mock_image_ctx, aio_comp, 0);
552 ASSERT_EQ(0, on_ready.wait());
553
554 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
555 ASSERT_EQ(0, when_shut_down(mock_mis_compare_and_write_journal_replay, false));
556 ASSERT_EQ(0, on_safe.wait());
557
558 }
559
560 TEST_F(TestMockJournalReplay, IOError) {
561 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
562
563 librbd::ImageCtx *ictx;
564 ASSERT_EQ(0, open_image(m_image_name, &ictx));
565
566 MockReplayImageCtx mock_image_ctx(*ictx);
567
568 MockExclusiveLock mock_exclusive_lock;
569 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
570 expect_accept_ops(mock_exclusive_lock, true);
571
572 MockJournalReplay mock_journal_replay(mock_image_ctx);
573 MockIoImageRequest mock_io_image_request;
574 expect_op_work_queue(mock_image_ctx);
575
576 InSequence seq;
577 io::AioCompletion *aio_comp;
578 C_SaferCond on_ready;
579 C_SaferCond on_safe;
580 expect_aio_discard(mock_io_image_request, &aio_comp, 123, 456,
581 ictx->discard_granularity_bytes);
582 when_process(mock_journal_replay,
583 EventEntry{AioDiscardEvent(123, 456,
584 ictx->discard_granularity_bytes)},
585 &on_ready, &on_safe);
586
587 when_complete(mock_image_ctx, aio_comp, -EINVAL);
588 ASSERT_EQ(-EINVAL, on_safe.wait());
589
590 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
591 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
592 ASSERT_EQ(0, on_ready.wait());
593 }
594
595 TEST_F(TestMockJournalReplay, SoftFlushIO) {
596 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
597
598 librbd::ImageCtx *ictx;
599 ASSERT_EQ(0, open_image(m_image_name, &ictx));
600
601 MockReplayImageCtx mock_image_ctx(*ictx);
602
603 MockExclusiveLock mock_exclusive_lock;
604 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
605 expect_accept_ops(mock_exclusive_lock, true);
606
607 MockJournalReplay mock_journal_replay(mock_image_ctx);
608 MockIoImageRequest mock_io_image_request;
609 expect_op_work_queue(mock_image_ctx);
610
611 InSequence seq;
612 const size_t io_count = 32;
613 C_SaferCond on_safes[io_count];
614 for (size_t i = 0; i < io_count; ++i) {
615 io::AioCompletion *aio_comp;
616 io::AioCompletion *flush_comp = nullptr;
617 C_SaferCond on_ready;
618 expect_aio_discard(mock_io_image_request, &aio_comp, 123, 456,
619 ictx->discard_granularity_bytes);
620 if (i == io_count - 1) {
621 expect_aio_flush(mock_io_image_request, &flush_comp);
622 }
623 when_process(mock_journal_replay,
624 EventEntry{AioDiscardEvent(123, 456,
625 ictx->discard_granularity_bytes)},
626 &on_ready, &on_safes[i]);
627 when_complete(mock_image_ctx, aio_comp, 0);
628 ASSERT_EQ(0, on_ready.wait());
629
630 if (flush_comp != nullptr) {
631 when_complete(mock_image_ctx, flush_comp, 0);
632 }
633 }
634 for (auto &on_safe : on_safes) {
635 ASSERT_EQ(0, on_safe.wait());
636 }
637
638 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
639 }
640
641 TEST_F(TestMockJournalReplay, PauseIO) {
642 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
643
644 librbd::ImageCtx *ictx;
645 ASSERT_EQ(0, open_image(m_image_name, &ictx));
646
647 MockReplayImageCtx mock_image_ctx(*ictx);
648
649 MockExclusiveLock mock_exclusive_lock;
650 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
651 expect_accept_ops(mock_exclusive_lock, true);
652
653 MockJournalReplay mock_journal_replay(mock_image_ctx);
654 MockIoImageRequest mock_io_image_request;
655 expect_op_work_queue(mock_image_ctx);
656
657 InSequence seq;
658 const size_t io_count = 64;
659 std::list<io::AioCompletion *> flush_comps;
660 C_SaferCond on_safes[io_count];
661 for (size_t i = 0; i < io_count; ++i) {
662 io::AioCompletion *aio_comp;
663 C_SaferCond on_ready;
664 expect_aio_write(mock_io_image_request, &aio_comp, 123, 456, "test");
665 if ((i + 1) % 32 == 0) {
666 flush_comps.push_back(nullptr);
667 expect_aio_flush(mock_io_image_request, &flush_comps.back());
668 }
669 when_process(mock_journal_replay,
670 EventEntry{AioWriteEvent(123, 456, to_bl("test"))},
671 &on_ready, &on_safes[i]);
672 when_complete(mock_image_ctx, aio_comp, 0);
673 if (i < io_count - 1) {
674 ASSERT_EQ(0, on_ready.wait());
675 } else {
676 for (auto flush_comp : flush_comps) {
677 when_complete(mock_image_ctx, flush_comp, 0);
678 }
679 ASSERT_EQ(0, on_ready.wait());
680 }
681 }
682 for (auto &on_safe : on_safes) {
683 ASSERT_EQ(0, on_safe.wait());
684 }
685
686 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
687 }
688
689 TEST_F(TestMockJournalReplay, Flush) {
690 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
691
692 librbd::ImageCtx *ictx;
693 ASSERT_EQ(0, open_image(m_image_name, &ictx));
694
695 MockReplayImageCtx mock_image_ctx(*ictx);
696
697 MockExclusiveLock mock_exclusive_lock;
698 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
699 expect_accept_ops(mock_exclusive_lock, true);
700
701 MockJournalReplay mock_journal_replay(mock_image_ctx);
702 MockIoImageRequest mock_io_image_request;
703 expect_op_work_queue(mock_image_ctx);
704
705 InSequence seq;
706 io::AioCompletion *aio_comp = nullptr;
707 C_SaferCond on_ready;
708 C_SaferCond on_safe;
709 expect_aio_discard(mock_io_image_request, &aio_comp, 123, 456,
710 ictx->discard_granularity_bytes);
711 when_process(mock_journal_replay,
712 EventEntry{AioDiscardEvent(123, 456,
713 ictx->discard_granularity_bytes)},
714 &on_ready, &on_safe);
715
716 when_complete(mock_image_ctx, aio_comp, 0);
717 ASSERT_EQ(0, on_ready.wait());
718
719 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
720 ASSERT_EQ(0, when_flush(mock_journal_replay));
721 ASSERT_EQ(0, on_safe.wait());
722 }
723
724 TEST_F(TestMockJournalReplay, OpFinishError) {
725 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
726
727 librbd::ImageCtx *ictx;
728 ASSERT_EQ(0, open_image(m_image_name, &ictx));
729
730 MockReplayImageCtx mock_image_ctx(*ictx);
731
732 MockExclusiveLock mock_exclusive_lock;
733 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
734 expect_accept_ops(mock_exclusive_lock, true);
735
736 MockJournalReplay mock_journal_replay(mock_image_ctx);
737 expect_op_work_queue(mock_image_ctx);
738
739 InSequence seq;
740 C_SaferCond on_start_ready;
741 C_SaferCond on_start_safe;
742 when_process(mock_journal_replay,
743 EventEntry{SnapRemoveEvent(123,
744 cls::rbd::UserSnapshotNamespace(),
745 "snap")},
746 &on_start_ready,
747 &on_start_safe);
748 ASSERT_EQ(0, on_start_ready.wait());
749
750 C_SaferCond on_finish_ready;
751 C_SaferCond on_finish_safe;
752 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EIO)},
753 &on_finish_ready, &on_finish_safe);
754
755 ASSERT_EQ(-EIO, on_start_safe.wait());
756 ASSERT_EQ(-EIO, on_finish_safe.wait());
757 ASSERT_EQ(0, on_finish_ready.wait());
758 }
759
760 TEST_F(TestMockJournalReplay, BlockedOpFinishError) {
761 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
762
763 librbd::ImageCtx *ictx;
764 ASSERT_EQ(0, open_image(m_image_name, &ictx));
765
766 MockReplayImageCtx mock_image_ctx(*ictx);
767
768 MockExclusiveLock mock_exclusive_lock;
769 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
770 expect_accept_ops(mock_exclusive_lock, true);
771
772 MockJournalReplay mock_journal_replay(mock_image_ctx);
773 expect_op_work_queue(mock_image_ctx);
774
775 InSequence seq;
776 Context *on_finish = nullptr;
777 expect_refresh_image(mock_image_ctx, false, 0);
778 expect_snap_create(mock_image_ctx, &on_finish, "snap", 123);
779
780 C_SaferCond on_start_ready;
781 C_SaferCond on_start_safe;
782 when_process(mock_journal_replay,
783 EventEntry{SnapCreateEvent(123,
784 cls::rbd::UserSnapshotNamespace(),
785 "snap")},
786 &on_start_ready,
787 &on_start_safe);
788
789 C_SaferCond on_resume;
790 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
791 ASSERT_EQ(0, on_start_ready.wait());
792
793 C_SaferCond on_finish_ready;
794 C_SaferCond on_finish_safe;
795 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EBADMSG)},
796 &on_finish_ready, &on_finish_safe);
797
798 ASSERT_EQ(-EBADMSG, on_resume.wait());
799 wait_for_op_invoked(&on_finish, -ESTALE);
800
801 ASSERT_EQ(-ESTALE, on_start_safe.wait());
802 ASSERT_EQ(-ESTALE, on_finish_safe.wait());
803 ASSERT_EQ(0, on_finish_ready.wait());
804 }
805
806 TEST_F(TestMockJournalReplay, MissingOpFinishEvent) {
807 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
808
809 librbd::ImageCtx *ictx;
810 ASSERT_EQ(0, open_image(m_image_name, &ictx));
811
812 MockReplayImageCtx mock_image_ctx(*ictx);
813
814 MockExclusiveLock mock_exclusive_lock;
815 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
816 expect_accept_ops(mock_exclusive_lock, true);
817
818 MockJournalReplay mock_journal_replay(mock_image_ctx);
819 expect_op_work_queue(mock_image_ctx);
820
821 EXPECT_CALL(*mock_image_ctx.state, is_refresh_required())
822 .WillRepeatedly(Return(false));
823
824 InSequence seq;
825 Context *on_snap_create_finish = nullptr;
826 expect_snap_create(mock_image_ctx, &on_snap_create_finish, "snap", 123);
827
828 Context *on_snap_remove_finish = nullptr;
829 expect_snap_remove(mock_image_ctx, &on_snap_remove_finish, "snap");
830
831 C_SaferCond on_snap_remove_ready;
832 C_SaferCond on_snap_remove_safe;
833 when_process(mock_journal_replay,
834 EventEntry{SnapRemoveEvent(122,
835 cls::rbd::UserSnapshotNamespace(),
836 "snap")},
837 &on_snap_remove_ready,
838 &on_snap_remove_safe);
839 ictx->op_work_queue->drain();
840 ASSERT_EQ(0, on_snap_remove_ready.wait());
841
842 C_SaferCond on_snap_create_ready;
843 C_SaferCond on_snap_create_safe;
844 when_process(mock_journal_replay,
845 EventEntry{SnapCreateEvent(123,
846 cls::rbd::UserSnapshotNamespace(),
847 "snap")},
848 &on_snap_create_ready,
849 &on_snap_create_safe);
850 ictx->op_work_queue->drain();
851
852 C_SaferCond on_shut_down;
853 mock_journal_replay.shut_down(false, &on_shut_down);
854
855 wait_for_op_invoked(&on_snap_remove_finish, 0);
856 ASSERT_EQ(0, on_snap_remove_safe.wait());
857
858 C_SaferCond on_snap_create_resume;
859 when_replay_op_ready(mock_journal_replay, 123, &on_snap_create_resume);
860 ASSERT_EQ(0, on_snap_create_resume.wait());
861
862 wait_for_op_invoked(&on_snap_create_finish, 0);
863 ASSERT_EQ(0, on_snap_create_ready.wait());
864 ASSERT_EQ(0, on_snap_create_safe.wait());
865
866 ASSERT_EQ(0, on_shut_down.wait());
867 }
868
869 TEST_F(TestMockJournalReplay, MissingOpFinishEventCancelOps) {
870 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
871
872 librbd::ImageCtx *ictx;
873 ASSERT_EQ(0, open_image(m_image_name, &ictx));
874
875 MockReplayImageCtx mock_image_ctx(*ictx);
876
877 MockExclusiveLock mock_exclusive_lock;
878 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
879 expect_accept_ops(mock_exclusive_lock, true);
880
881 MockJournalReplay mock_journal_replay(mock_image_ctx);
882 expect_op_work_queue(mock_image_ctx);
883
884 InSequence seq;
885 Context *on_snap_create_finish = nullptr;
886 expect_refresh_image(mock_image_ctx, false, 0);
887 expect_snap_create(mock_image_ctx, &on_snap_create_finish, "snap", 123);
888
889 C_SaferCond on_snap_remove_ready;
890 C_SaferCond on_snap_remove_safe;
891 when_process(mock_journal_replay,
892 EventEntry{SnapRemoveEvent(122,
893 cls::rbd::UserSnapshotNamespace(),
894 "snap")},
895 &on_snap_remove_ready,
896 &on_snap_remove_safe);
897 ictx->op_work_queue->drain();
898 ASSERT_EQ(0, on_snap_remove_ready.wait());
899
900 C_SaferCond on_snap_create_ready;
901 C_SaferCond on_snap_create_safe;
902 when_process(mock_journal_replay,
903 EventEntry{SnapCreateEvent(123,
904 cls::rbd::UserSnapshotNamespace(),
905 "snap")},
906 &on_snap_create_ready,
907 &on_snap_create_safe);
908 ictx->op_work_queue->drain();
909
910 C_SaferCond on_resume;
911 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
912 ASSERT_EQ(0, on_snap_create_ready.wait());
913
914 C_SaferCond on_shut_down;
915 mock_journal_replay.shut_down(true, &on_shut_down);
916
917 ASSERT_EQ(-ERESTART, on_resume.wait());
918 on_snap_create_finish->complete(-ERESTART);
919 ASSERT_EQ(-ERESTART, on_snap_create_safe.wait());
920
921 ASSERT_EQ(-ERESTART, on_snap_remove_safe.wait());
922 ASSERT_EQ(0, on_shut_down.wait());
923 }
924
925 TEST_F(TestMockJournalReplay, UnknownOpFinishEvent) {
926 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
927
928 librbd::ImageCtx *ictx;
929 ASSERT_EQ(0, open_image(m_image_name, &ictx));
930
931 MockReplayImageCtx mock_image_ctx(*ictx);
932
933 MockExclusiveLock mock_exclusive_lock;
934 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
935 expect_accept_ops(mock_exclusive_lock, true);
936
937 MockJournalReplay mock_journal_replay(mock_image_ctx);
938 expect_op_work_queue(mock_image_ctx);
939
940 InSequence seq;
941 C_SaferCond on_ready;
942 C_SaferCond on_safe;
943 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
944 &on_ready, &on_safe);
945
946 ASSERT_EQ(0, on_safe.wait());
947 ASSERT_EQ(0, on_ready.wait());
948 }
949
950 TEST_F(TestMockJournalReplay, OpEventError) {
951 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
952
953 librbd::ImageCtx *ictx;
954 ASSERT_EQ(0, open_image(m_image_name, &ictx));
955
956 MockReplayImageCtx mock_image_ctx(*ictx);
957
958 MockExclusiveLock mock_exclusive_lock;
959 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
960 expect_accept_ops(mock_exclusive_lock, true);
961
962 MockJournalReplay mock_journal_replay(mock_image_ctx);
963 expect_op_work_queue(mock_image_ctx);
964
965 InSequence seq;
966 Context *on_finish = nullptr;
967 expect_refresh_image(mock_image_ctx, false, 0);
968 expect_snap_remove(mock_image_ctx, &on_finish, "snap");
969
970 C_SaferCond on_start_ready;
971 C_SaferCond on_start_safe;
972 when_process(mock_journal_replay,
973 EventEntry{SnapRemoveEvent(123,
974 cls::rbd::UserSnapshotNamespace(),
975 "snap")},
976 &on_start_ready,
977 &on_start_safe);
978 ASSERT_EQ(0, on_start_ready.wait());
979
980 C_SaferCond on_finish_ready;
981 C_SaferCond on_finish_safe;
982 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
983 &on_finish_ready, &on_finish_safe);
984
985 wait_for_op_invoked(&on_finish, -EINVAL);
986 ASSERT_EQ(-EINVAL, on_start_safe.wait());
987 ASSERT_EQ(0, on_finish_ready.wait());
988 ASSERT_EQ(-EINVAL, on_finish_safe.wait());
989 }
990
991 TEST_F(TestMockJournalReplay, SnapCreateEvent) {
992 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
993
994 librbd::ImageCtx *ictx;
995 ASSERT_EQ(0, open_image(m_image_name, &ictx));
996
997 MockReplayImageCtx mock_image_ctx(*ictx);
998
999 MockExclusiveLock mock_exclusive_lock;
1000 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1001 expect_accept_ops(mock_exclusive_lock, true);
1002
1003 MockJournalReplay mock_journal_replay(mock_image_ctx);
1004 expect_op_work_queue(mock_image_ctx);
1005
1006 InSequence seq;
1007 Context *on_finish = nullptr;
1008 expect_refresh_image(mock_image_ctx, false, 0);
1009 expect_snap_create(mock_image_ctx, &on_finish, "snap", 123);
1010
1011 C_SaferCond on_start_ready;
1012 C_SaferCond on_start_safe;
1013 when_process(mock_journal_replay,
1014 EventEntry{SnapCreateEvent(123,
1015 cls::rbd::UserSnapshotNamespace(),
1016 "snap")},
1017 &on_start_ready,
1018 &on_start_safe);
1019
1020 C_SaferCond on_resume;
1021 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
1022 ASSERT_EQ(0, on_start_ready.wait());
1023
1024 C_SaferCond on_finish_ready;
1025 C_SaferCond on_finish_safe;
1026 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1027 &on_finish_ready, &on_finish_safe);
1028
1029 ASSERT_EQ(0, on_resume.wait());
1030 wait_for_op_invoked(&on_finish, 0);
1031
1032 ASSERT_EQ(0, on_start_safe.wait());
1033 ASSERT_EQ(0, on_finish_ready.wait());
1034 ASSERT_EQ(0, on_finish_safe.wait());
1035 }
1036
1037 TEST_F(TestMockJournalReplay, SnapCreateEventExists) {
1038 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1039
1040 librbd::ImageCtx *ictx;
1041 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1042
1043 MockReplayImageCtx mock_image_ctx(*ictx);
1044
1045 MockExclusiveLock mock_exclusive_lock;
1046 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1047 expect_accept_ops(mock_exclusive_lock, true);
1048
1049 MockJournalReplay mock_journal_replay(mock_image_ctx);
1050 expect_op_work_queue(mock_image_ctx);
1051
1052 InSequence seq;
1053 Context *on_finish = nullptr;
1054 expect_refresh_image(mock_image_ctx, false, 0);
1055 expect_snap_create(mock_image_ctx, &on_finish, "snap", 123);
1056
1057 C_SaferCond on_start_ready;
1058 C_SaferCond on_start_safe;
1059 when_process(mock_journal_replay,
1060 EventEntry{SnapCreateEvent(123,
1061 cls::rbd::UserSnapshotNamespace(),
1062 "snap")},
1063 &on_start_ready,
1064 &on_start_safe);
1065
1066 wait_for_op_invoked(&on_finish, -EEXIST);
1067 ASSERT_EQ(0, on_start_ready.wait());
1068
1069 C_SaferCond on_finish_ready;
1070 C_SaferCond on_finish_safe;
1071 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1072 &on_finish_ready, &on_finish_safe);
1073
1074 ASSERT_EQ(0, on_start_safe.wait());
1075 ASSERT_EQ(0, on_finish_ready.wait());
1076 ASSERT_EQ(0, on_finish_safe.wait());
1077 }
1078
1079 TEST_F(TestMockJournalReplay, SnapRemoveEvent) {
1080 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1081
1082 librbd::ImageCtx *ictx;
1083 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1084
1085 MockReplayImageCtx mock_image_ctx(*ictx);
1086
1087 MockExclusiveLock mock_exclusive_lock;
1088 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1089 expect_accept_ops(mock_exclusive_lock, true);
1090
1091 MockJournalReplay mock_journal_replay(mock_image_ctx);
1092 expect_op_work_queue(mock_image_ctx);
1093
1094 InSequence seq;
1095 Context *on_finish = nullptr;
1096 expect_refresh_image(mock_image_ctx, false, 0);
1097 expect_snap_remove(mock_image_ctx, &on_finish, "snap");
1098
1099 C_SaferCond on_start_ready;
1100 C_SaferCond on_start_safe;
1101 when_process(mock_journal_replay,
1102 EventEntry{SnapRemoveEvent(123,
1103 cls::rbd::UserSnapshotNamespace(),
1104 "snap")},
1105 &on_start_ready,
1106 &on_start_safe);
1107 ASSERT_EQ(0, on_start_ready.wait());
1108
1109 C_SaferCond on_finish_ready;
1110 C_SaferCond on_finish_safe;
1111 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1112 &on_finish_ready, &on_finish_safe);
1113
1114 wait_for_op_invoked(&on_finish, 0);
1115 ASSERT_EQ(0, on_start_safe.wait());
1116 ASSERT_EQ(0, on_finish_ready.wait());
1117 ASSERT_EQ(0, on_finish_safe.wait());
1118 }
1119
1120 TEST_F(TestMockJournalReplay, SnapRemoveEventDNE) {
1121 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1122
1123 librbd::ImageCtx *ictx;
1124 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1125
1126 MockReplayImageCtx mock_image_ctx(*ictx);
1127
1128 MockExclusiveLock mock_exclusive_lock;
1129 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1130 expect_accept_ops(mock_exclusive_lock, true);
1131
1132 MockJournalReplay mock_journal_replay(mock_image_ctx);
1133 expect_op_work_queue(mock_image_ctx);
1134
1135 InSequence seq;
1136 Context *on_finish = nullptr;
1137 expect_refresh_image(mock_image_ctx, false, 0);
1138 expect_snap_remove(mock_image_ctx, &on_finish, "snap");
1139
1140 C_SaferCond on_start_ready;
1141 C_SaferCond on_start_safe;
1142 when_process(mock_journal_replay,
1143 EventEntry{SnapRemoveEvent(123,
1144 cls::rbd::UserSnapshotNamespace(),
1145 "snap")},
1146 &on_start_ready,
1147 &on_start_safe);
1148 ASSERT_EQ(0, on_start_ready.wait());
1149
1150 C_SaferCond on_finish_ready;
1151 C_SaferCond on_finish_safe;
1152 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1153 &on_finish_ready, &on_finish_safe);
1154
1155 wait_for_op_invoked(&on_finish, -ENOENT);
1156 ASSERT_EQ(0, on_start_safe.wait());
1157 ASSERT_EQ(0, on_finish_ready.wait());
1158 ASSERT_EQ(0, on_finish_safe.wait());
1159 }
1160
1161 TEST_F(TestMockJournalReplay, SnapRenameEvent) {
1162 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1163
1164 librbd::ImageCtx *ictx;
1165 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1166
1167 MockReplayImageCtx mock_image_ctx(*ictx);
1168
1169 MockExclusiveLock mock_exclusive_lock;
1170 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1171 expect_accept_ops(mock_exclusive_lock, true);
1172
1173 MockJournalReplay mock_journal_replay(mock_image_ctx);
1174 expect_op_work_queue(mock_image_ctx);
1175
1176 InSequence seq;
1177 Context *on_finish = nullptr;
1178 expect_refresh_image(mock_image_ctx, false, 0);
1179 expect_snap_rename(mock_image_ctx, &on_finish, 234, "snap");
1180
1181 C_SaferCond on_start_ready;
1182 C_SaferCond on_start_safe;
1183 when_process(mock_journal_replay,
1184 EventEntry{SnapRenameEvent(123, 234, "snap1", "snap")},
1185 &on_start_ready, &on_start_safe);
1186 ASSERT_EQ(0, on_start_ready.wait());
1187
1188 C_SaferCond on_finish_ready;
1189 C_SaferCond on_finish_safe;
1190 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1191 &on_finish_ready, &on_finish_safe);
1192
1193 wait_for_op_invoked(&on_finish, 0);
1194 ASSERT_EQ(0, on_start_safe.wait());
1195 ASSERT_EQ(0, on_finish_ready.wait());
1196 ASSERT_EQ(0, on_finish_safe.wait());
1197 }
1198
1199 TEST_F(TestMockJournalReplay, SnapRenameEventExists) {
1200 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1201
1202 librbd::ImageCtx *ictx;
1203 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1204
1205 MockReplayImageCtx mock_image_ctx(*ictx);
1206
1207 MockExclusiveLock mock_exclusive_lock;
1208 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1209 expect_accept_ops(mock_exclusive_lock, true);
1210
1211 MockJournalReplay mock_journal_replay(mock_image_ctx);
1212 expect_op_work_queue(mock_image_ctx);
1213
1214 InSequence seq;
1215 Context *on_finish = nullptr;
1216 expect_refresh_image(mock_image_ctx, false, 0);
1217 expect_snap_rename(mock_image_ctx, &on_finish, 234, "snap");
1218
1219 C_SaferCond on_start_ready;
1220 C_SaferCond on_start_safe;
1221 when_process(mock_journal_replay,
1222 EventEntry{SnapRenameEvent(123, 234, "snap1", "snap")},
1223 &on_start_ready, &on_start_safe);
1224 ASSERT_EQ(0, on_start_ready.wait());
1225
1226 C_SaferCond on_finish_ready;
1227 C_SaferCond on_finish_safe;
1228 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1229 &on_finish_ready, &on_finish_safe);
1230
1231 wait_for_op_invoked(&on_finish, -EEXIST);
1232 ASSERT_EQ(0, on_start_safe.wait());
1233 ASSERT_EQ(0, on_finish_ready.wait());
1234 ASSERT_EQ(0, on_finish_safe.wait());
1235 }
1236
1237 TEST_F(TestMockJournalReplay, SnapProtectEvent) {
1238 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1239
1240 librbd::ImageCtx *ictx;
1241 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1242
1243 MockReplayImageCtx mock_image_ctx(*ictx);
1244
1245 MockExclusiveLock mock_exclusive_lock;
1246 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1247 expect_accept_ops(mock_exclusive_lock, true);
1248
1249 MockJournalReplay mock_journal_replay(mock_image_ctx);
1250 expect_op_work_queue(mock_image_ctx);
1251
1252 InSequence seq;
1253 Context *on_finish = nullptr;
1254 expect_refresh_image(mock_image_ctx, false, 0);
1255 expect_snap_protect(mock_image_ctx, &on_finish, "snap");
1256
1257 C_SaferCond on_start_ready;
1258 C_SaferCond on_start_safe;
1259 when_process(mock_journal_replay,
1260 EventEntry{SnapProtectEvent(123,
1261 cls::rbd::UserSnapshotNamespace(),
1262 "snap")},
1263 &on_start_ready,
1264 &on_start_safe);
1265 ASSERT_EQ(0, on_start_ready.wait());
1266
1267 C_SaferCond on_finish_ready;
1268 C_SaferCond on_finish_safe;
1269 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1270 &on_finish_ready, &on_finish_safe);
1271
1272 wait_for_op_invoked(&on_finish, 0);
1273 ASSERT_EQ(0, on_start_safe.wait());
1274 ASSERT_EQ(0, on_finish_ready.wait());
1275 ASSERT_EQ(0, on_finish_safe.wait());
1276 }
1277
1278 TEST_F(TestMockJournalReplay, SnapProtectEventBusy) {
1279 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1280
1281 librbd::ImageCtx *ictx;
1282 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1283
1284 MockReplayImageCtx mock_image_ctx(*ictx);
1285
1286 MockExclusiveLock mock_exclusive_lock;
1287 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1288 expect_accept_ops(mock_exclusive_lock, true);
1289
1290 MockJournalReplay mock_journal_replay(mock_image_ctx);
1291 expect_op_work_queue(mock_image_ctx);
1292
1293 InSequence seq;
1294 Context *on_finish = nullptr;
1295 expect_refresh_image(mock_image_ctx, false, 0);
1296 expect_snap_protect(mock_image_ctx, &on_finish, "snap");
1297
1298 C_SaferCond on_start_ready;
1299 C_SaferCond on_start_safe;
1300 when_process(mock_journal_replay,
1301 EventEntry{SnapProtectEvent(123,
1302 cls::rbd::UserSnapshotNamespace(),
1303 "snap")},
1304 &on_start_ready,
1305 &on_start_safe);
1306 ASSERT_EQ(0, on_start_ready.wait());
1307
1308 C_SaferCond on_finish_ready;
1309 C_SaferCond on_finish_safe;
1310 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1311 &on_finish_ready, &on_finish_safe);
1312
1313 wait_for_op_invoked(&on_finish, -EBUSY);
1314 ASSERT_EQ(0, on_start_safe.wait());
1315 ASSERT_EQ(0, on_finish_ready.wait());
1316 ASSERT_EQ(0, on_finish_safe.wait());
1317 }
1318
1319 TEST_F(TestMockJournalReplay, SnapUnprotectEvent) {
1320 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1321
1322 librbd::ImageCtx *ictx;
1323 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1324
1325 MockReplayImageCtx mock_image_ctx(*ictx);
1326
1327 MockExclusiveLock mock_exclusive_lock;
1328 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1329 expect_accept_ops(mock_exclusive_lock, true);
1330
1331 MockJournalReplay mock_journal_replay(mock_image_ctx);
1332 expect_op_work_queue(mock_image_ctx);
1333
1334 InSequence seq;
1335 Context *on_finish = nullptr;
1336 expect_refresh_image(mock_image_ctx, false, 0);
1337 expect_snap_unprotect(mock_image_ctx, &on_finish, "snap");
1338
1339 C_SaferCond on_start_ready;
1340 C_SaferCond on_start_safe;
1341 when_process(mock_journal_replay,
1342 EventEntry{SnapUnprotectEvent(123,
1343 cls::rbd::UserSnapshotNamespace(),
1344 "snap")},
1345 &on_start_ready,
1346 &on_start_safe);
1347 ASSERT_EQ(0, on_start_ready.wait());
1348
1349 C_SaferCond on_finish_ready;
1350 C_SaferCond on_finish_safe;
1351 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1352 &on_finish_ready, &on_finish_safe);
1353
1354 wait_for_op_invoked(&on_finish, 0);
1355 ASSERT_EQ(0, on_start_safe.wait());
1356 ASSERT_EQ(0, on_finish_ready.wait());
1357 ASSERT_EQ(0, on_finish_safe.wait());
1358 }
1359
1360 TEST_F(TestMockJournalReplay, SnapUnprotectOpFinishBusy) {
1361 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1362
1363 librbd::ImageCtx *ictx;
1364 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1365
1366 MockReplayImageCtx mock_image_ctx(*ictx);
1367
1368 MockExclusiveLock mock_exclusive_lock;
1369 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1370 expect_accept_ops(mock_exclusive_lock, true);
1371
1372 MockJournalReplay mock_journal_replay(mock_image_ctx);
1373 expect_op_work_queue(mock_image_ctx);
1374
1375 InSequence seq;
1376 C_SaferCond on_start_ready;
1377 C_SaferCond on_start_safe;
1378 when_process(mock_journal_replay,
1379 EventEntry{SnapUnprotectEvent(123,
1380 cls::rbd::UserSnapshotNamespace(),
1381 "snap")},
1382 &on_start_ready,
1383 &on_start_safe);
1384 ASSERT_EQ(0, on_start_ready.wait());
1385
1386 // aborts the snap unprotect op if image had children
1387 C_SaferCond on_finish_ready;
1388 C_SaferCond on_finish_safe;
1389 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EBUSY)},
1390 &on_finish_ready, &on_finish_safe);
1391
1392 ASSERT_EQ(0, on_start_safe.wait());
1393 ASSERT_EQ(0, on_finish_safe.wait());
1394 ASSERT_EQ(0, on_finish_ready.wait());
1395 }
1396
1397 TEST_F(TestMockJournalReplay, SnapUnprotectEventInvalid) {
1398 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1399
1400 librbd::ImageCtx *ictx;
1401 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1402
1403 MockReplayImageCtx mock_image_ctx(*ictx);
1404
1405 MockExclusiveLock mock_exclusive_lock;
1406 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1407 expect_accept_ops(mock_exclusive_lock, true);
1408
1409 MockJournalReplay mock_journal_replay(mock_image_ctx);
1410 expect_op_work_queue(mock_image_ctx);
1411
1412 InSequence seq;
1413 Context *on_finish = nullptr;
1414 expect_refresh_image(mock_image_ctx, false, 0);
1415 expect_snap_unprotect(mock_image_ctx, &on_finish, "snap");
1416
1417 C_SaferCond on_start_ready;
1418 C_SaferCond on_start_safe;
1419 when_process(mock_journal_replay,
1420 EventEntry{SnapUnprotectEvent(123,
1421 cls::rbd::UserSnapshotNamespace(),
1422 "snap")},
1423 &on_start_ready,
1424 &on_start_safe);
1425 ASSERT_EQ(0, on_start_ready.wait());
1426
1427 C_SaferCond on_finish_ready;
1428 C_SaferCond on_finish_safe;
1429 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1430 &on_finish_ready, &on_finish_safe);
1431
1432 wait_for_op_invoked(&on_finish, -EINVAL);
1433 ASSERT_EQ(0, on_start_safe.wait());
1434 ASSERT_EQ(0, on_finish_ready.wait());
1435 ASSERT_EQ(0, on_finish_safe.wait());
1436 }
1437
1438 TEST_F(TestMockJournalReplay, SnapRollbackEvent) {
1439 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1440
1441 librbd::ImageCtx *ictx;
1442 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1443
1444 MockReplayImageCtx mock_image_ctx(*ictx);
1445
1446 MockExclusiveLock mock_exclusive_lock;
1447 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1448 expect_accept_ops(mock_exclusive_lock, true);
1449
1450 MockJournalReplay mock_journal_replay(mock_image_ctx);
1451 expect_op_work_queue(mock_image_ctx);
1452
1453 InSequence seq;
1454 Context *on_finish = nullptr;
1455 expect_refresh_image(mock_image_ctx, false, 0);
1456 expect_snap_rollback(mock_image_ctx, &on_finish, "snap");
1457
1458 C_SaferCond on_start_ready;
1459 C_SaferCond on_start_safe;
1460 when_process(mock_journal_replay,
1461 EventEntry{SnapRollbackEvent(123,
1462 cls::rbd::UserSnapshotNamespace(),
1463 "snap")},
1464 &on_start_ready,
1465 &on_start_safe);
1466 ASSERT_EQ(0, on_start_ready.wait());
1467
1468 C_SaferCond on_finish_ready;
1469 C_SaferCond on_finish_safe;
1470 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1471 &on_finish_ready, &on_finish_safe);
1472
1473 wait_for_op_invoked(&on_finish, 0);
1474 ASSERT_EQ(0, on_start_safe.wait());
1475 ASSERT_EQ(0, on_finish_ready.wait());
1476 ASSERT_EQ(0, on_finish_safe.wait());
1477 }
1478
1479 TEST_F(TestMockJournalReplay, RenameEvent) {
1480 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1481
1482 librbd::ImageCtx *ictx;
1483 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1484
1485 MockReplayImageCtx mock_image_ctx(*ictx);
1486
1487 MockExclusiveLock mock_exclusive_lock;
1488 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1489 expect_accept_ops(mock_exclusive_lock, true);
1490
1491 MockJournalReplay mock_journal_replay(mock_image_ctx);
1492 expect_op_work_queue(mock_image_ctx);
1493
1494 InSequence seq;
1495 Context *on_finish = nullptr;
1496 expect_refresh_image(mock_image_ctx, false, 0);
1497 expect_rename(mock_image_ctx, &on_finish, "image");
1498
1499 C_SaferCond on_start_ready;
1500 C_SaferCond on_start_safe;
1501 when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
1502 &on_start_ready, &on_start_safe);
1503 ASSERT_EQ(0, on_start_ready.wait());
1504
1505 C_SaferCond on_finish_ready;
1506 C_SaferCond on_finish_safe;
1507 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1508 &on_finish_ready, &on_finish_safe);
1509
1510 wait_for_op_invoked(&on_finish, 0);
1511 ASSERT_EQ(0, on_start_safe.wait());
1512 ASSERT_EQ(0, on_finish_ready.wait());
1513 ASSERT_EQ(0, on_finish_safe.wait());
1514 }
1515
1516 TEST_F(TestMockJournalReplay, RenameEventExists) {
1517 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1518
1519 librbd::ImageCtx *ictx;
1520 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1521
1522 MockReplayImageCtx mock_image_ctx(*ictx);
1523
1524 MockExclusiveLock mock_exclusive_lock;
1525 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1526 expect_accept_ops(mock_exclusive_lock, true);
1527
1528 MockJournalReplay mock_journal_replay(mock_image_ctx);
1529 expect_op_work_queue(mock_image_ctx);
1530
1531 InSequence seq;
1532 Context *on_finish = nullptr;
1533 expect_refresh_image(mock_image_ctx, false, 0);
1534 expect_rename(mock_image_ctx, &on_finish, "image");
1535
1536 C_SaferCond on_start_ready;
1537 C_SaferCond on_start_safe;
1538 when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
1539 &on_start_ready, &on_start_safe);
1540 ASSERT_EQ(0, on_start_ready.wait());
1541
1542 C_SaferCond on_finish_ready;
1543 C_SaferCond on_finish_safe;
1544 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1545 &on_finish_ready, &on_finish_safe);
1546
1547 wait_for_op_invoked(&on_finish, -EEXIST);
1548 ASSERT_EQ(0, on_start_safe.wait());
1549 ASSERT_EQ(0, on_finish_ready.wait());
1550 ASSERT_EQ(0, on_finish_safe.wait());
1551 }
1552
1553 TEST_F(TestMockJournalReplay, ResizeEvent) {
1554 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1555
1556 librbd::ImageCtx *ictx;
1557 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1558
1559 MockReplayImageCtx mock_image_ctx(*ictx);
1560
1561 MockExclusiveLock mock_exclusive_lock;
1562 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1563 expect_accept_ops(mock_exclusive_lock, true);
1564
1565 MockJournalReplay mock_journal_replay(mock_image_ctx);
1566 expect_op_work_queue(mock_image_ctx);
1567
1568 InSequence seq;
1569 Context *on_finish = nullptr;
1570 expect_refresh_image(mock_image_ctx, false, 0);
1571 expect_resize(mock_image_ctx, &on_finish, 234, 123);
1572
1573 C_SaferCond on_start_ready;
1574 C_SaferCond on_start_safe;
1575 when_process(mock_journal_replay, EventEntry{ResizeEvent(123, 234)},
1576 &on_start_ready, &on_start_safe);
1577
1578 C_SaferCond on_resume;
1579 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
1580 ASSERT_EQ(0, on_start_ready.wait());
1581
1582 C_SaferCond on_finish_ready;
1583 C_SaferCond on_finish_safe;
1584 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1585 &on_finish_ready, &on_finish_safe);
1586
1587 ASSERT_EQ(0, on_resume.wait());
1588 wait_for_op_invoked(&on_finish, 0);
1589
1590 ASSERT_EQ(0, on_start_safe.wait());
1591 ASSERT_EQ(0, on_finish_ready.wait());
1592 ASSERT_EQ(0, on_finish_safe.wait());
1593 }
1594
1595 TEST_F(TestMockJournalReplay, FlattenEvent) {
1596 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1597
1598 librbd::ImageCtx *ictx;
1599 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1600
1601 MockReplayImageCtx mock_image_ctx(*ictx);
1602
1603 MockExclusiveLock mock_exclusive_lock;
1604 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1605 expect_accept_ops(mock_exclusive_lock, true);
1606
1607 MockJournalReplay mock_journal_replay(mock_image_ctx);
1608 expect_op_work_queue(mock_image_ctx);
1609
1610 InSequence seq;
1611 Context *on_finish = nullptr;
1612 expect_refresh_image(mock_image_ctx, false, 0);
1613 expect_flatten(mock_image_ctx, &on_finish);
1614
1615 C_SaferCond on_start_ready;
1616 C_SaferCond on_start_safe;
1617 when_process(mock_journal_replay, EventEntry{FlattenEvent(123)},
1618 &on_start_ready, &on_start_safe);
1619 ASSERT_EQ(0, on_start_ready.wait());
1620
1621 C_SaferCond on_finish_ready;
1622 C_SaferCond on_finish_safe;
1623 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1624 &on_finish_ready, &on_finish_safe);
1625
1626 wait_for_op_invoked(&on_finish, 0);
1627 ASSERT_EQ(0, on_start_safe.wait());
1628 ASSERT_EQ(0, on_finish_ready.wait());
1629 ASSERT_EQ(0, on_finish_safe.wait());
1630 }
1631
1632 TEST_F(TestMockJournalReplay, FlattenEventInvalid) {
1633 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1634
1635 librbd::ImageCtx *ictx;
1636 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1637
1638 MockReplayImageCtx mock_image_ctx(*ictx);
1639
1640 MockExclusiveLock mock_exclusive_lock;
1641 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1642 expect_accept_ops(mock_exclusive_lock, true);
1643
1644 MockJournalReplay mock_journal_replay(mock_image_ctx);
1645 expect_op_work_queue(mock_image_ctx);
1646
1647 InSequence seq;
1648 Context *on_finish = nullptr;
1649 expect_refresh_image(mock_image_ctx, false, 0);
1650 expect_flatten(mock_image_ctx, &on_finish);
1651
1652 C_SaferCond on_start_ready;
1653 C_SaferCond on_start_safe;
1654 when_process(mock_journal_replay, EventEntry{FlattenEvent(123)},
1655 &on_start_ready, &on_start_safe);
1656 ASSERT_EQ(0, on_start_ready.wait());
1657
1658 C_SaferCond on_finish_ready;
1659 C_SaferCond on_finish_safe;
1660 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1661 &on_finish_ready, &on_finish_safe);
1662
1663 wait_for_op_invoked(&on_finish, -EINVAL);
1664 ASSERT_EQ(0, on_start_safe.wait());
1665 ASSERT_EQ(0, on_finish_ready.wait());
1666 ASSERT_EQ(0, on_finish_safe.wait());
1667 }
1668
1669 TEST_F(TestMockJournalReplay, UpdateFeaturesEvent) {
1670 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1671
1672 librbd::ImageCtx *ictx;
1673 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1674
1675 uint64_t features = RBD_FEATURE_OBJECT_MAP | RBD_FEATURE_FAST_DIFF;
1676 bool enabled = !ictx->test_features(features);
1677
1678 MockReplayImageCtx mock_image_ctx(*ictx);
1679
1680 MockExclusiveLock mock_exclusive_lock;
1681 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1682 expect_accept_ops(mock_exclusive_lock, true);
1683
1684 MockJournalReplay mock_journal_replay(mock_image_ctx);
1685 expect_op_work_queue(mock_image_ctx);
1686
1687 InSequence seq;
1688 Context *on_finish = nullptr;
1689 expect_refresh_image(mock_image_ctx, false, 0);
1690 expect_update_features(mock_image_ctx, &on_finish, features, enabled, 123);
1691
1692 C_SaferCond on_start_ready;
1693 C_SaferCond on_start_safe;
1694 when_process(mock_journal_replay,
1695 EventEntry{UpdateFeaturesEvent(123, features, enabled)},
1696 &on_start_ready, &on_start_safe);
1697
1698 C_SaferCond on_resume;
1699 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
1700 ASSERT_EQ(0, on_start_ready.wait());
1701
1702 C_SaferCond on_finish_ready;
1703 C_SaferCond on_finish_safe;
1704 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1705 &on_finish_ready, &on_finish_safe);
1706
1707 ASSERT_EQ(0, on_resume.wait());
1708 wait_for_op_invoked(&on_finish, 0);
1709
1710 ASSERT_EQ(0, on_start_safe.wait());
1711 ASSERT_EQ(0, on_finish_ready.wait());
1712 ASSERT_EQ(0, on_finish_safe.wait());
1713 }
1714
1715 TEST_F(TestMockJournalReplay, MetadataSetEvent) {
1716 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1717
1718 librbd::ImageCtx *ictx;
1719 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1720
1721 MockReplayImageCtx mock_image_ctx(*ictx);
1722
1723 MockExclusiveLock mock_exclusive_lock;
1724 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1725 expect_accept_ops(mock_exclusive_lock, true);
1726
1727 MockJournalReplay mock_journal_replay(mock_image_ctx);
1728 expect_op_work_queue(mock_image_ctx);
1729
1730 InSequence seq;
1731 Context *on_finish = nullptr;
1732 expect_metadata_set(mock_image_ctx, &on_finish, "key", "value");
1733 expect_refresh_image(mock_image_ctx, false, 0);
1734
1735 C_SaferCond on_start_ready;
1736 C_SaferCond on_start_safe;
1737 when_process(mock_journal_replay, EventEntry{MetadataSetEvent(123, "key", "value")},
1738 &on_start_ready, &on_start_safe);
1739 ASSERT_EQ(0, on_start_ready.wait());
1740
1741 C_SaferCond on_finish_ready;
1742 C_SaferCond on_finish_safe;
1743 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1744 &on_finish_ready, &on_finish_safe);
1745
1746 wait_for_op_invoked(&on_finish, 0);
1747 ASSERT_EQ(0, on_start_safe.wait());
1748 ASSERT_EQ(0, on_finish_ready.wait());
1749 ASSERT_EQ(0, on_finish_safe.wait());
1750 }
1751
1752 TEST_F(TestMockJournalReplay, MetadataRemoveEvent) {
1753 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1754
1755 librbd::ImageCtx *ictx;
1756 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1757
1758 MockReplayImageCtx mock_image_ctx(*ictx);
1759
1760 MockExclusiveLock mock_exclusive_lock;
1761 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1762 expect_accept_ops(mock_exclusive_lock, true);
1763
1764 MockJournalReplay mock_journal_replay(mock_image_ctx);
1765 expect_op_work_queue(mock_image_ctx);
1766
1767 InSequence seq;
1768 Context *on_finish = nullptr;
1769 expect_metadata_remove(mock_image_ctx, &on_finish, "key");
1770 expect_refresh_image(mock_image_ctx, false, 0);
1771
1772 C_SaferCond on_start_ready;
1773 C_SaferCond on_start_safe;
1774 when_process(mock_journal_replay, EventEntry{MetadataRemoveEvent(123, "key")},
1775 &on_start_ready, &on_start_safe);
1776 ASSERT_EQ(0, on_start_ready.wait());
1777
1778 C_SaferCond on_finish_ready;
1779 C_SaferCond on_finish_safe;
1780 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1781 &on_finish_ready, &on_finish_safe);
1782
1783 wait_for_op_invoked(&on_finish, 0);
1784 ASSERT_EQ(0, on_start_safe.wait());
1785 ASSERT_EQ(0, on_finish_ready.wait());
1786 ASSERT_EQ(0, on_finish_safe.wait());
1787 }
1788
1789 TEST_F(TestMockJournalReplay, MetadataRemoveEventDNE) {
1790 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1791
1792 librbd::ImageCtx *ictx;
1793 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1794
1795 MockReplayImageCtx mock_image_ctx(*ictx);
1796
1797 MockExclusiveLock mock_exclusive_lock;
1798 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1799 expect_accept_ops(mock_exclusive_lock, true);
1800
1801 MockJournalReplay mock_journal_replay(mock_image_ctx);
1802 expect_op_work_queue(mock_image_ctx);
1803
1804 InSequence seq;
1805 Context *on_finish = nullptr;
1806 expect_metadata_remove(mock_image_ctx, &on_finish, "key");
1807
1808 C_SaferCond on_start_ready;
1809 C_SaferCond on_start_safe;
1810 when_process(mock_journal_replay, EventEntry{MetadataRemoveEvent(123, "key")},
1811 &on_start_ready, &on_start_safe);
1812 ASSERT_EQ(0, on_start_ready.wait());
1813
1814 C_SaferCond on_finish_ready;
1815 C_SaferCond on_finish_safe;
1816 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1817 &on_finish_ready, &on_finish_safe);
1818
1819 wait_for_op_invoked(&on_finish, -ENOENT);
1820 ASSERT_EQ(0, on_start_safe.wait());
1821 ASSERT_EQ(0, on_finish_ready.wait());
1822 ASSERT_EQ(0, on_finish_safe.wait());
1823 }
1824
1825 TEST_F(TestMockJournalReplay, UnknownEvent) {
1826 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1827
1828 librbd::ImageCtx *ictx;
1829 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1830
1831 MockReplayImageCtx mock_image_ctx(*ictx);
1832
1833 MockExclusiveLock mock_exclusive_lock;
1834 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1835 expect_accept_ops(mock_exclusive_lock, true);
1836
1837 MockJournalReplay mock_journal_replay(mock_image_ctx);
1838 expect_op_work_queue(mock_image_ctx);
1839
1840 InSequence seq;
1841
1842 bufferlist bl;
1843 ENCODE_START(1, 1, bl);
1844 encode(static_cast<uint32_t>(-1), bl);
1845 ENCODE_FINISH(bl);
1846
1847 auto it = bl.cbegin();
1848 C_SaferCond on_ready;
1849 C_SaferCond on_safe;
1850 when_process(mock_journal_replay, &it, &on_ready, &on_safe);
1851
1852 ASSERT_EQ(0, on_safe.wait());
1853 ASSERT_EQ(0, on_ready.wait());
1854 }
1855
1856 TEST_F(TestMockJournalReplay, RefreshImageBeforeOpStart) {
1857 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1858
1859 librbd::ImageCtx *ictx;
1860 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1861
1862 MockReplayImageCtx mock_image_ctx(*ictx);
1863
1864 MockExclusiveLock mock_exclusive_lock;
1865 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1866 expect_accept_ops(mock_exclusive_lock, true);
1867
1868 MockJournalReplay mock_journal_replay(mock_image_ctx);
1869 expect_op_work_queue(mock_image_ctx);
1870
1871 InSequence seq;
1872 Context *on_finish = nullptr;
1873 expect_refresh_image(mock_image_ctx, true, 0);
1874 expect_resize(mock_image_ctx, &on_finish, 234, 123);
1875
1876 C_SaferCond on_start_ready;
1877 C_SaferCond on_start_safe;
1878 when_process(mock_journal_replay, EventEntry{ResizeEvent(123, 234)},
1879 &on_start_ready, &on_start_safe);
1880
1881 C_SaferCond on_resume;
1882 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
1883 ASSERT_EQ(0, on_start_ready.wait());
1884
1885 C_SaferCond on_finish_ready;
1886 C_SaferCond on_finish_safe;
1887 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1888 &on_finish_ready, &on_finish_safe);
1889
1890 ASSERT_EQ(0, on_resume.wait());
1891 wait_for_op_invoked(&on_finish, 0);
1892
1893 ASSERT_EQ(0, on_start_safe.wait());
1894 ASSERT_EQ(0, on_finish_ready.wait());
1895 ASSERT_EQ(0, on_finish_safe.wait());
1896 }
1897
1898 TEST_F(TestMockJournalReplay, FlushEventAfterShutDown) {
1899 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1900
1901 librbd::ImageCtx *ictx;
1902 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1903
1904 MockReplayImageCtx mock_image_ctx(*ictx);
1905
1906 MockExclusiveLock mock_exclusive_lock;
1907 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1908 expect_accept_ops(mock_exclusive_lock, true);
1909
1910 MockJournalReplay mock_journal_replay(mock_image_ctx);
1911 MockIoImageRequest mock_io_image_request;
1912 expect_op_work_queue(mock_image_ctx);
1913
1914 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1915
1916 C_SaferCond on_ready;
1917 C_SaferCond on_safe;
1918 when_process(mock_journal_replay, EventEntry{AioFlushEvent()},
1919 &on_ready, &on_safe);
1920 ASSERT_EQ(0, on_ready.wait());
1921 ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
1922 }
1923
1924 TEST_F(TestMockJournalReplay, ModifyEventAfterShutDown) {
1925 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1926
1927 librbd::ImageCtx *ictx;
1928 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1929
1930 MockReplayImageCtx mock_image_ctx(*ictx);
1931
1932 MockExclusiveLock mock_exclusive_lock;
1933 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1934 expect_accept_ops(mock_exclusive_lock, true);
1935
1936 MockJournalReplay mock_journal_replay(mock_image_ctx);
1937 MockIoImageRequest mock_io_image_request;
1938 expect_op_work_queue(mock_image_ctx);
1939
1940 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1941
1942 C_SaferCond on_ready;
1943 C_SaferCond on_safe;
1944 when_process(mock_journal_replay,
1945 EventEntry{AioWriteEvent(123, 456, to_bl("test"))},
1946 &on_ready, &on_safe);
1947 ASSERT_EQ(0, on_ready.wait());
1948 ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
1949 }
1950
1951 TEST_F(TestMockJournalReplay, OpEventAfterShutDown) {
1952 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1953
1954 librbd::ImageCtx *ictx;
1955 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1956
1957 MockReplayImageCtx mock_image_ctx(*ictx);
1958
1959 MockExclusiveLock mock_exclusive_lock;
1960 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1961 expect_accept_ops(mock_exclusive_lock, true);
1962
1963 MockJournalReplay mock_journal_replay(mock_image_ctx);
1964 MockIoImageRequest mock_io_image_request;
1965 expect_op_work_queue(mock_image_ctx);
1966
1967 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1968
1969 C_SaferCond on_ready;
1970 C_SaferCond on_safe;
1971 when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
1972 &on_ready, &on_safe);
1973 ASSERT_EQ(0, on_ready.wait());
1974 ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
1975 }
1976
1977 TEST_F(TestMockJournalReplay, LockLostBeforeProcess) {
1978 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1979
1980 librbd::ImageCtx *ictx;
1981 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1982
1983 MockReplayImageCtx mock_image_ctx(*ictx);
1984
1985 MockExclusiveLock mock_exclusive_lock;
1986 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1987 expect_accept_ops(mock_exclusive_lock, false);
1988
1989 MockJournalReplay mock_journal_replay(mock_image_ctx);
1990 MockIoImageRequest mock_io_image_request;
1991 expect_op_work_queue(mock_image_ctx);
1992
1993 InSequence seq;
1994 C_SaferCond on_ready;
1995 C_SaferCond on_safe;
1996 when_process(mock_journal_replay, EventEntry{AioFlushEvent()},
1997 &on_ready, &on_safe);
1998 ASSERT_EQ(0, on_ready.wait());
1999 ASSERT_EQ(-ECANCELED, on_safe.wait());
2000
2001 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
2002 }
2003
2004 TEST_F(TestMockJournalReplay, LockLostBeforeExecuteOp) {
2005 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
2006
2007 librbd::ImageCtx *ictx;
2008 ASSERT_EQ(0, open_image(m_image_name, &ictx));
2009
2010 MockReplayImageCtx mock_image_ctx(*ictx);
2011
2012 MockExclusiveLock mock_exclusive_lock;
2013 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
2014 expect_accept_ops(mock_exclusive_lock, false);
2015
2016 MockJournalReplay mock_journal_replay(mock_image_ctx);
2017 expect_op_work_queue(mock_image_ctx);
2018
2019 InSequence seq;
2020 EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillOnce(Return(true));
2021 EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillOnce(Return(true));
2022 expect_refresh_image(mock_image_ctx, false, 0);
2023
2024 C_SaferCond on_start_ready;
2025 C_SaferCond on_start_safe;
2026 when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
2027 &on_start_ready, &on_start_safe);
2028 ASSERT_EQ(0, on_start_ready.wait());
2029
2030 C_SaferCond on_finish_ready;
2031 C_SaferCond on_finish_safe;
2032 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
2033 &on_finish_ready, &on_finish_safe);
2034
2035 ASSERT_EQ(-ECANCELED, on_start_safe.wait());
2036 ASSERT_EQ(0, on_finish_ready.wait());
2037 ASSERT_EQ(-ECANCELED, on_finish_safe.wait());
2038 }
2039
2040 } // namespace journal
2041 } // namespace librbd