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