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