Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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_refresh_image(mock_image_ctx, false, 0);
1704   expect_metadata_set(mock_image_ctx, &on_finish, "key", "value");
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_refresh_image(mock_image_ctx, false, 0);
1741   expect_metadata_remove(mock_image_ctx, &on_finish, "key");
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_refresh_image(mock_image_ctx, false, 0);
1778   expect_metadata_remove(mock_image_ctx, &on_finish, "key");
1779
1780   C_SaferCond on_start_ready;
1781   C_SaferCond on_start_safe;
1782   when_process(mock_journal_replay, EventEntry{MetadataRemoveEvent(123, "key")},
1783                &on_start_ready, &on_start_safe);
1784   ASSERT_EQ(0, on_start_ready.wait());
1785
1786   C_SaferCond on_finish_ready;
1787   C_SaferCond on_finish_safe;
1788   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1789                &on_finish_ready, &on_finish_safe);
1790
1791   wait_for_op_invoked(&on_finish, -ENOENT);
1792   ASSERT_EQ(0, on_start_safe.wait());
1793   ASSERT_EQ(0, on_finish_ready.wait());
1794   ASSERT_EQ(0, on_finish_safe.wait());
1795 }
1796
1797 TEST_F(TestMockJournalReplay, UnknownEvent) {
1798   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1799
1800   librbd::ImageCtx *ictx;
1801   ASSERT_EQ(0, open_image(m_image_name, &ictx));
1802
1803   MockReplayImageCtx mock_image_ctx(*ictx);
1804
1805   MockExclusiveLock mock_exclusive_lock;
1806   mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1807   expect_accept_ops(mock_exclusive_lock, true);
1808
1809   MockJournalReplay mock_journal_replay(mock_image_ctx);
1810   expect_op_work_queue(mock_image_ctx);
1811
1812   InSequence seq;
1813
1814   bufferlist bl;
1815   ENCODE_START(1, 1, bl);
1816   ::encode(static_cast<uint32_t>(-1), bl);
1817   ENCODE_FINISH(bl);
1818
1819   bufferlist::iterator it = bl.begin();
1820   C_SaferCond on_ready;
1821   C_SaferCond on_safe;
1822   when_process(mock_journal_replay, &it, &on_ready, &on_safe);
1823
1824   ASSERT_EQ(0, on_safe.wait());
1825   ASSERT_EQ(0, on_ready.wait());
1826 }
1827
1828 TEST_F(TestMockJournalReplay, RefreshImageBeforeOpStart) {
1829   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1830
1831   librbd::ImageCtx *ictx;
1832   ASSERT_EQ(0, open_image(m_image_name, &ictx));
1833
1834   MockReplayImageCtx mock_image_ctx(*ictx);
1835
1836   MockExclusiveLock mock_exclusive_lock;
1837   mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1838   expect_accept_ops(mock_exclusive_lock, true);
1839
1840   MockJournalReplay mock_journal_replay(mock_image_ctx);
1841   expect_op_work_queue(mock_image_ctx);
1842
1843   InSequence seq;
1844   Context *on_finish = nullptr;
1845   expect_refresh_image(mock_image_ctx, true, 0);
1846   expect_resize(mock_image_ctx, &on_finish, 234, 123);
1847
1848   C_SaferCond on_start_ready;
1849   C_SaferCond on_start_safe;
1850   when_process(mock_journal_replay, EventEntry{ResizeEvent(123, 234)},
1851                &on_start_ready, &on_start_safe);
1852
1853   C_SaferCond on_resume;
1854   when_replay_op_ready(mock_journal_replay, 123, &on_resume);
1855   ASSERT_EQ(0, on_start_ready.wait());
1856
1857   C_SaferCond on_finish_ready;
1858   C_SaferCond on_finish_safe;
1859   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1860                &on_finish_ready, &on_finish_safe);
1861
1862   ASSERT_EQ(0, on_resume.wait());
1863   wait_for_op_invoked(&on_finish, 0);
1864
1865   ASSERT_EQ(0, on_start_safe.wait());
1866   ASSERT_EQ(0, on_finish_ready.wait());
1867   ASSERT_EQ(0, on_finish_safe.wait());
1868 }
1869
1870 TEST_F(TestMockJournalReplay, FlushEventAfterShutDown) {
1871   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1872
1873   librbd::ImageCtx *ictx;
1874   ASSERT_EQ(0, open_image(m_image_name, &ictx));
1875
1876   MockReplayImageCtx mock_image_ctx(*ictx);
1877
1878   MockExclusiveLock mock_exclusive_lock;
1879   mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1880   expect_accept_ops(mock_exclusive_lock, true);
1881
1882   MockJournalReplay mock_journal_replay(mock_image_ctx);
1883   MockIoImageRequest mock_io_image_request;
1884   expect_op_work_queue(mock_image_ctx);
1885
1886   ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1887
1888   C_SaferCond on_ready;
1889   C_SaferCond on_safe;
1890   when_process(mock_journal_replay, EventEntry{AioFlushEvent()},
1891                &on_ready, &on_safe);
1892   ASSERT_EQ(0, on_ready.wait());
1893   ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
1894 }
1895
1896 TEST_F(TestMockJournalReplay, ModifyEventAfterShutDown) {
1897   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1898
1899   librbd::ImageCtx *ictx;
1900   ASSERT_EQ(0, open_image(m_image_name, &ictx));
1901
1902   MockReplayImageCtx mock_image_ctx(*ictx);
1903
1904   MockExclusiveLock mock_exclusive_lock;
1905   mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1906   expect_accept_ops(mock_exclusive_lock, true);
1907
1908   MockJournalReplay mock_journal_replay(mock_image_ctx);
1909   MockIoImageRequest mock_io_image_request;
1910   expect_op_work_queue(mock_image_ctx);
1911
1912   ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1913
1914   C_SaferCond on_ready;
1915   C_SaferCond on_safe;
1916   when_process(mock_journal_replay,
1917                EventEntry{AioWriteEvent(123, 456, to_bl("test"))},
1918                &on_ready, &on_safe);
1919   ASSERT_EQ(0, on_ready.wait());
1920   ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
1921 }
1922
1923 TEST_F(TestMockJournalReplay, OpEventAfterShutDown) {
1924   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1925
1926   librbd::ImageCtx *ictx;
1927   ASSERT_EQ(0, open_image(m_image_name, &ictx));
1928
1929   MockReplayImageCtx mock_image_ctx(*ictx);
1930
1931   MockExclusiveLock mock_exclusive_lock;
1932   mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1933   expect_accept_ops(mock_exclusive_lock, true);
1934
1935   MockJournalReplay mock_journal_replay(mock_image_ctx);
1936   MockIoImageRequest mock_io_image_request;
1937   expect_op_work_queue(mock_image_ctx);
1938
1939   ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1940
1941   C_SaferCond on_ready;
1942   C_SaferCond on_safe;
1943   when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
1944                &on_ready, &on_safe);
1945   ASSERT_EQ(0, on_ready.wait());
1946   ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
1947 }
1948
1949 TEST_F(TestMockJournalReplay, LockLostBeforeProcess) {
1950   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1951
1952   librbd::ImageCtx *ictx;
1953   ASSERT_EQ(0, open_image(m_image_name, &ictx));
1954
1955   MockReplayImageCtx mock_image_ctx(*ictx);
1956
1957   MockExclusiveLock mock_exclusive_lock;
1958   mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1959   expect_accept_ops(mock_exclusive_lock, false);
1960
1961   MockJournalReplay mock_journal_replay(mock_image_ctx);
1962   MockIoImageRequest mock_io_image_request;
1963   expect_op_work_queue(mock_image_ctx);
1964
1965   InSequence seq;
1966   C_SaferCond on_ready;
1967   C_SaferCond on_safe;
1968   when_process(mock_journal_replay, EventEntry{AioFlushEvent()},
1969                &on_ready, &on_safe);
1970   ASSERT_EQ(0, on_ready.wait());
1971   ASSERT_EQ(-ECANCELED, on_safe.wait());
1972
1973   ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1974 }
1975
1976 TEST_F(TestMockJournalReplay, LockLostBeforeExecuteOp) {
1977   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1978
1979   librbd::ImageCtx *ictx;
1980   ASSERT_EQ(0, open_image(m_image_name, &ictx));
1981
1982   MockReplayImageCtx mock_image_ctx(*ictx);
1983
1984   MockExclusiveLock mock_exclusive_lock;
1985   mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1986   expect_accept_ops(mock_exclusive_lock, false);
1987
1988   MockJournalReplay mock_journal_replay(mock_image_ctx);
1989   expect_op_work_queue(mock_image_ctx);
1990
1991   InSequence seq;
1992   EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillOnce(Return(true));
1993   EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillOnce(Return(true));
1994   expect_refresh_image(mock_image_ctx, false, 0);
1995
1996   C_SaferCond on_start_ready;
1997   C_SaferCond on_start_safe;
1998   when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
1999                &on_start_ready, &on_start_safe);
2000   ASSERT_EQ(0, on_start_ready.wait());
2001
2002   C_SaferCond on_finish_ready;
2003   C_SaferCond on_finish_safe;
2004   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
2005                &on_finish_ready, &on_finish_safe);
2006
2007   ASSERT_EQ(-ECANCELED, on_start_safe.wait());
2008   ASSERT_EQ(0, on_finish_ready.wait());
2009   ASSERT_EQ(-ECANCELED, on_finish_safe.wait());
2010 }
2011
2012 } // namespace journal
2013 } // namespace librbd