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