From 03314145d1bb5f4330a92d945af9df8856284724 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Thu, 30 Jun 2016 14:31:23 +0300 Subject: [PATCH] test: fix librbd tests for rbd_skip_partial_discard Signed-off-by: Mykola Golub (cherry picked from commit 9717417b7b8aa1b24a82a0bfddbfc23748188641) Conflicts: src/rocksdb this was a mistake in the original commit --- src/test/librbd/fsx.cc | 30 ++++++- src/test/librbd/journal/test_Entries.cc | 3 + src/test/librbd/journal/test_Replay.cc | 6 +- src/test/librbd/test_internal.cc | 3 + src/test/librbd/test_librbd.cc | 85 +++++++++++++------ src/test/librbd/test_support.h | 13 +-- src/test/pybind/test_rbd.py | 6 +- .../image_sync/test_mock_ObjectCopyRequest.cc | 2 + 8 files changed, 110 insertions(+), 38 deletions(-) diff --git a/src/test/librbd/fsx.cc b/src/test/librbd/fsx.cc index 1997877146ac..95a2f899480b 100644 --- a/src/test/librbd/fsx.cc +++ b/src/test/librbd/fsx.cc @@ -502,7 +502,7 @@ struct rbd_ctx { int krbd_fd; /* image /dev/rbd fd */ /* reused for nbd test */ }; -#define RBD_CTX_INIT (struct rbd_ctx) { NULL, NULL, NULL, -1 } +#define RBD_CTX_INIT (struct rbd_ctx) { NULL, NULL, NULL, -1} struct rbd_operations { int (*open)(const char *name, struct rbd_ctx *ctx); @@ -524,6 +524,7 @@ char *iname; /* name of our test image */ rados_t cluster; /* handle for our test cluster */ rados_ioctx_t ioctx; /* handle for our test pool */ struct krbd_ctx *krbd; /* handle for libkrbd */ +bool skip_partial_discard; /* rbd_skip_partial_discard config value*/ /* * librbd/krbd rbd_operations handlers. Given the rest of fsx.c, no @@ -1354,10 +1355,25 @@ report_failure(int status) #define short_at(cp) ((unsigned short)((*((unsigned char *)(cp)) << 8) | \ *(((unsigned char *)(cp)) + 1))) +int +fsxcmp(char *good_buf, char *temp_buf, unsigned size) +{ + if (!skip_partial_discard) { + return memcmp(good_buf, temp_buf, size); + } + + for (unsigned i = 0; i < size; i++) { + if (good_buf[i] != temp_buf[i] && good_buf[i] != 0) { + return good_buf[i] - temp_buf[i]; + } + } + return 0; +} + void check_buffers(char *good_buf, char *temp_buf, unsigned offset, unsigned size) { - if (memcmp(good_buf + offset, temp_buf, size) != 0) { + if (fsxcmp(good_buf + offset, temp_buf, size) != 0) { unsigned i = 0; unsigned n = 0; @@ -1448,6 +1464,7 @@ create_image() { int r; int order = 0; + char buf[32]; r = rados_create(&cluster, NULL); if (r < 0) { @@ -1505,6 +1522,15 @@ create_image() goto failed_open; } } + + r = rados_conf_get(cluster, "rbd_skip_partial_discard", buf, + sizeof(buf)); + if (r < 0) { + simple_err("Could not get rbd_skip_partial_discard value", r); + goto failed_open; + } + skip_partial_discard = (strcmp(buf, "true") == 0); + return 0; failed_open: diff --git a/src/test/librbd/journal/test_Entries.cc b/src/test/librbd/journal/test_Entries.cc index 3fd24f27c688..cea3f93dfadc 100644 --- a/src/test/librbd/journal/test_Entries.cc +++ b/src/test/librbd/journal/test_Entries.cc @@ -160,6 +160,9 @@ TEST_F(TestJournalEntries, AioWrite) { TEST_F(TestJournalEntries, AioDiscard) { REQUIRE_FEATURE(RBD_FEATURE_JOURNALING); + CephContext* cct = reinterpret_cast(_rados.cct()); + REQUIRE(!cct->_conf->rbd_skip_partial_discard); + librbd::ImageCtx *ictx; ASSERT_EQ(0, open_image(m_image_name, &ictx)); diff --git a/src/test/librbd/journal/test_Replay.cc b/src/test/librbd/journal/test_Replay.cc index ba63588f3b9f..361c6e0c7eaf 100644 --- a/src/test/librbd/journal/test_Replay.cc +++ b/src/test/librbd/journal/test_Replay.cc @@ -147,7 +147,11 @@ TEST_F(TestJournalReplay, AioDiscardEvent) { &read_payload[0], NULL, 0); ASSERT_EQ(0, aio_comp->wait_for_complete()); aio_comp->release(); - ASSERT_EQ(std::string(read_payload.size(), '\0'), read_payload); + if (ictx->cct->_conf->rbd_skip_partial_discard) { + ASSERT_EQ(payload, read_payload); + } else { + ASSERT_EQ(std::string(read_payload.size(), '\0'), read_payload); + } // check the commit position is properly updated int64_t current_tag; diff --git a/src/test/librbd/test_internal.cc b/src/test/librbd/test_internal.cc index b5c6f6b1ee43..c594c3f7a2b6 100644 --- a/src/test/librbd/test_internal.cc +++ b/src/test/librbd/test_internal.cc @@ -631,6 +631,9 @@ TEST_F(TestInternal, DiscardCopyup) { REQUIRE_FEATURE(RBD_FEATURE_LAYERING); + CephContext* cct = reinterpret_cast(_rados.cct()); + REQUIRE(!cct->_conf->rbd_skip_partial_discard); + m_image_name = get_temp_image_name(); m_image_size = 1 << 14; diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index 73c54b03d854..c03ce647154e 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -42,6 +42,8 @@ #include "test/librbd/test_support.h" #include "common/Cond.h" #include "common/Mutex.h" +#include "common/config.h" +#include "common/ceph_context.h" #include "common/errno.h" #include "include/interval_set.h" #include "include/stringify.h" @@ -1164,11 +1166,14 @@ TEST_F(TestLibRBD, TestIO) rados_ioctx_t ioctx; rados_ioctx_create(_cluster, m_pool_name.c_str(), &ioctx); + CephContext* cct = reinterpret_cast(_rados.cct()); + bool skip_discard = cct->_conf->rbd_skip_partial_discard; + rbd_image_t image; int order = 0; std::string name = get_temp_image_name(); uint64_t size = 2 << 20; - + ASSERT_EQ(0, create_image(ioctx, name.c_str(), size, &order)); ASSERT_EQ(0, rbd_open(ioctx, name.c_str(), &image, NULL)); @@ -1199,11 +1204,13 @@ TEST_F(TestLibRBD, TestIO) ASSERT_PASSED(aio_discard_test_data, image, TEST_IO_SIZE*3, TEST_IO_SIZE); ASSERT_PASSED(read_test_data, image, test_data, 0, TEST_IO_SIZE, 0); - ASSERT_PASSED(read_test_data, image, zero_data, TEST_IO_SIZE, TEST_IO_SIZE, 0); + ASSERT_PASSED(read_test_data, image, skip_discard ? test_data : zero_data, + TEST_IO_SIZE, TEST_IO_SIZE, 0); ASSERT_PASSED(read_test_data, image, test_data, TEST_IO_SIZE*2, TEST_IO_SIZE, 0); - ASSERT_PASSED(read_test_data, image, zero_data, TEST_IO_SIZE*3, TEST_IO_SIZE, 0); + ASSERT_PASSED(read_test_data, image, skip_discard ? test_data : zero_data, + TEST_IO_SIZE*3, TEST_IO_SIZE, 0); ASSERT_PASSED(read_test_data, image, test_data, TEST_IO_SIZE*4, TEST_IO_SIZE, 0); - + rbd_image_info_t info; rbd_completion_t comp; ASSERT_EQ(0, rbd_stat(image, &info, sizeof(info))); @@ -1238,6 +1245,9 @@ TEST_F(TestLibRBD, TestIOWithIOHint) rados_ioctx_t ioctx; rados_ioctx_create(_cluster, m_pool_name.c_str(), &ioctx); + CephContext* cct = reinterpret_cast(_rados.cct()); + bool skip_discard = cct->_conf->rbd_skip_partial_discard; + rbd_image_t image; int order = 0; std::string name = get_temp_image_name(); @@ -1278,11 +1288,13 @@ TEST_F(TestLibRBD, TestIOWithIOHint) ASSERT_PASSED(read_test_data, image, test_data, 0, TEST_IO_SIZE, LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL); - ASSERT_PASSED(read_test_data, image, zero_data, TEST_IO_SIZE, TEST_IO_SIZE, + ASSERT_PASSED(read_test_data, image, skip_discard ? test_data : zero_data, + TEST_IO_SIZE, TEST_IO_SIZE, LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL); ASSERT_PASSED(read_test_data, image, test_data, TEST_IO_SIZE*2, TEST_IO_SIZE, LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL); - ASSERT_PASSED(read_test_data, image, zero_data, TEST_IO_SIZE*3, TEST_IO_SIZE, + ASSERT_PASSED(read_test_data, image, skip_discard ? test_data : zero_data, + TEST_IO_SIZE*3, TEST_IO_SIZE, LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL); ASSERT_PASSED(read_test_data, image, test_data, TEST_IO_SIZE*4, TEST_IO_SIZE, 0); @@ -1442,25 +1454,28 @@ void read_test_data(librbd::Image& image, const char *expected, off_t off, size_ *passed = true; } -TEST_F(TestLibRBD, TestIOPP) +TEST_F(TestLibRBD, TestIOPP) { librados::IoCtx ioctx; ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx)); + CephContext* cct = reinterpret_cast(_rados.cct()); + bool skip_discard = cct->_conf->rbd_skip_partial_discard; + { librbd::RBD rbd; librbd::Image image; int order = 0; std::string name = get_temp_image_name(); uint64_t size = 2 << 20; - + ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), size, &order)); ASSERT_EQ(0, rbd.open(ioctx, image, name.c_str(), NULL)); char test_data[TEST_IO_SIZE + 1]; char zero_data[TEST_IO_SIZE + 1]; int i; - + for (i = 0; i < TEST_IO_SIZE; ++i) { test_data[i] = (char) (rand() % (126 - 33) + 33); } @@ -1469,24 +1484,26 @@ TEST_F(TestLibRBD, TestIOPP) for (i = 0; i < 5; ++i) ASSERT_PASSED(write_test_data, image, test_data, strlen(test_data) * i, 0); - + for (i = 5; i < 10; ++i) ASSERT_PASSED(aio_write_test_data, image, test_data, strlen(test_data) * i, 0); - + for (i = 0; i < 5; ++i) ASSERT_PASSED(read_test_data, image, test_data, strlen(test_data) * i, TEST_IO_SIZE, 0); - + for (i = 5; i < 10; ++i) ASSERT_PASSED(aio_read_test_data, image, test_data, strlen(test_data) * i, TEST_IO_SIZE, 0); // discard 2nd, 4th sections. ASSERT_PASSED(discard_test_data, image, TEST_IO_SIZE, TEST_IO_SIZE); ASSERT_PASSED(aio_discard_test_data, image, TEST_IO_SIZE*3, TEST_IO_SIZE); - + ASSERT_PASSED(read_test_data, image, test_data, 0, TEST_IO_SIZE, 0); - ASSERT_PASSED(read_test_data, image, zero_data, TEST_IO_SIZE, TEST_IO_SIZE, 0); + ASSERT_PASSED(read_test_data, image, skip_discard ? test_data : zero_data, + TEST_IO_SIZE, TEST_IO_SIZE, 0); ASSERT_PASSED(read_test_data, image, test_data, TEST_IO_SIZE*2, TEST_IO_SIZE, 0); - ASSERT_PASSED(read_test_data, image, zero_data, TEST_IO_SIZE*3, TEST_IO_SIZE, 0); + ASSERT_PASSED(read_test_data, image, skip_discard ? test_data : zero_data, + TEST_IO_SIZE*3, TEST_IO_SIZE, 0); ASSERT_PASSED(read_test_data, image, test_data, TEST_IO_SIZE*4, TEST_IO_SIZE, 0); ASSERT_PASSED(validate_object_map, image); @@ -2391,7 +2408,7 @@ static int iterate_error_cb(uint64_t off, size_t len, int exists, void *arg) return -EINVAL; } -void scribble(librbd::Image& image, int n, int max, +void scribble(librbd::Image& image, int n, int max, bool skip_discard, interval_set *exists, interval_set *what) { @@ -2402,7 +2419,7 @@ void scribble(librbd::Image& image, int n, int max, for (int i=0; i w; w.insert(off, len); @@ -2477,6 +2494,9 @@ TYPED_TEST(DiffIterateTest, DiffIterate) librados::IoCtx ioctx; ASSERT_EQ(0, this->_rados.ioctx_create(this->m_pool_name.c_str(), ioctx)); + CephContext* cct = reinterpret_cast(this->_rados.cct()); + bool skip_discard = cct->_conf->rbd_skip_partial_discard; + { librbd::RBD rbd; librbd::Image image; @@ -2494,10 +2514,10 @@ TYPED_TEST(DiffIterateTest, DiffIterate) interval_set exists; interval_set one, two; - scribble(image, 10, 102400, &exists, &one); + scribble(image, 10, 102400, skip_discard, &exists, &one); cout << " wrote " << one << std::endl; ASSERT_EQ(0, image.snap_create("one")); - scribble(image, 10, 102400, &exists, &two); + scribble(image, 10, 102400, skip_discard, &exists, &two); two = round_diff_interval(two, object_size); cout << " wrote " << two << std::endl; @@ -2625,6 +2645,9 @@ TYPED_TEST(DiffIterateTest, DiffIterateStress) librados::IoCtx ioctx; ASSERT_EQ(0, this->_rados.ioctx_create(this->m_pool_name.c_str(), ioctx)); + CephContext* cct = reinterpret_cast(this->_rados.cct()); + bool skip_discard = cct->_conf->rbd_skip_partial_discard; + librbd::RBD rbd; librbd::Image image; int order = 0; @@ -2646,7 +2669,7 @@ TYPED_TEST(DiffIterateTest, DiffIterateStress) int n = 20; for (int i=0; i w; - scribble(image, 10, 8192000, &curexists, &w); + scribble(image, 10, 8192000, skip_discard, &curexists, &w); cout << " i=" << i << " exists " << curexists << " wrote " << w << std::endl; string s = "snap" + stringify(i); ASSERT_EQ(0, image.snap_create(s.c_str())); @@ -2744,6 +2767,9 @@ TYPED_TEST(DiffIterateTest, DiffIterateIgnoreParent) librados::IoCtx ioctx; ASSERT_EQ(0, this->_rados.ioctx_create(this->m_pool_name.c_str(), ioctx)); + CephContext* cct = reinterpret_cast(this->_rados.cct()); + bool skip_discard = cct->_conf->rbd_skip_partial_discard; + librbd::RBD rbd; librbd::Image image; std::string name = this->get_temp_image_name(); @@ -2774,7 +2800,7 @@ TYPED_TEST(DiffIterateTest, DiffIterateIgnoreParent) interval_set exists; interval_set two; - scribble(image, 10, 102400, &exists, &two); + scribble(image, 10, 102400, skip_discard, &exists, &two); two = round_diff_interval(two, object_size); cout << " wrote " << two << " to clone" << std::endl; @@ -2793,6 +2819,9 @@ TYPED_TEST(DiffIterateTest, DiffIterateCallbackError) librados::IoCtx ioctx; ASSERT_EQ(0, this->_rados.ioctx_create(this->m_pool_name.c_str(), ioctx)); + CephContext* cct = reinterpret_cast(this->_rados.cct()); + bool skip_discard = cct->_conf->rbd_skip_partial_discard; + { librbd::RBD rbd; librbd::Image image; @@ -2805,7 +2834,7 @@ TYPED_TEST(DiffIterateTest, DiffIterateCallbackError) interval_set exists; interval_set one; - scribble(image, 10, 102400, &exists, &one); + scribble(image, 10, 102400, skip_discard, &exists, &one); cout << " wrote " << one << std::endl; interval_set diff; @@ -2823,6 +2852,9 @@ TYPED_TEST(DiffIterateTest, DiffIterateParentDiscard) librados::IoCtx ioctx; ASSERT_EQ(0, this->_rados.ioctx_create(this->m_pool_name.c_str(), ioctx)); + CephContext* cct = reinterpret_cast(this->_rados.cct()); + bool skip_discard = cct->_conf->rbd_skip_partial_discard; + librbd::RBD rbd; librbd::Image image; std::string name = this->get_temp_image_name(); @@ -2839,7 +2871,7 @@ TYPED_TEST(DiffIterateTest, DiffIterateParentDiscard) interval_set exists; interval_set one; - scribble(image, 10, 102400, &exists, &one); + scribble(image, 10, 102400, skip_discard, &exists, &one); ASSERT_EQ(0, image.snap_create("one")); ASSERT_EQ(1 << order, image.discard(0, 1 << order)); @@ -2854,7 +2886,7 @@ TYPED_TEST(DiffIterateTest, DiffIterateParentDiscard) ASSERT_EQ(0, rbd.open(ioctx, image, clone_name.c_str(), NULL)); interval_set two; - scribble(image, 10, 102400, &exists, &two); + scribble(image, 10, 102400, skip_discard, &exists, &two); two = round_diff_interval(two, object_size); interval_set diff; @@ -3768,6 +3800,9 @@ TEST_F(TestLibRBD, BlockingAIO) librados::IoCtx ioctx; ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx)); + CephContext* cct = reinterpret_cast(_rados.cct()); + bool skip_discard = cct->_conf->rbd_skip_partial_discard; + librbd::RBD rbd; std::string name = get_temp_image_name(); uint64_t size = 1 << 20; @@ -3820,7 +3855,7 @@ TEST_F(TestLibRBD, BlockingAIO) bufferlist expected_bl; expected_bl.append(std::string(128, '1')); - expected_bl.append(std::string(128, '\0')); + expected_bl.append(std::string(128, skip_discard ? '1' : '\0')); ASSERT_TRUE(expected_bl.contents_equal(read_bl)); } diff --git a/src/test/librbd/test_support.h b/src/test/librbd/test_support.h index 3a2298e82087..bce931ad91c3 100644 --- a/src/test/librbd/test_support.h +++ b/src/test/librbd/test_support.h @@ -11,18 +11,13 @@ int create_image_pp(librbd::RBD &rbd, librados::IoCtx &ioctx, const std::string &name, uint64_t size); int get_image_id(librbd::Image &image, std::string *image_id); -#define REQUIRE_FEATURE(feature) { \ - if (!is_feature_enabled(feature)) { \ - std::cout << "SKIPPING" << std::endl; \ - return SUCCEED(); \ - } \ -} - -#define REQUIRE_FORMAT_V1() { \ - if (is_feature_enabled(0)) { \ +#define REQUIRE(x) { \ + if (!(x)) { \ std::cout << "SKIPPING" << std::endl; \ return SUCCEED(); \ } \ } +#define REQUIRE_FEATURE(feature) REQUIRE(is_feature_enabled(feature)) +#define REQUIRE_FORMAT_V1() REQUIRE(!is_feature_enabled(0)) #define REQUIRE_FORMAT_V2() REQUIRE_FEATURE(0) diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index 5b760e14d6cd..386087dc8aa6 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -1131,6 +1131,7 @@ class TestExclusiveLock(object): image1.remove_snap('snap') def test_follower_discard(self): + global rados with Image(ioctx, image_name) as image1, Image(ioctx2, image_name) as image2: data = rand_data(256) image1.write(data, 0) @@ -1138,7 +1139,10 @@ class TestExclusiveLock(object): eq(image1.is_exclusive_lock_owner(), False) eq(image2.is_exclusive_lock_owner(), True) read = image2.read(0, 256) - eq(256 * b'\0', read) + if rados.conf_get('rbd_skip_partial_discard') == 'false': + eq(256 * b'\0', read) + else: + eq(data, read) def test_follower_write(self): with Image(ioctx, image_name) as image1, Image(ioctx2, image_name) as image2: diff --git a/src/test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc b/src/test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc index c0d60db3bf89..e27bcb6db178 100644 --- a/src/test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc +++ b/src/test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc @@ -472,6 +472,8 @@ TEST_F(TestMockImageSyncObjectCopyRequest, WriteSnaps) { } TEST_F(TestMockImageSyncObjectCopyRequest, Trim) { + ASSERT_EQ(0, metadata_set(m_remote_image_ctx, + "conf_rbd_skip_partial_discard", "false")); // scribble some data interval_set one; scribble(m_remote_image_ctx, 10, 102400, &one); -- 2.47.3