]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
test: fix librbd tests for rbd_skip_partial_discard
authorMykola Golub <mgolub@mirantis.com>
Thu, 30 Jun 2016 11:31:23 +0000 (14:31 +0300)
committerMykola Golub <mgolub@mirantis.com>
Fri, 19 Aug 2016 19:59:06 +0000 (22:59 +0300)
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
(cherry picked from commit 9717417b7b8aa1b24a82a0bfddbfc23748188641)

Conflicts:
src/rocksdb this was a mistake in the original commit

src/test/librbd/fsx.cc
src/test/librbd/journal/test_Entries.cc
src/test/librbd/journal/test_Replay.cc
src/test/librbd/test_internal.cc
src/test/librbd/test_librbd.cc
src/test/librbd/test_support.h
src/test/pybind/test_rbd.py
src/test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc

index 1997877146ac67df082fc16c3007cdd2d1e4fbc7..95a2f899480b1e024010be8011fdc58c8378f0dc 100644 (file)
@@ -502,7 +502,7 @@ struct rbd_ctx {
        int krbd_fd;            /* image /dev/rbd<id> 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:
index 3fd24f27c688cb0d9419a6cc7d206ea97fb69ed1..cea3f93dfadc457906fda7c920a5fada5889e7fe 100644 (file)
@@ -160,6 +160,9 @@ TEST_F(TestJournalEntries, AioWrite) {
 TEST_F(TestJournalEntries, AioDiscard) {
   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
 
+  CephContext* cct = reinterpret_cast<CephContext*>(_rados.cct());
+  REQUIRE(!cct->_conf->rbd_skip_partial_discard);
+
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
index ba63588f3b9f95facf181256a93ee8e9d2ebba0f..361c6e0c7eafb6463531f322d4bd549b7f30cb4e 100644 (file)
@@ -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;
index b5c6f6b1ee43808bac0f7a35c28de1648eaf4756..c594c3f7a2b6ebcd57ff9efacc7a31c31b755095 100644 (file)
@@ -631,6 +631,9 @@ TEST_F(TestInternal, DiscardCopyup)
 {
   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
 
+  CephContext* cct = reinterpret_cast<CephContext*>(_rados.cct());
+  REQUIRE(!cct->_conf->rbd_skip_partial_discard);
+
   m_image_name = get_temp_image_name();
   m_image_size = 1 << 14;
 
index 73c54b03d8546c20eeaa7d7a76d4dd9af66a2954..c03ce647154e3bf81b28c59a5f94a17aac15411b 100644 (file)
@@ -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<CephContext*>(_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<CephContext*>(_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<CephContext*>(_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<uint64_t> *exists,
               interval_set<uint64_t> *what)
 {
@@ -2402,7 +2419,7 @@ void scribble(librbd::Image& image, int n, int max,
   for (int i=0; i<n; i++) {
     uint64_t off = rand() % (size - max + 1);
     uint64_t len = 1 + rand() % max;
-    if (rand() % 4 == 0) {
+    if (!skip_discard && rand() % 4 == 0) {
       ASSERT_EQ((int)len, image.discard(off, len));
       interval_set<uint64_t> 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<CephContext*>(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<uint64_t> exists;
     interval_set<uint64_t> 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<CephContext*>(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<n; i++) {
     interval_set<uint64_t> 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<CephContext*>(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<uint64_t> exists;
   interval_set<uint64_t> 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<CephContext*>(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<uint64_t> exists;
     interval_set<uint64_t> one;
-    scribble(image, 10, 102400, &exists, &one);
+    scribble(image, 10, 102400, skip_discard, &exists, &one);
     cout << " wrote " << one << std::endl;
 
     interval_set<uint64_t> 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<CephContext*>(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<uint64_t> exists;
   interval_set<uint64_t> 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<uint64_t> two;
-  scribble(image, 10, 102400, &exists, &two);
+  scribble(image, 10, 102400, skip_discard, &exists, &two);
   two = round_diff_interval(two, object_size);
 
   interval_set<uint64_t> 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<CephContext*>(_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));
 }
 
index 3a2298e820876fc0ae55a7ae22efcf902252fa05..bce931ad91c3eab8ecc8e2687921129aa8c61d10 100644 (file)
@@ -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)
index 5b760e14d6cd0000cb3a37fe5613f42e9a73f042..386087dc8aa664355c28677efb2ac8db74ee541c 100644 (file)
@@ -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:
index c0d60db3bf8989ccf5435829d8ac7c11426b1d1b..e27bcb6db17800a18e3eb8fd75132f0d4cc9d7c8 100644 (file)
@@ -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<uint64_t> one;
   scribble(m_remote_image_ctx, 10, 102400, &one);