1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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"
18 struct MockContextRWL
: public C_SaferCond
{
19 MOCK_METHOD1(complete
, void(int));
20 MOCK_METHOD1(finish
, void(int));
22 void do_complete(int r
) {
23 C_SaferCond::complete(r
);
27 } // anonymous namespace
31 inline ImageCtx
*get_image_ctx(MockImageCtx
*image_ctx
) {
32 return image_ctx
->image_ctx
;
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
>;
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"
54 using ::testing::DoDefault
;
55 using ::testing::InSequence
;
56 using ::testing::Invoke
;
58 typedef io::Extent Extent
;
59 typedef io::Extents Extents
;
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
;
67 MockImageCacheStateRWL
*get_cache_state(
68 MockImageCtx
& mock_image_ctx
, MockApi
& mock_api
) {
69 MockImageCacheStateRWL
*rwl_state
= new MockImageCacheStateRWL(&mock_image_ctx
, mock_api
);
73 void validate_cache_state(librbd::ImageCtx
*image_ctx
,
74 MockImageCacheStateRWL
&state
,
75 bool present
, bool empty
, bool clean
,
76 string host
, string path
,
78 ASSERT_EQ(present
, state
.present
);
79 ASSERT_EQ(empty
, state
.empty
);
80 ASSERT_EQ(clean
, state
.clean
);
82 ASSERT_EQ(host
, state
.host
);
83 ASSERT_EQ(path
, state
.path
);
84 ASSERT_EQ(size
, state
.size
);
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
);
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
) {
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
) {
109 TEST_F(TestMockCacheReplicatedWriteLog
, init_state_write
) {
110 librbd::ImageCtx
*ictx
;
111 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
113 MockImageCtx
mock_image_ctx(*ictx
);
115 MockImageCacheStateRWL
image_cache_state(&mock_image_ctx
, mock_api
);
117 validate_cache_state(ictx
, image_cache_state
, false, true, true, "", "", 0);
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());
128 TEST_F(TestMockCacheReplicatedWriteLog
, init_state_json_write
) {
129 librbd::ImageCtx
*ictx
;
130 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
132 MockImageCtx
mock_image_ctx(*ictx
);
134 MockImageCacheStateRWL
image_cache_state(&mock_image_ctx
, mock_api
);
136 string strf
= "{ \"present\": true, \"empty\": false, \"clean\": false, \
137 \"host\": \"testhost\", \
138 \"path\": \"/tmp\", \
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);
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());
154 TEST_F(TestMockCacheReplicatedWriteLog
, init_shutdown
) {
155 librbd::ImageCtx
*ictx
;
156 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
158 MockImageCtx
mock_image_ctx(*ictx
);
159 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
168 expect_context_complete(finish_ctx1
, 0);
169 rwl
.init(&finish_ctx1
);
170 ASSERT_EQ(0, finish_ctx1
.wait());
172 MockContextRWL finish_ctx2
;
173 expect_context_complete(finish_ctx2
, 0);
174 rwl
.shut_down(&finish_ctx2
);
175 ASSERT_EQ(0, finish_ctx2
.wait());
178 TEST_F(TestMockCacheReplicatedWriteLog
, write
) {
179 librbd::ImageCtx
*ictx
;
180 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
182 MockImageCtx
mock_image_ctx(*ictx
);
183 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
185 MockReplicatedWriteLog
rwl(
186 mock_image_ctx
, get_cache_state(mock_image_ctx
, mock_api
),
187 mock_image_writeback
, mock_api
);
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());
196 MockContextRWL finish_ctx2
;
197 expect_context_complete(finish_ctx2
, 0);
198 Extents image_extents
{{0, 4096}};
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());
205 MockContextRWL finish_ctx3
;
206 expect_context_complete(finish_ctx3
, 0);
207 rwl
.shut_down(&finish_ctx3
);
208 ASSERT_EQ(0, finish_ctx3
.wait());
211 TEST_F(TestMockCacheReplicatedWriteLog
, flush
) {
212 librbd::ImageCtx
*ictx
;
213 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
215 MockImageCtx
mock_image_ctx(*ictx
);
216 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
218 MockReplicatedWriteLog
rwl(
219 mock_image_ctx
, get_cache_state(mock_image_ctx
, mock_api
),
220 mock_image_writeback
, mock_api
);
222 expect_op_work_queue(mock_image_ctx
);
223 expect_metadata_set(mock_image_ctx
);
225 MockContextRWL finish_ctx1
;
226 expect_context_complete(finish_ctx1
, 0);
227 rwl
.init(&finish_ctx1
);
228 ASSERT_EQ(0, finish_ctx1
.wait());
230 MockContextRWL finish_ctx2
;
231 expect_context_complete(finish_ctx2
, 0);
232 Extents image_extents
{{0, 4096}};
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());
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());
245 MockContextRWL finish_ctx3
;
246 expect_context_complete(finish_ctx3
, 0);
247 rwl
.shut_down(&finish_ctx3
);
249 ASSERT_EQ(0, finish_ctx3
.wait());
252 TEST_F(TestMockCacheReplicatedWriteLog
, flush_source_shutdown
) {
253 librbd::ImageCtx
*ictx
;
254 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
256 MockImageCtx
mock_image_ctx(*ictx
);
257 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
259 MockReplicatedWriteLog
rwl(
260 mock_image_ctx
, get_cache_state(mock_image_ctx
, mock_api
),
261 mock_image_writeback
, mock_api
);
263 expect_op_work_queue(mock_image_ctx
);
264 expect_metadata_set(mock_image_ctx
);
266 MockContextRWL finish_ctx1
;
267 expect_context_complete(finish_ctx1
, 0);
268 rwl
.init(&finish_ctx1
);
269 ASSERT_EQ(0, finish_ctx1
.wait());
271 MockContextRWL finish_ctx2
;
272 expect_context_complete(finish_ctx2
, 0);
273 Extents image_extents
{{0, 4096}};
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());
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());
285 MockContextRWL finish_ctx3
;
286 expect_context_complete(finish_ctx3
, 0);
287 rwl
.shut_down(&finish_ctx3
);
288 ASSERT_EQ(0, finish_ctx3
.wait());
291 TEST_F(TestMockCacheReplicatedWriteLog
, flush_source_internal
) {
292 librbd::ImageCtx
*ictx
;
293 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
295 MockImageCtx
mock_image_ctx(*ictx
);
296 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
298 MockReplicatedWriteLog
rwl(
299 mock_image_ctx
, get_cache_state(mock_image_ctx
, mock_api
),
300 mock_image_writeback
, mock_api
);
302 expect_op_work_queue(mock_image_ctx
);
303 expect_metadata_set(mock_image_ctx
);
305 MockContextRWL finish_ctx1
;
306 expect_context_complete(finish_ctx1
, 0);
307 rwl
.init(&finish_ctx1
);
308 ASSERT_EQ(0, finish_ctx1
.wait());
310 MockContextRWL finish_ctx2
;
311 expect_context_complete(finish_ctx2
, 0);
312 Extents image_extents
{{0, 4096}};
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());
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());
324 MockContextRWL finish_ctx3
;
325 expect_context_complete(finish_ctx3
, 0);
326 rwl
.shut_down(&finish_ctx3
);
327 ASSERT_EQ(0, finish_ctx3
.wait());
330 TEST_F(TestMockCacheReplicatedWriteLog
, flush_source_user
) {
331 librbd::ImageCtx
*ictx
;
332 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
334 MockImageCtx
mock_image_ctx(*ictx
);
335 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
343 MockContextRWL finish_ctx1
;
344 expect_context_complete(finish_ctx1
, 0);
345 rwl
.init(&finish_ctx1
);
346 ASSERT_EQ(0, finish_ctx1
.wait());
348 MockContextRWL finish_ctx2
;
349 expect_context_complete(finish_ctx2
, 0);
350 Extents image_extents
{{0, 4096}};
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());
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());
363 MockContextRWL finish_ctx3
;
364 expect_context_complete(finish_ctx3
, 0);
365 rwl
.shut_down(&finish_ctx3
);
366 ASSERT_EQ(0, finish_ctx3
.wait());
369 TEST_F(TestMockCacheReplicatedWriteLog
, read_hit_rwl_cache
) {
370 librbd::ImageCtx
*ictx
;
371 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
373 MockImageCtx
mock_image_ctx(*ictx
);
374 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
382 MockContextRWL finish_ctx1
;
383 expect_context_complete(finish_ctx1
, 0);
384 rwl
.init(&finish_ctx1
);
385 ASSERT_EQ(0, finish_ctx1
.wait());
387 MockContextRWL finish_ctx2
;
388 expect_context_complete(finish_ctx2
, 0);
389 Extents image_extents
{{0, 4096}};
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());
397 MockContextRWL finish_ctx_read
;
398 expect_context_complete(finish_ctx_read
, 0);
399 Extents image_extents_read
{{0, 4096}};
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
));
406 MockContextRWL finish_ctx3
;
407 expect_context_complete(finish_ctx3
, 0);
408 rwl
.shut_down(&finish_ctx3
);
409 ASSERT_EQ(0, finish_ctx3
.wait());
412 TEST_F(TestMockCacheReplicatedWriteLog
, read_hit_part_rwl_cache
) {
413 librbd::ImageCtx
*ictx
;
414 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
416 MockImageCtx
mock_image_ctx(*ictx
);
417 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
425 MockContextRWL finish_ctx1
;
426 expect_context_complete(finish_ctx1
, 0);
427 rwl
.init(&finish_ctx1
);
428 ASSERT_EQ(0, finish_ctx1
.wait());
430 MockContextRWL finish_ctx2
;
431 expect_context_complete(finish_ctx2
, 0);
432 Extents image_extents
{{0, 4096}};
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());
440 MockContextRWL finish_ctx_read
;
441 Extents image_extents_read
{{512, 4096}};
443 bl_copy
.begin(511).copy(4096-512, hit_bl
);
444 expect_context_complete(finish_ctx_read
, 512);
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
));
453 MockContextRWL finish_ctx3
;
454 expect_context_complete(finish_ctx3
, 0);
455 rwl
.shut_down(&finish_ctx3
);
456 ASSERT_EQ(0, finish_ctx3
.wait());
459 TEST_F(TestMockCacheReplicatedWriteLog
, read_miss_rwl_cache
) {
460 librbd::ImageCtx
*ictx
;
461 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
463 MockImageCtx
mock_image_ctx(*ictx
);
464 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
472 MockContextRWL finish_ctx1
;
473 expect_context_complete(finish_ctx1
, 0);
474 rwl
.init(&finish_ctx1
);
475 ASSERT_EQ(0, finish_ctx1
.wait());
477 MockContextRWL finish_ctx2
;
478 expect_context_complete(finish_ctx2
, 0);
479 Extents image_extents
{{0, 4096}};
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());
486 MockContextRWL finish_ctx_read
;
487 Extents image_extents_read
{{4096, 4096}};
488 expect_context_complete(finish_ctx_read
, 4096);
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());
495 MockContextRWL finish_ctx3
;
496 expect_context_complete(finish_ctx3
, 0);
497 rwl
.shut_down(&finish_ctx3
);
498 ASSERT_EQ(0, finish_ctx3
.wait());
501 TEST_F(TestMockCacheReplicatedWriteLog
, discard
) {
502 librbd::ImageCtx
*ictx
;
503 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
505 MockImageCtx
mock_image_ctx(*ictx
);
506 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
514 MockContextRWL finish_ctx1
;
515 expect_context_complete(finish_ctx1
, 0);
516 rwl
.init(&finish_ctx1
);
517 ASSERT_EQ(0, finish_ctx1
.wait());
519 MockContextRWL finish_ctx2
;
520 expect_context_complete(finish_ctx2
, 0);
521 Extents image_extents
{{0, 4096}};
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());
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());
534 MockContextRWL finish_ctx_read
;
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());
542 MockContextRWL finish_ctx3
;
543 expect_context_complete(finish_ctx3
, 0);
544 rwl
.shut_down(&finish_ctx3
);
546 ASSERT_EQ(0, finish_ctx3
.wait());
549 TEST_F(TestMockCacheReplicatedWriteLog
, writesame
) {
550 librbd::ImageCtx
*ictx
;
551 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
553 MockImageCtx
mock_image_ctx(*ictx
);
554 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
562 MockContextRWL finish_ctx1
;
563 expect_context_complete(finish_ctx1
, 0);
564 rwl
.init(&finish_ctx1
);
565 ASSERT_EQ(0, finish_ctx1
.wait());
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());
576 MockContextRWL finish_ctx_read
;
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
));
584 MockContextRWL finish_ctx3
;
585 expect_context_complete(finish_ctx3
, 0);
586 rwl
.shut_down(&finish_ctx3
);
588 ASSERT_EQ(0, finish_ctx3
.wait());
591 TEST_F(TestMockCacheReplicatedWriteLog
, invalidate
) {
592 librbd::ImageCtx
*ictx
;
593 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
595 MockImageCtx
mock_image_ctx(*ictx
);
596 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
604 MockContextRWL finish_ctx1
;
605 expect_context_complete(finish_ctx1
, 0);
606 rwl
.init(&finish_ctx1
);
607 ASSERT_EQ(0, finish_ctx1
.wait());
609 MockContextRWL finish_ctx2
;
610 expect_context_complete(finish_ctx2
, 0);
611 Extents image_extents
{{0, 4096}};
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());
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());
624 MockContextRWL finish_ctx3
;
625 expect_context_complete(finish_ctx3
, 0);
626 rwl
.shut_down(&finish_ctx3
);
628 ASSERT_EQ(0, finish_ctx3
.wait());
631 TEST_F(TestMockCacheReplicatedWriteLog
, compare_and_write_compare_matched
) {
632 librbd::ImageCtx
*ictx
;
633 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
635 MockImageCtx
mock_image_ctx(*ictx
);
636 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
644 MockContextRWL finish_ctx1
;
645 expect_context_complete(finish_ctx1
, 0);
646 rwl
.init(&finish_ctx1
);
647 ASSERT_EQ(0, finish_ctx1
.wait());
649 MockContextRWL finish_ctx2
;
650 expect_context_complete(finish_ctx2
, 0);
651 Extents image_extents
{{0, 4096}};
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());
659 MockContextRWL finish_ctx_cw
;
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
);
670 MockContextRWL finish_ctx_read
;
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
));
678 MockContextRWL finish_ctx3
;
679 expect_context_complete(finish_ctx3
, 0);
680 rwl
.shut_down(&finish_ctx3
);
682 ASSERT_EQ(0, finish_ctx3
.wait());
685 TEST_F(TestMockCacheReplicatedWriteLog
, compare_and_write_compare_failed
) {
686 librbd::ImageCtx
*ictx
;
687 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
689 MockImageCtx
mock_image_ctx(*ictx
);
690 MockImageWriteback
mock_image_writeback(mock_image_ctx
);
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
);
698 MockContextRWL finish_ctx1
;
699 expect_context_complete(finish_ctx1
, 0);
700 rwl
.init(&finish_ctx1
);
701 ASSERT_EQ(0, finish_ctx1
.wait());
703 MockContextRWL finish_ctx2
;
704 expect_context_complete(finish_ctx2
, 0);
705 Extents image_extents
{{0, 4096}};
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());
713 MockContextRWL finish_ctx_cw
;
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
);
724 MockContextRWL finish_ctx_read
;
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
));
732 MockContextRWL finish_ctx3
;
733 expect_context_complete(finish_ctx3
, 0);
734 rwl
.shut_down(&finish_ctx3
);
735 ASSERT_EQ(0, finish_ctx3
.wait());
740 } // namespace librbd