From 1f411c0f8536de947b3eaff1c79bb718b5044661 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Tue, 19 Feb 2019 17:45:24 +0100 Subject: [PATCH] test/librbd: add test cases for compare-and-write with copyup Signed-off-by: Ilya Dryomov --- src/test/librbd/test_librbd.cc | 124 +++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index 1fe3ce48f0b..2c3bb1102b2 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -4477,6 +4477,130 @@ TEST_F(TestLibRBD, TestPendingAio) rados_ioctx_destroy(ioctx); } +void compare_and_write_copyup(librados::IoCtx &ioctx, bool deep_copyup, + bool *passed) +{ + librbd::RBD rbd; + std::string parent_name = TestLibRBD::get_temp_image_name(); + uint64_t size = 2 << 20; + int order = 0; + ASSERT_EQ(0, create_image_pp(rbd, ioctx, parent_name.c_str(), size, &order)); + + librbd::Image parent_image; + ASSERT_EQ(0, rbd.open(ioctx, parent_image, parent_name.c_str(), NULL)); + + bufferlist bl; + bl.append(std::string(4096, '1')); + ASSERT_EQ((ssize_t)bl.length(), parent_image.write(0, bl.length(), bl)); + + ASSERT_EQ(0, parent_image.snap_create("snap1")); + ASSERT_EQ(0, parent_image.snap_protect("snap1")); + + uint64_t features; + ASSERT_EQ(0, parent_image.features(&features)); + + std::string clone_name = TestLibRBD::get_temp_image_name(); + EXPECT_EQ(0, rbd.clone(ioctx, parent_name.c_str(), "snap1", ioctx, + clone_name.c_str(), features, &order)); + + librbd::Image clone_image; + ASSERT_EQ(0, rbd.open(ioctx, clone_image, clone_name.c_str(), NULL)); + if (deep_copyup) { + ASSERT_EQ(0, clone_image.snap_create("snap1")); + } + + bufferlist cmp_bl; + cmp_bl.append(std::string(96, '1')); + bufferlist write_bl; + write_bl.append(std::string(512, '2')); + uint64_t mismatch_off; + ASSERT_EQ((ssize_t)write_bl.length(), + clone_image.compare_and_write(512, write_bl.length(), cmp_bl, + write_bl, &mismatch_off, 0)); + + bufferlist read_bl; + ASSERT_EQ(4096, clone_image.read(0, 4096, read_bl)); + + bufferlist expected_bl; + expected_bl.append(std::string(512, '1')); + expected_bl.append(std::string(512, '2')); + expected_bl.append(std::string(3072, '1')); + ASSERT_TRUE(expected_bl.contents_equal(read_bl)); + *passed = true; +} + +TEST_F(TestLibRBD, CompareAndWriteCopyup) +{ + REQUIRE_FEATURE(RBD_FEATURE_LAYERING); + + librados::IoCtx ioctx; + ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx)); + + ASSERT_PASSED(compare_and_write_copyup, ioctx, false); + ASSERT_PASSED(compare_and_write_copyup, ioctx, true); +} + +void compare_and_write_copyup_mismatch(librados::IoCtx &ioctx, + bool deep_copyup, bool *passed) +{ + librbd::RBD rbd; + std::string parent_name = TestLibRBD::get_temp_image_name(); + uint64_t size = 2 << 20; + int order = 0; + ASSERT_EQ(0, create_image_pp(rbd, ioctx, parent_name.c_str(), size, &order)); + + librbd::Image parent_image; + ASSERT_EQ(0, rbd.open(ioctx, parent_image, parent_name.c_str(), NULL)); + + bufferlist bl; + bl.append(std::string(4096, '1')); + ASSERT_EQ((ssize_t)bl.length(), parent_image.write(0, bl.length(), bl)); + + ASSERT_EQ(0, parent_image.snap_create("snap1")); + ASSERT_EQ(0, parent_image.snap_protect("snap1")); + + uint64_t features; + ASSERT_EQ(0, parent_image.features(&features)); + + std::string clone_name = TestLibRBD::get_temp_image_name(); + EXPECT_EQ(0, rbd.clone(ioctx, parent_name.c_str(), "snap1", ioctx, + clone_name.c_str(), features, &order)); + + librbd::Image clone_image; + ASSERT_EQ(0, rbd.open(ioctx, clone_image, clone_name.c_str(), NULL)); + if (deep_copyup) { + ASSERT_EQ(0, clone_image.snap_create("snap1")); + } + + bufferlist cmp_bl; + cmp_bl.append(std::string(48, '1')); + cmp_bl.append(std::string(48, '3')); + bufferlist write_bl; + write_bl.append(std::string(512, '2')); + uint64_t mismatch_off; + ASSERT_EQ(-EILSEQ, + clone_image.compare_and_write(512, write_bl.length(), cmp_bl, + write_bl, &mismatch_off, 0)); + ASSERT_EQ(48U, mismatch_off); + + bufferlist read_bl; + ASSERT_EQ(4096, clone_image.read(0, 4096, read_bl)); + + ASSERT_TRUE(bl.contents_equal(read_bl)); + *passed = true; +} + +TEST_F(TestLibRBD, CompareAndWriteCopyupMismatch) +{ + REQUIRE_FEATURE(RBD_FEATURE_LAYERING); + + librados::IoCtx ioctx; + ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx)); + + ASSERT_PASSED(compare_and_write_copyup_mismatch, ioctx, false); + ASSERT_PASSED(compare_and_write_copyup_mismatch, ioctx, true); +} + TEST_F(TestLibRBD, Flatten) { REQUIRE_FEATURE(RBD_FEATURE_LAYERING); -- 2.39.5