MB-23112 Fix deleteWithMeta and extended meta data input 65/74565/2 4.6.0 v4.6.1 v4.6.1-MP1
authorChris Hillery <ceej@couchbase.com>
Thu, 2 Mar 2017 22:43:22 +0000 (14:43 -0800)
committerChris Hillery <ceej@couchbase.com>
Thu, 2 Mar 2017 22:58:22 +0000 (22:58 +0000)
An incorrect offset meant that we tried to parse an incorrect
part of the packet as ExtendedMetaData.

Test code updated to cover this case.

Cherry-pic from http://review.couchbase.org/74529

Change-Id: I4121dca695028be1b14f9248e0c1917c6b28df20
Reviewed-on: http://review.couchbase.org/74565
Well-Formed: Build Bot <build@couchbase.com>
Reviewed-by: Chris Hillery <ceej@couchbase.com>
Tested-by: Chris Hillery <ceej@couchbase.com>
src/ep_engine.cc
tests/ep_testsuite_xdcr.cc

index 064c237..306aa2d 100644 (file)
@@ -5707,6 +5707,7 @@ ENGINE_ERROR_CODE EventuallyPersistentEngine::deleteWithMeta(
         if (nmeta > 0) {
             try {
                 emd.reset(new ExtendedMetaData(request->bytes +
+                                               sizeof(request->bytes) +
                                                nkey +
                                                keyOffset, nmeta));
             } catch (const std::bad_alloc&) {
index e223691..1394283 100644 (file)
@@ -1885,16 +1885,23 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
     // Watson (4.6) accepts valid encodings, but ignores them
     std::vector<char> junkMeta = {-2,-1,2,3};
 
+    int force = 0;
+
+    if (strstr(testHarness.get_current_testcase()->cfg,
+               "conflict_resolution_type=lww") != nullptr) {
+        force = FORCE_ACCEPT_WITH_META_OPS;
+    }
+
     // Set the key and junk nmeta
     set_with_meta(h, h1, "key", 3, NULL, 0, 0, &itemMeta, 0,
-                  FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                  force, PROTOCOL_BINARY_RAW_BYTES,
                   nullptr, junkMeta);
     checkeq(PROTOCOL_BINARY_RESPONSE_EINVAL, last_status.load(), "Expected EINVAL");
 
     // Set the key and junk nmeta that's quite large
     junkMeta.resize(std::numeric_limits<uint16_t>::max());
     set_with_meta(h, h1, "key", 3, NULL, 0, 0, &itemMeta, 0,
-                  FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                  force, PROTOCOL_BINARY_RAW_BYTES,
                   nullptr, junkMeta);
     checkeq(PROTOCOL_BINARY_RESPONSE_EINVAL, last_status.load(), "Expected EINVAL");
 
@@ -1942,14 +1949,14 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
 
         // Set the key with a low CAS value and real nmeta
         set_with_meta(h, h1, "key1", 4, nullptr, 0, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                      force, PROTOCOL_BINARY_RAW_BYTES,
                       nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
 
         itemMeta.cas++;
         del_with_meta(h, h1, "key1", 4, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, nullptr, validMetaVector);
+                      force, nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
     }
@@ -1964,14 +1971,14 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
 
         // Set the key with a low CAS value and real nmeta
         set_with_meta(h, h1, "key2", 4, nullptr, 0, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                      force, PROTOCOL_BINARY_RAW_BYTES,
                       nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
 
         itemMeta.cas++;
         del_with_meta(h, h1, "key2", 4, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, nullptr, validMetaVector);
+                      force, nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
     }
@@ -1988,14 +1995,14 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
 
         // Set the key with a low CAS value and real nmeta
         set_with_meta(h, h1, "key3", 4, nullptr, 0, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                      force, PROTOCOL_BINARY_RAW_BYTES,
                       nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
 
         itemMeta.cas++;
         del_with_meta(h, h1, "key3", 4, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, nullptr, validMetaVector);
+                      force, nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
     }
@@ -2012,14 +2019,14 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
 
         // Set the key with a low CAS value and real nmeta
         set_with_meta(h, h1, "key4", 4, NULL, 0, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                      force, PROTOCOL_BINARY_RAW_BYTES,
                       nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
 
         itemMeta.cas++;
         del_with_meta(h, h1, "key4", 4, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, nullptr, validMetaVector);
+                      force, nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
     }
@@ -2130,10 +2137,14 @@ BaseTestCase testsuite_testcases[] = {
                  test_cas_regeneration, test_setup, teardown,
                  "conflict_resolution_type=seqno",
                  prepare, cleanup),
-        TestCase("test CAS options and nmeta",
+        TestCase("test CAS options and nmeta (lww)",
                  test_cas_options_and_nmeta, test_setup, teardown,
                  "conflict_resolution_type=lww",
                  prepare, cleanup),
+        TestCase("test CAS options and nmeta (seqno)",
+                 test_cas_options_and_nmeta, test_setup, teardown,
+                 "conflict_resolution_type=seqno",
+                 prepare, cleanup),
 
         TestCase(NULL, NULL, NULL, NULL, NULL, prepare, cleanup)
 };