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