]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/cache/pwl/test_mock_ReplicatedWriteLog.cc
import ceph quincy 17.2.1
[ceph.git] / ceph / src / test / librbd / cache / pwl / test_mock_ReplicatedWriteLog.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include <iostream>
5 #include "common/hostname.h"
6 #include "test/librbd/test_mock_fixture.h"
7 #include "test/librbd/test_support.h"
8 #include "test/librbd/mock/MockImageCtx.h"
9 #include "include/rbd/librbd.hpp"
10 #include "librbd/cache/pwl/ImageCacheState.h"
11 #include "librbd/cache/pwl/Types.h"
12 #include "librbd/cache/ImageWriteback.h"
13 #include "librbd/plugin/Api.h"
14
15 namespace librbd {
16 namespace {
17
18 struct MockContextRWL : public C_SaferCond {
19 MOCK_METHOD1(complete, void(int));
20 MOCK_METHOD1(finish, void(int));
21
22 void do_complete(int r) {
23 C_SaferCond::complete(r);
24 }
25 };
26
27 } // anonymous namespace
28
29 namespace util {
30
31 inline ImageCtx *get_image_ctx(MockImageCtx *image_ctx) {
32 return image_ctx->image_ctx;
33 }
34
35 } // namespace util
36 } // namespace librbd
37
38 #include "librbd/cache/pwl/AbstractWriteLog.cc"
39 #include "librbd/cache/pwl/rwl/WriteLog.cc"
40 template class librbd::cache::pwl::rwl::WriteLog<librbd::MockImageCtx>;
41
42 // template definitions
43 #include "librbd/cache/ImageWriteback.cc"
44 #include "librbd/cache/pwl/ImageCacheState.cc"
45 #include "librbd/cache/pwl/Request.cc"
46 #include "librbd/cache/pwl/rwl/Request.cc"
47 #include "librbd/plugin/Api.cc"
48
49 namespace librbd {
50 namespace cache {
51 namespace pwl {
52
53 using ::testing::_;
54 using ::testing::DoDefault;
55 using ::testing::InSequence;
56 using ::testing::Invoke;
57
58 typedef io::Extent Extent;
59 typedef io::Extents Extents;
60
61 struct TestMockCacheReplicatedWriteLog : public TestMockFixture {
62 typedef librbd::cache::pwl::rwl::WriteLog<librbd::MockImageCtx> MockReplicatedWriteLog;
63 typedef librbd::cache::pwl::ImageCacheState<librbd::MockImageCtx> MockImageCacheStateRWL;
64 typedef librbd::cache::ImageWriteback<librbd::MockImageCtx> MockImageWriteback;
65 typedef librbd::plugin::Api<librbd::MockImageCtx> MockApi;
66
67 MockImageCacheStateRWL *get_cache_state(
68 MockImageCtx& mock_image_ctx, MockApi& mock_api) {
69 MockImageCacheStateRWL *rwl_state = new MockImageCacheStateRWL(&mock_image_ctx, mock_api);
70 return rwl_state;
71 }
72
73 void validate_cache_state(librbd::ImageCtx *image_ctx,
74 MockImageCacheStateRWL &state,
75 bool present, bool empty, bool clean,
76 string host, string path,
77 uint64_t size) {
78 ASSERT_EQ(present, state.present);
79 ASSERT_EQ(empty, state.empty);
80 ASSERT_EQ(clean, state.clean);
81
82 ASSERT_EQ(host, state.host);
83 ASSERT_EQ(path, state.path);
84 ASSERT_EQ(size, state.size);
85 }
86
87 void expect_context_complete(MockContextRWL& mock_context, int r) {
88 EXPECT_CALL(mock_context, complete(r))
89 .WillRepeatedly(Invoke([&mock_context](int r) {
90 mock_context.do_complete(r);
91 }));
92 }
93
94 void expect_metadata_set(MockImageCtx& mock_image_ctx) {
95 EXPECT_CALL(*mock_image_ctx.operations, execute_metadata_set(_, _, _))
96 .WillRepeatedly(Invoke([](std::string key, std::string val, Context* ctx) {
97 ctx->complete(0);
98 }));
99 }
100
101 void expect_metadata_remove(MockImageCtx& mock_image_ctx) {
102 EXPECT_CALL(*mock_image_ctx.operations, execute_metadata_remove(_, _))
103 .WillRepeatedly(Invoke([](std::string key, Context* ctx) {
104 ctx->complete(0);
105 }));
106 }
107 };
108
109 TEST_F(TestMockCacheReplicatedWriteLog, init_state_write) {
110 librbd::ImageCtx *ictx;
111 ASSERT_EQ(0, open_image(m_image_name, &ictx));
112
113 MockImageCtx mock_image_ctx(*ictx);
114 MockApi mock_api;
115 MockImageCacheStateRWL image_cache_state(&mock_image_ctx, mock_api);
116
117 validate_cache_state(ictx, image_cache_state, false, true, true, "", "", 0);
118
119 image_cache_state.empty = false;
120 image_cache_state.clean = false;
121 MockContextRWL finish_ctx;
122 expect_metadata_set(mock_image_ctx);
123 expect_context_complete(finish_ctx, 0);
124 image_cache_state.write_image_cache_state(&finish_ctx);
125 ASSERT_EQ(0, finish_ctx.wait());
126 }
127
128 TEST_F(TestMockCacheReplicatedWriteLog, init_state_json_write) {
129 librbd::ImageCtx *ictx;
130 ASSERT_EQ(0, open_image(m_image_name, &ictx));
131
132 MockImageCtx mock_image_ctx(*ictx);
133 MockApi mock_api;
134 MockImageCacheStateRWL image_cache_state(&mock_image_ctx, mock_api);
135
136 string strf = "{ \"present\": true, \"empty\": false, \"clean\": false, \
137 \"host\": \"testhost\", \
138 \"path\": \"/tmp\", \
139 \"mode\": \"rwl\", \
140 \"size\": 1024 }";
141 json_spirit::mValue json_root;
142 ASSERT_TRUE(json_spirit::read(strf.c_str(), json_root));
143 ASSERT_TRUE(image_cache_state.init_from_metadata(json_root));
144 validate_cache_state(ictx, image_cache_state, true, false, false,
145 "testhost", "/tmp", 1024);
146
147 MockContextRWL finish_ctx;
148 expect_metadata_remove(mock_image_ctx);
149 expect_context_complete(finish_ctx, 0);
150 image_cache_state.clear_image_cache_state(&finish_ctx);
151 ASSERT_EQ(0, finish_ctx.wait());
152 }
153
154 TEST_F(TestMockCacheReplicatedWriteLog, init_shutdown) {
155 librbd::ImageCtx *ictx;
156 ASSERT_EQ(0, open_image(m_image_name, &ictx));
157
158 MockImageCtx mock_image_ctx(*ictx);
159 MockImageWriteback mock_image_writeback(mock_image_ctx);
160 MockApi mock_api;
161 MockReplicatedWriteLog rwl(
162 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
163 mock_image_writeback, mock_api);
164 MockContextRWL finish_ctx1;
165 expect_op_work_queue(mock_image_ctx);
166 expect_metadata_set(mock_image_ctx);
167
168 expect_context_complete(finish_ctx1, 0);
169 rwl.init(&finish_ctx1);
170 ASSERT_EQ(0, finish_ctx1.wait());
171
172 MockContextRWL finish_ctx2;
173 expect_context_complete(finish_ctx2, 0);
174 rwl.shut_down(&finish_ctx2);
175 ASSERT_EQ(0, finish_ctx2.wait());
176 }
177
178 TEST_F(TestMockCacheReplicatedWriteLog, write) {
179 librbd::ImageCtx *ictx;
180 ASSERT_EQ(0, open_image(m_image_name, &ictx));
181
182 MockImageCtx mock_image_ctx(*ictx);
183 MockImageWriteback mock_image_writeback(mock_image_ctx);
184 MockApi mock_api;
185 MockReplicatedWriteLog rwl(
186 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
187 mock_image_writeback, mock_api);
188
189 MockContextRWL finish_ctx1;
190 expect_op_work_queue(mock_image_ctx);
191 expect_metadata_set(mock_image_ctx);
192 expect_context_complete(finish_ctx1, 0);
193 rwl.init(&finish_ctx1);
194 ASSERT_EQ(0, finish_ctx1.wait());
195
196 MockContextRWL finish_ctx2;
197 expect_context_complete(finish_ctx2, 0);
198 Extents image_extents{{0, 4096}};
199 bufferlist bl;
200 bl.append(std::string(4096, '1'));
201 int fadvise_flags = 0;
202 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
203 ASSERT_EQ(0, finish_ctx2.wait());
204
205 MockContextRWL finish_ctx3;
206 expect_context_complete(finish_ctx3, 0);
207 rwl.shut_down(&finish_ctx3);
208 ASSERT_EQ(0, finish_ctx3.wait());
209 }
210
211 TEST_F(TestMockCacheReplicatedWriteLog, flush) {
212 librbd::ImageCtx *ictx;
213 ASSERT_EQ(0, open_image(m_image_name, &ictx));
214
215 MockImageCtx mock_image_ctx(*ictx);
216 MockImageWriteback mock_image_writeback(mock_image_ctx);
217 MockApi mock_api;
218 MockReplicatedWriteLog rwl(
219 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
220 mock_image_writeback, mock_api);
221
222 expect_op_work_queue(mock_image_ctx);
223 expect_metadata_set(mock_image_ctx);
224
225 MockContextRWL finish_ctx1;
226 expect_context_complete(finish_ctx1, 0);
227 rwl.init(&finish_ctx1);
228 ASSERT_EQ(0, finish_ctx1.wait());
229
230 MockContextRWL finish_ctx2;
231 expect_context_complete(finish_ctx2, 0);
232 Extents image_extents{{0, 4096}};
233 bufferlist bl;
234 bl.append(std::string(4096, '1'));
235 bufferlist bl_copy = bl;
236 int fadvise_flags = 0;
237 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
238 ASSERT_EQ(0, finish_ctx2.wait());
239
240 MockContextRWL finish_ctx_flush;
241 expect_context_complete(finish_ctx_flush, 0);
242 rwl.flush(&finish_ctx_flush);
243 ASSERT_EQ(0, finish_ctx_flush.wait());
244
245 MockContextRWL finish_ctx3;
246 expect_context_complete(finish_ctx3, 0);
247 rwl.shut_down(&finish_ctx3);
248
249 ASSERT_EQ(0, finish_ctx3.wait());
250 }
251
252 TEST_F(TestMockCacheReplicatedWriteLog, flush_source_shutdown) {
253 librbd::ImageCtx *ictx;
254 ASSERT_EQ(0, open_image(m_image_name, &ictx));
255
256 MockImageCtx mock_image_ctx(*ictx);
257 MockImageWriteback mock_image_writeback(mock_image_ctx);
258 MockApi mock_api;
259 MockReplicatedWriteLog rwl(
260 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
261 mock_image_writeback, mock_api);
262
263 expect_op_work_queue(mock_image_ctx);
264 expect_metadata_set(mock_image_ctx);
265
266 MockContextRWL finish_ctx1;
267 expect_context_complete(finish_ctx1, 0);
268 rwl.init(&finish_ctx1);
269 ASSERT_EQ(0, finish_ctx1.wait());
270
271 MockContextRWL finish_ctx2;
272 expect_context_complete(finish_ctx2, 0);
273 Extents image_extents{{0, 4096}};
274 bufferlist bl;
275 bl.append(std::string(4096, '1'));
276 int fadvise_flags = 0;
277 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
278 ASSERT_EQ(0, finish_ctx2.wait());
279
280 MockContextRWL finish_ctx_flush;
281 expect_context_complete(finish_ctx_flush, 0);
282 rwl.flush(io::FLUSH_SOURCE_SHUTDOWN, &finish_ctx_flush);
283 ASSERT_EQ(0, finish_ctx_flush.wait());
284
285 MockContextRWL finish_ctx3;
286 expect_context_complete(finish_ctx3, 0);
287 rwl.shut_down(&finish_ctx3);
288 ASSERT_EQ(0, finish_ctx3.wait());
289 }
290
291 TEST_F(TestMockCacheReplicatedWriteLog, flush_source_internal) {
292 librbd::ImageCtx *ictx;
293 ASSERT_EQ(0, open_image(m_image_name, &ictx));
294
295 MockImageCtx mock_image_ctx(*ictx);
296 MockImageWriteback mock_image_writeback(mock_image_ctx);
297 MockApi mock_api;
298 MockReplicatedWriteLog rwl(
299 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
300 mock_image_writeback, mock_api);
301
302 expect_op_work_queue(mock_image_ctx);
303 expect_metadata_set(mock_image_ctx);
304
305 MockContextRWL finish_ctx1;
306 expect_context_complete(finish_ctx1, 0);
307 rwl.init(&finish_ctx1);
308 ASSERT_EQ(0, finish_ctx1.wait());
309
310 MockContextRWL finish_ctx2;
311 expect_context_complete(finish_ctx2, 0);
312 Extents image_extents{{0, 4096}};
313 bufferlist bl;
314 bl.append(std::string(4096, '1'));
315 int fadvise_flags = 0;
316 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
317 ASSERT_EQ(0, finish_ctx2.wait());
318
319 MockContextRWL finish_ctx_flush;
320 expect_context_complete(finish_ctx_flush, 0);
321 rwl.flush(io::FLUSH_SOURCE_INTERNAL, &finish_ctx_flush);
322 ASSERT_EQ(0, finish_ctx_flush.wait());
323
324 MockContextRWL finish_ctx3;
325 expect_context_complete(finish_ctx3, 0);
326 rwl.shut_down(&finish_ctx3);
327 ASSERT_EQ(0, finish_ctx3.wait());
328 }
329
330 TEST_F(TestMockCacheReplicatedWriteLog, flush_source_user) {
331 librbd::ImageCtx *ictx;
332 ASSERT_EQ(0, open_image(m_image_name, &ictx));
333
334 MockImageCtx mock_image_ctx(*ictx);
335 MockImageWriteback mock_image_writeback(mock_image_ctx);
336 MockApi mock_api;
337 MockReplicatedWriteLog rwl(
338 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
339 mock_image_writeback, mock_api);
340 expect_op_work_queue(mock_image_ctx);
341 expect_metadata_set(mock_image_ctx);
342
343 MockContextRWL finish_ctx1;
344 expect_context_complete(finish_ctx1, 0);
345 rwl.init(&finish_ctx1);
346 ASSERT_EQ(0, finish_ctx1.wait());
347
348 MockContextRWL finish_ctx2;
349 expect_context_complete(finish_ctx2, 0);
350 Extents image_extents{{0, 4096}};
351 bufferlist bl;
352 bl.append(std::string(4096, '1'));
353 int fadvise_flags = 0;
354 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
355 ASSERT_EQ(0, finish_ctx2.wait());
356
357 usleep(10000);
358 MockContextRWL finish_ctx_flush;
359 expect_context_complete(finish_ctx_flush, 0);
360 rwl.flush(io::FLUSH_SOURCE_USER, &finish_ctx_flush);
361 ASSERT_EQ(0, finish_ctx_flush.wait());
362
363 MockContextRWL finish_ctx3;
364 expect_context_complete(finish_ctx3, 0);
365 rwl.shut_down(&finish_ctx3);
366 ASSERT_EQ(0, finish_ctx3.wait());
367 }
368
369 TEST_F(TestMockCacheReplicatedWriteLog, read_hit_rwl_cache) {
370 librbd::ImageCtx *ictx;
371 ASSERT_EQ(0, open_image(m_image_name, &ictx));
372
373 MockImageCtx mock_image_ctx(*ictx);
374 MockImageWriteback mock_image_writeback(mock_image_ctx);
375 MockApi mock_api;
376 MockReplicatedWriteLog rwl(
377 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
378 mock_image_writeback, mock_api);
379 expect_op_work_queue(mock_image_ctx);
380 expect_metadata_set(mock_image_ctx);
381
382 MockContextRWL finish_ctx1;
383 expect_context_complete(finish_ctx1, 0);
384 rwl.init(&finish_ctx1);
385 ASSERT_EQ(0, finish_ctx1.wait());
386
387 MockContextRWL finish_ctx2;
388 expect_context_complete(finish_ctx2, 0);
389 Extents image_extents{{0, 4096}};
390 bufferlist bl;
391 bl.append(std::string(4096, '1'));
392 bufferlist bl_copy = bl;
393 int fadvise_flags = 0;
394 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
395 ASSERT_EQ(0, finish_ctx2.wait());
396
397 MockContextRWL finish_ctx_read;
398 expect_context_complete(finish_ctx_read, 0);
399 Extents image_extents_read{{0, 4096}};
400 bufferlist read_bl;
401 rwl.read(std::move(image_extents_read), &read_bl, fadvise_flags, &finish_ctx_read);
402 ASSERT_EQ(0, finish_ctx_read.wait());
403 ASSERT_EQ(4096, read_bl.length());
404 ASSERT_TRUE(bl_copy.contents_equal(read_bl));
405
406 MockContextRWL finish_ctx3;
407 expect_context_complete(finish_ctx3, 0);
408 rwl.shut_down(&finish_ctx3);
409 ASSERT_EQ(0, finish_ctx3.wait());
410 }
411
412 TEST_F(TestMockCacheReplicatedWriteLog, read_hit_part_rwl_cache) {
413 librbd::ImageCtx *ictx;
414 ASSERT_EQ(0, open_image(m_image_name, &ictx));
415
416 MockImageCtx mock_image_ctx(*ictx);
417 MockImageWriteback mock_image_writeback(mock_image_ctx);
418 MockApi mock_api;
419 MockReplicatedWriteLog rwl(
420 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
421 mock_image_writeback, mock_api);
422 expect_op_work_queue(mock_image_ctx);
423 expect_metadata_set(mock_image_ctx);
424
425 MockContextRWL finish_ctx1;
426 expect_context_complete(finish_ctx1, 0);
427 rwl.init(&finish_ctx1);
428 ASSERT_EQ(0, finish_ctx1.wait());
429
430 MockContextRWL finish_ctx2;
431 expect_context_complete(finish_ctx2, 0);
432 Extents image_extents{{0, 4096}};
433 bufferlist bl;
434 bl.append(std::string(4096, '1'));
435 bufferlist bl_copy = bl;
436 int fadvise_flags = 0;
437 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
438 ASSERT_EQ(0, finish_ctx2.wait());
439
440 MockContextRWL finish_ctx_read;
441 Extents image_extents_read{{512, 4096}};
442 bufferlist hit_bl;
443 bl_copy.begin(511).copy(4096-512, hit_bl);
444 expect_context_complete(finish_ctx_read, 512);
445 bufferlist read_bl;
446 rwl.read(std::move(image_extents_read), &read_bl, fadvise_flags, &finish_ctx_read);
447 ASSERT_EQ(512, finish_ctx_read.wait());
448 ASSERT_EQ(4096, read_bl.length());
449 bufferlist read_bl_hit;
450 read_bl.begin(0).copy(4096-512, read_bl_hit);
451 ASSERT_TRUE(hit_bl.contents_equal(read_bl_hit));
452
453 MockContextRWL finish_ctx3;
454 expect_context_complete(finish_ctx3, 0);
455 rwl.shut_down(&finish_ctx3);
456 ASSERT_EQ(0, finish_ctx3.wait());
457 }
458
459 TEST_F(TestMockCacheReplicatedWriteLog, read_miss_rwl_cache) {
460 librbd::ImageCtx *ictx;
461 ASSERT_EQ(0, open_image(m_image_name, &ictx));
462
463 MockImageCtx mock_image_ctx(*ictx);
464 MockImageWriteback mock_image_writeback(mock_image_ctx);
465 MockApi mock_api;
466 MockReplicatedWriteLog rwl(
467 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
468 mock_image_writeback, mock_api);
469 expect_op_work_queue(mock_image_ctx);
470 expect_metadata_set(mock_image_ctx);
471
472 MockContextRWL finish_ctx1;
473 expect_context_complete(finish_ctx1, 0);
474 rwl.init(&finish_ctx1);
475 ASSERT_EQ(0, finish_ctx1.wait());
476
477 MockContextRWL finish_ctx2;
478 expect_context_complete(finish_ctx2, 0);
479 Extents image_extents{{0, 4096}};
480 bufferlist bl;
481 bl.append(std::string(4096, '1'));
482 int fadvise_flags = 0;
483 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
484 ASSERT_EQ(0, finish_ctx2.wait());
485
486 MockContextRWL finish_ctx_read;
487 Extents image_extents_read{{4096, 4096}};
488 expect_context_complete(finish_ctx_read, 4096);
489 bufferlist read_bl;
490 ASSERT_EQ(0, read_bl.length());
491 rwl.read(std::move(image_extents_read), &read_bl, fadvise_flags, &finish_ctx_read);
492 ASSERT_EQ(4096, finish_ctx_read.wait());
493 ASSERT_EQ(4096, read_bl.length());
494
495 MockContextRWL finish_ctx3;
496 expect_context_complete(finish_ctx3, 0);
497 rwl.shut_down(&finish_ctx3);
498 ASSERT_EQ(0, finish_ctx3.wait());
499 }
500
501 TEST_F(TestMockCacheReplicatedWriteLog, discard) {
502 librbd::ImageCtx *ictx;
503 ASSERT_EQ(0, open_image(m_image_name, &ictx));
504
505 MockImageCtx mock_image_ctx(*ictx);
506 MockImageWriteback mock_image_writeback(mock_image_ctx);
507 MockApi mock_api;
508 MockReplicatedWriteLog rwl(
509 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
510 mock_image_writeback, mock_api);
511 expect_op_work_queue(mock_image_ctx);
512 expect_metadata_set(mock_image_ctx);
513
514 MockContextRWL finish_ctx1;
515 expect_context_complete(finish_ctx1, 0);
516 rwl.init(&finish_ctx1);
517 ASSERT_EQ(0, finish_ctx1.wait());
518
519 MockContextRWL finish_ctx2;
520 expect_context_complete(finish_ctx2, 0);
521 Extents image_extents{{0, 4096}};
522 bufferlist bl;
523 bl.append(std::string(4096, '1'));
524 bufferlist bl_copy = bl;
525 int fadvise_flags = 0;
526 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
527 ASSERT_EQ(0, finish_ctx2.wait());
528
529 MockContextRWL finish_ctx_discard;
530 expect_context_complete(finish_ctx_discard, 0);
531 rwl.discard(0, 4096, 1, &finish_ctx_discard);
532 ASSERT_EQ(0, finish_ctx_discard.wait());
533
534 MockContextRWL finish_ctx_read;
535 bufferlist read_bl;
536 expect_context_complete(finish_ctx_read, 0);
537 rwl.read({{0, 4096}}, &read_bl, fadvise_flags, &finish_ctx_read);
538 ASSERT_EQ(0, finish_ctx_read.wait());
539 ASSERT_EQ(4096, read_bl.length());
540 ASSERT_TRUE(read_bl.is_zero());
541
542 MockContextRWL finish_ctx3;
543 expect_context_complete(finish_ctx3, 0);
544 rwl.shut_down(&finish_ctx3);
545
546 ASSERT_EQ(0, finish_ctx3.wait());
547 }
548
549 TEST_F(TestMockCacheReplicatedWriteLog, writesame) {
550 librbd::ImageCtx *ictx;
551 ASSERT_EQ(0, open_image(m_image_name, &ictx));
552
553 MockImageCtx mock_image_ctx(*ictx);
554 MockImageWriteback mock_image_writeback(mock_image_ctx);
555 MockApi mock_api;
556 MockReplicatedWriteLog rwl(
557 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
558 mock_image_writeback, mock_api);
559 expect_op_work_queue(mock_image_ctx);
560 expect_metadata_set(mock_image_ctx);
561
562 MockContextRWL finish_ctx1;
563 expect_context_complete(finish_ctx1, 0);
564 rwl.init(&finish_ctx1);
565 ASSERT_EQ(0, finish_ctx1.wait());
566
567 MockContextRWL finish_ctx2;
568 expect_context_complete(finish_ctx2, 0);
569 bufferlist bl, test_bl;
570 bl.append(std::string(512, '1'));
571 test_bl.append(std::string(4096, '1'));
572 int fadvise_flags = 0;
573 rwl.writesame(0, 4096, std::move(bl), fadvise_flags, &finish_ctx2);
574 ASSERT_EQ(0, finish_ctx2.wait());
575
576 MockContextRWL finish_ctx_read;
577 bufferlist read_bl;
578 expect_context_complete(finish_ctx_read, 0);
579 rwl.read({{0, 4096}}, &read_bl, fadvise_flags, &finish_ctx_read);
580 ASSERT_EQ(0, finish_ctx_read.wait());
581 ASSERT_EQ(4096, read_bl.length());
582 ASSERT_TRUE(test_bl.contents_equal(read_bl));
583
584 MockContextRWL finish_ctx3;
585 expect_context_complete(finish_ctx3, 0);
586 rwl.shut_down(&finish_ctx3);
587
588 ASSERT_EQ(0, finish_ctx3.wait());
589 }
590
591 TEST_F(TestMockCacheReplicatedWriteLog, invalidate) {
592 librbd::ImageCtx *ictx;
593 ASSERT_EQ(0, open_image(m_image_name, &ictx));
594
595 MockImageCtx mock_image_ctx(*ictx);
596 MockImageWriteback mock_image_writeback(mock_image_ctx);
597 MockApi mock_api;
598 MockReplicatedWriteLog rwl(
599 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
600 mock_image_writeback, mock_api);
601 expect_op_work_queue(mock_image_ctx);
602 expect_metadata_set(mock_image_ctx);
603
604 MockContextRWL finish_ctx1;
605 expect_context_complete(finish_ctx1, 0);
606 rwl.init(&finish_ctx1);
607 ASSERT_EQ(0, finish_ctx1.wait());
608
609 MockContextRWL finish_ctx2;
610 expect_context_complete(finish_ctx2, 0);
611 Extents image_extents{{0, 4096}};
612 bufferlist bl;
613 bl.append(std::string(4096, '1'));
614 bufferlist bl_copy = bl;
615 int fadvise_flags = 0;
616 rwl.write(std::move(image_extents), std::move(bl), fadvise_flags, &finish_ctx2);
617 ASSERT_EQ(0, finish_ctx2.wait());
618
619 MockContextRWL finish_ctx_invalidate;
620 expect_context_complete(finish_ctx_invalidate, 0);
621 rwl.invalidate(&finish_ctx_invalidate);
622 ASSERT_EQ(0, finish_ctx_invalidate.wait());
623
624 MockContextRWL finish_ctx3;
625 expect_context_complete(finish_ctx3, 0);
626 rwl.shut_down(&finish_ctx3);
627
628 ASSERT_EQ(0, finish_ctx3.wait());
629 }
630
631 TEST_F(TestMockCacheReplicatedWriteLog, compare_and_write_compare_matched) {
632 librbd::ImageCtx *ictx;
633 ASSERT_EQ(0, open_image(m_image_name, &ictx));
634
635 MockImageCtx mock_image_ctx(*ictx);
636 MockImageWriteback mock_image_writeback(mock_image_ctx);
637 MockApi mock_api;
638 MockReplicatedWriteLog rwl(
639 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
640 mock_image_writeback, mock_api);
641 expect_op_work_queue(mock_image_ctx);
642 expect_metadata_set(mock_image_ctx);
643
644 MockContextRWL finish_ctx1;
645 expect_context_complete(finish_ctx1, 0);
646 rwl.init(&finish_ctx1);
647 ASSERT_EQ(0, finish_ctx1.wait());
648
649 MockContextRWL finish_ctx2;
650 expect_context_complete(finish_ctx2, 0);
651 Extents image_extents{{0, 4096}};
652 bufferlist bl1;
653 bl1.append(std::string(4096, '1'));
654 bufferlist com_bl = bl1;
655 int fadvise_flags = 0;
656 rwl.write(std::move(image_extents), std::move(bl1), fadvise_flags, &finish_ctx2);
657 ASSERT_EQ(0, finish_ctx2.wait());
658
659 MockContextRWL finish_ctx_cw;
660 bufferlist bl2;
661 bl2.append(std::string(4096, '2'));
662 bufferlist bl2_copy = bl2;
663 uint64_t mismatch_offset = -1;
664 expect_context_complete(finish_ctx_cw, 0);
665 rwl.compare_and_write({{0, 4096}}, std::move(com_bl), std::move(bl2),
666 &mismatch_offset, fadvise_flags, &finish_ctx_cw);
667 ASSERT_EQ(0, finish_ctx_cw.wait());
668 ASSERT_EQ(0, mismatch_offset);
669
670 MockContextRWL finish_ctx_read;
671 bufferlist read_bl;
672 expect_context_complete(finish_ctx_read, 0);
673 rwl.read({{0, 4096}}, &read_bl, fadvise_flags, &finish_ctx_read);
674 ASSERT_EQ(0, finish_ctx_read.wait());
675 ASSERT_EQ(4096, read_bl.length());
676 ASSERT_TRUE(bl2_copy.contents_equal(read_bl));
677
678 MockContextRWL finish_ctx3;
679 expect_context_complete(finish_ctx3, 0);
680 rwl.shut_down(&finish_ctx3);
681
682 ASSERT_EQ(0, finish_ctx3.wait());
683 }
684
685 TEST_F(TestMockCacheReplicatedWriteLog, compare_and_write_compare_failed) {
686 librbd::ImageCtx *ictx;
687 ASSERT_EQ(0, open_image(m_image_name, &ictx));
688
689 MockImageCtx mock_image_ctx(*ictx);
690 MockImageWriteback mock_image_writeback(mock_image_ctx);
691 MockApi mock_api;
692 MockReplicatedWriteLog rwl(
693 mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
694 mock_image_writeback, mock_api);
695 expect_op_work_queue(mock_image_ctx);
696 expect_metadata_set(mock_image_ctx);
697
698 MockContextRWL finish_ctx1;
699 expect_context_complete(finish_ctx1, 0);
700 rwl.init(&finish_ctx1);
701 ASSERT_EQ(0, finish_ctx1.wait());
702
703 MockContextRWL finish_ctx2;
704 expect_context_complete(finish_ctx2, 0);
705 Extents image_extents{{0, 4096}};
706 bufferlist bl1;
707 bl1.append(std::string(4096, '1'));
708 bufferlist bl1_copy = bl1;
709 int fadvise_flags = 0;
710 rwl.write(std::move(image_extents), std::move(bl1), fadvise_flags, &finish_ctx2);
711 ASSERT_EQ(0, finish_ctx2.wait());
712
713 MockContextRWL finish_ctx_cw;
714 bufferlist bl2;
715 bl2.append(std::string(4096, '2'));
716 bufferlist com_bl = bl2;
717 uint64_t mismatch_offset = -1;
718 expect_context_complete(finish_ctx_cw, -EILSEQ);
719 rwl.compare_and_write({{0, 4096}}, std::move(com_bl), std::move(bl2),
720 &mismatch_offset, fadvise_flags, &finish_ctx_cw);
721 ASSERT_EQ(-EILSEQ, finish_ctx_cw.wait());
722 ASSERT_EQ(0, mismatch_offset);
723
724 MockContextRWL finish_ctx_read;
725 bufferlist read_bl;
726 expect_context_complete(finish_ctx_read, 0);
727 rwl.read({{0, 4096}}, &read_bl, fadvise_flags, &finish_ctx_read);
728 ASSERT_EQ(0, finish_ctx_read.wait());
729 ASSERT_EQ(4096, read_bl.length());
730 ASSERT_TRUE(bl1_copy.contents_equal(read_bl));
731
732 MockContextRWL finish_ctx3;
733 expect_context_complete(finish_ctx3, 0);
734 rwl.shut_down(&finish_ctx3);
735 ASSERT_EQ(0, finish_ctx3.wait());
736 }
737
738 } // namespace pwl
739 } // namespace cache
740 } // namespace librbd