Merge remote-tracking branch 'couchbase/3.0.x' into sherlock 77/64977/1
authorDave Rigby <daver@couchbase.com>
Thu, 16 Jun 2016 08:42:22 +0000 (09:42 +0100)
committerDave Rigby <daver@couchbase.com>
Thu, 16 Jun 2016 10:24:15 +0000 (11:24 +0100)
* couchbase/3.0.x:
  MB-19204: ep_testsuite: Don't release the item while we're using it
  MB-19204: Address data race in ep_test_apis/testsuite
  MB-19204: ep_testsuite: Use std::string for last_key/body
  MB-19204: Remove alarm() call from atomic_ptr_test, reduce iteration count
  MB-19204: hash_table_test: Fix TSan issues

Start of merge of 3.1.5+ changes into sherlock, broken into multiple
merges due to the size.

Change-Id: I65530d3c81d6b5e8b0171d0e3e1da3e14e0bb308

tests/ep_test_apis.cc
tests/ep_test_apis.h
tests/ep_testsuite.cc
tests/module_tests/atomic_ptr_test.cc
tests/module_tests/hash_table_test.cc

index 4ace9fb..ffb88c7 100644 (file)
 
 std::map<std::string, std::string> vals;
 bool dump_stats = false;
-protocol_binary_response_status last_status =
-    static_cast<protocol_binary_response_status>(0);
-uint32_t last_bodylen = 0;
-char *last_key = NULL;
-char *last_body = NULL;
-bool last_deleted_flag = false;
-uint8_t last_conflict_resolution_mode = static_cast<uint8_t>(-1);
-uint64_t last_cas = 0;
-uint8_t last_datatype = 0x00;
+AtomicValue<protocol_binary_response_status> last_status(
+    static_cast<protocol_binary_response_status>(0));
+std::string last_key;
+std::string last_body;
+bool last_deleted_flag(false);
+AtomicValue<uint8_t> last_conflict_resolution_mode{0xff};
+AtomicValue<uint64_t> last_cas(0);
+AtomicValue<uint8_t> last_datatype(0x00);
 ItemMetaData last_meta;
 uint64_t last_uuid = 0;
 uint64_t last_seqno = 0;
@@ -65,16 +64,7 @@ ENGINE_ERROR_CODE vb_map_response(const void *cookie,
                                   const void *map,
                                   size_t mapsize) {
     (void)cookie;
-    last_bodylen = mapsize;
-    if (last_body) {
-        free(last_body);
-        last_body = NULL;
-    }
-    if (mapsize > 0) {
-        last_body = static_cast<char*>(malloc(mapsize));
-        cb_assert(last_body);
-        memcpy(last_body, map, mapsize);
-    }
+    last_body.assign(static_cast<const char*>(map), mapsize);
     return ENGINE_SUCCESS;
 }
 
@@ -85,28 +75,9 @@ bool add_response(const void *key, uint16_t keylen, const void *ext,
     (void)ext;
     (void)extlen;
     (void)cookie;
-    last_bodylen = bodylen;
     last_status = static_cast<protocol_binary_response_status>(status);
-    if (last_body) {
-        free(last_body);
-        last_body = NULL;
-    }
-    if (bodylen > 0) {
-        last_body = static_cast<char*>(malloc(bodylen + 1));
-        cb_assert(last_body);
-        memcpy(last_body, body, bodylen);
-        last_body[bodylen] = '\0';
-    }
-    if (last_key) {
-        free(last_key);
-        last_key = NULL;
-    }
-    if (keylen > 0) {
-        last_key = static_cast<char*>(malloc(keylen + 1));
-        cb_assert(last_key);
-        memcpy(last_key, key, keylen);
-        last_key[keylen] = '\0';
-    }
+    last_body.assign(static_cast<const char*>(body), bodylen);
+    last_key.assign(static_cast<const char*>(key), keylen);
     last_cas = cas;
     last_datatype = datatype;
     return true;
@@ -407,7 +378,7 @@ void evict_key(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
         check(last_status == PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS,
               "Expected exists when evicting key.");
     } else {
-        if (strcmp(last_body, "Already ejected.") != 0) {
+        if (last_body != "Already ejected.") {
             nonResidentItems++;
             numEjectedItems++;
         }
@@ -420,9 +391,9 @@ void evict_key(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
     check(get_int_stat(h, h1, "ep_num_value_ejects") == numEjectedItems,
           "Incorrect number of ejected items");
 
-    if (msg != NULL && strcmp(last_body, msg) != 0) {
+    if (msg != NULL && last_body != msg) {
         fprintf(stderr, "Expected evict to return ``%s'', but it returned ``%s''\n",
-                msg, last_body);
+                msg, last_body.c_str());
         abort();
     }
 }
@@ -661,12 +632,12 @@ void verify_all_vb_seqnos(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1,
     const int per_vb_resp_size = sizeof(uint16_t) + sizeof(uint64_t);
     const int high_seqno_offset = sizeof(uint16_t);
 
-    std::string seqno_body(last_body, last_bodylen);
+    std::string seqno_body = last_body;
 
     /* Check if the total response length is as expected. We expect 10 bytes
        (2 for vb_id + 8 for seqno) */
-    checkeq((uint32_t)((vb_end - vb_start + 1) * per_vb_resp_size),
-            last_bodylen, "Failed to get all vb info.");
+    checkeq((size_t)((vb_end - vb_start + 1) * per_vb_resp_size),
+            last_body.size(), "Failed to get all vb info.");
     /* Check if the contents are correct */
     for (int i = 0; i < (vb_end - vb_start + 1); i++) {
         /* Check for correct vb_id */
@@ -966,13 +937,14 @@ bool verify_vbucket_state(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, uint16_t vb,
     if (last_status != PROTOCOL_BINARY_RESPONSE_SUCCESS) {
         if (!mute) {
             fprintf(stderr, "Last protocol status was %d (%s)\n",
-                    last_status, last_body ? last_body : "unknown");
+                    last_status.load(),
+                    last_body.size() > 0 ? last_body.c_str() : "unknown");
         }
         return false;
     }
 
     vbucket_state_t state;
-    memcpy(&state, last_body, sizeof(state));
+    memcpy(&state, last_body.data(), sizeof(state));
     state = static_cast<vbucket_state_t>(ntohl(state));
     return state == expected;
 }
@@ -1221,7 +1193,7 @@ void set_degraded_mode(ENGINE_HANDLE *h,
     if (last_status != PROTOCOL_BINARY_RESPONSE_SUCCESS) {
         std::cerr << "Failed to set degraded mode to " << enable
                   << ". protocol code: " << last_status << std::endl;
-        if (last_body) {
+        if (last_body.size() > 0) {
             std::cerr << "\tBody: [" << last_body << "]" << std::endl;
         }
 
index 3ce2d12..87f289f 100644 (file)
@@ -63,18 +63,17 @@ ENGINE_ERROR_CODE vb_map_response(const void *cookie, const void *map,
 }
 #endif
 
-extern protocol_binary_response_status last_status;
-extern char *last_key;
-extern char *last_body;
+extern AtomicValue<protocol_binary_response_status> last_status;
+extern std::string last_key;
+extern std::string last_body;
 extern bool dump_stats;
 extern std::map<std::string, std::string> vals;
-extern uint32_t last_bodylen;
-extern uint64_t last_cas;
-extern uint8_t last_datatype;
+extern AtomicValue<uint64_t> last_cas;
+extern AtomicValue<uint8_t> last_datatype;
 extern uint64_t last_uuid;
 extern uint64_t last_seqno;
 extern bool last_deleted_flag;
-extern uint8_t last_conflict_resolution_mode;
+extern AtomicValue<uint8_t> last_conflict_resolution_mode;
 extern ItemMetaData last_meta;
 
 extern uint8_t dcp_last_op;
index 9846e97..457d36d 100644 (file)
@@ -193,22 +193,22 @@ static void check_observe_seqno(bool failover, uint8_t format_type, uint16_t vb_
     uint64_t recv_failover_vbuuid;
     uint64_t recv_failover_seqno;
 
-    memcpy(&recv_format_type, last_body, sizeof(uint8_t));
+    memcpy(&recv_format_type, last_body.data(), sizeof(uint8_t));
     check(recv_format_type == format_type, "Wrong format type in result");
-    memcpy(&recv_vb_id, last_body + 1, sizeof(uint16_t));
+    memcpy(&recv_vb_id, last_body.data() + 1, sizeof(uint16_t));
     check(ntohs(recv_vb_id) == vb_id, "Wrong vbucket id in result");
-    memcpy(&recv_vb_uuid, last_body + 3, sizeof(uint64_t));
+    memcpy(&recv_vb_uuid, last_body.data() + 3, sizeof(uint64_t));
     check(ntohll(recv_vb_uuid) == vb_uuid, "Wrong vbucket uuid in result");
-    memcpy(&recv_last_persisted_seqno, last_body + 11, sizeof(uint64_t));
+    memcpy(&recv_last_persisted_seqno, last_body.data() + 11, sizeof(uint64_t));
     check(ntohll(recv_last_persisted_seqno) == last_persisted_seqno,
           "Wrong persisted seqno in result");
-    memcpy(&recv_current_seqno, last_body + 19, sizeof(uint64_t));
+    memcpy(&recv_current_seqno, last_body.data() + 19, sizeof(uint64_t));
     check(ntohll(recv_current_seqno) == current_seqno, "Wrong current seqno in result");
 
     if (failover) {
-        memcpy(&recv_failover_vbuuid, last_body + 27, sizeof(uint64_t));
+        memcpy(&recv_failover_vbuuid, last_body.data() + 27, sizeof(uint64_t));
         check(ntohll(recv_failover_vbuuid) == failover_vbuuid, "Wrong failover uuid in result");
-        memcpy(&recv_failover_seqno, last_body + 35, sizeof(uint64_t));
+        memcpy(&recv_failover_seqno, last_body.data() + 35, sizeof(uint64_t));
         check(ntohll(recv_failover_seqno) == failover_seqno, "Wrong failover seqno in result");
     }
 }
@@ -243,7 +243,7 @@ static enum test_result test_getl(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
     getl(h, h1, key, vbucketId, expiration);
     check(last_status == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT,
           "expected the key to be missing...");
-    if (last_body != NULL && (strcmp(last_body, "NOT_FOUND") != 0)) {
+    if (!last_body.empty() && last_body != "NOT_FOUND") {
         fprintf(stderr, "Should have returned NOT_FOUND. Getl Failed");
         abort();
     }
@@ -258,7 +258,7 @@ static enum test_result test_getl(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
     getl(h, h1, key, vbucketId, expiration);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
           "Expected to be able to getl on first try");
-    check(strcmp("{\"lock\":\"data\"}", last_body) == 0, "Body was malformed.");
+    check(last_body == "{\"lock\":\"data\"}", "Body was malformed.");
     check(last_datatype == PROTOCOL_BINARY_DATATYPE_JSON,
             "Expected datatype to be JSON");
 
@@ -270,7 +270,7 @@ static enum test_result test_getl(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
     check(last_status == PROTOCOL_BINARY_RESPONSE_ETMPFAIL,
           "Expected to fail getl on second try");
 
-    if (last_body != NULL && (strcmp(last_body, "LOCK_ERROR") != 0)) {
+    if (!last_body.empty() && last_body != "LOCK_ERROR") {
         fprintf(stderr, "Should have returned LOCK_ERROR. Getl Failed");
         abort();
     }
@@ -407,7 +407,7 @@ static enum test_result test_unl(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
     check(last_status == PROTOCOL_BINARY_RESPONSE_ETMPFAIL,
           "Expected to fail getl on second try");
 
-    if (last_body != NULL && (strcmp(last_body, "UNLOCK_ERROR") != 0)) {
+    if (!last_body.empty() && last_body != "UNLOCK_ERROR") {
         fprintf(stderr, "Should have returned UNLOCK_ERROR. Unl Failed");
         abort();
     }
@@ -2598,8 +2598,8 @@ static enum test_result test_get_replica(ENGINE_HANDLE *h,
                               "Get Replica Failed");
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
           "Expected PROTOCOL_BINARY_RESPONSE_SUCCESS response.");
-    check(strcmp("replicadata", last_body) == 0,
-                 "Should have returned identical value");
+    check(last_body == "replicadata",
+          "Should have returned identical value");
 
     return SUCCESS;
 }
@@ -2775,7 +2775,8 @@ static enum test_result test_gat(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
     gat(h, h1, "mykey", 0, 10);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS, "gat mykey");
     check(last_datatype == PROTOCOL_BINARY_DATATYPE_JSON, "Expected datatype to be JSON");
-    check(memcmp(last_body, "{\"some\":\"value\"}", sizeof("{\"some\":\"value\"}")) == 0,
+    check(last_body.compare(0, sizeof("{\"some\":\"value\"}"),
+                            "{\"some\":\"value\"}") == 0,
           "Invalid data returned");
 
     // time-travel 9 secs..
@@ -2831,7 +2832,8 @@ static enum test_result test_gatq(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
     gat(h, h1, "mykey", 0, 10, true);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS, "gat mykey");
     check(last_datatype == PROTOCOL_BINARY_DATATYPE_JSON, "Expected datatype to be JSON");
-    check(memcmp(last_body, "{\"some\":\"value\"}", sizeof("{\"some\":\"value\"}")) == 0,
+    check(last_body.compare(0, sizeof("{\"some\":\"value\"}"),
+                            "{\"some\":\"value\"}") == 0,
           "Invalid data returned");
 
     // time-travel 9 secs..
@@ -5931,9 +5933,9 @@ static enum test_result test_dcp_consumer_mutate_with_time_sync(
     h1->unknown_command(h, NULL, request, add_response);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
             "Expected Success");
-    check(last_bodylen == sizeof(int64_t),
+    checkeq(sizeof(int64_t), last_body.size(),
             "Bodylen didn't match expected value");
-    memcpy(&adjusted_time2, last_body, last_bodylen);
+    memcpy(&adjusted_time2, last_body.data(), last_body.size());
     adjusted_time2 = ntohll(adjusted_time2);
 
     /**
@@ -6073,9 +6075,9 @@ static enum test_result test_dcp_consumer_delete_with_time_sync(
     h1->unknown_command(h, NULL, request, add_response);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
             "Expected Success");
-    check(last_bodylen == sizeof(int64_t),
+    checkeq(sizeof(int64_t), last_body.size(),
             "Bodylen didn't match expected value");
-    memcpy(&adjusted_time2, last_body, last_bodylen);
+    memcpy(&adjusted_time2, last_body.data(), last_body.size());
     adjusted_time2 = ntohll(adjusted_time2);
 
     /**
@@ -8628,7 +8630,8 @@ static enum test_result test_cluster_config(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *
         createPacket(PROTOCOL_BINARY_CMD_GET_CLUSTER_CONFIG, 1, 0, NULL, 0, NULL, 0, NULL, 0);
     check(h1->unknown_command(h, NULL, pkt2, add_response) == ENGINE_SUCCESS,
             "Failed to get cluster configuration");
-    if (memcmp(last_body, &var, 8) != 0) {
+    if (last_body.compare(0, sizeof(var), reinterpret_cast<char*>(&var),
+                          sizeof(var)) != 0) {
         return FAIL;
     } else {
         return SUCCESS;
@@ -8651,7 +8654,8 @@ static enum test_result test_not_my_vbucket_with_cluster_config(ENGINE_HANDLE *h
     ENGINE_ERROR_CODE ret = h1->unknown_command(h, NULL, pkt2,
                                                 add_response);
     check(ret == ENGINE_SUCCESS, "Should've received not_my_vbucket/cluster config");
-    if (memcmp(last_body, &var, 8) != 0) {
+    if (last_body.compare(0, sizeof(var), reinterpret_cast<char*>(&var),
+                          sizeof(var)) != 0) {
         return FAIL;
     } else {
         return SUCCESS;
@@ -8659,7 +8663,8 @@ static enum test_result test_not_my_vbucket_with_cluster_config(ENGINE_HANDLE *h
     check(verify_key(h, h1, "key", 2) == ENGINE_NOT_MY_VBUCKET, "Expected miss");
     check(h1->get_engine_vb_map(h, NULL, vb_map_response) == ENGINE_SUCCESS,
             "Failed to recover cluster configuration");
-    if (memcmp(last_body, &var, 8) != 0) {
+    if (last_body.compare(0, sizeof(var), reinterpret_cast<char*>(&var),
+                          sizeof(var)) != 0) {
         return FAIL;
     } else {
         return SUCCESS;
@@ -8704,14 +8709,14 @@ static enum test_result test_all_keys_api(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1
     size_t offset = 0;
     for (size_t i = 0; i < 5; ++i) {
         uint16_t len;
-        memcpy(&len, last_body + offset, sizeof(uint16_t));
+        memcpy(&len, last_body.data() + offset, sizeof(uint16_t));
         len = ntohs(len);
         check(keylen == len,
               "Key length mismatch in all_docs response");
         std::stringstream ss;
         ss << "key_" << start_num++;
         offset += sizeof(uint16_t);
-        check(memcmp(last_body + offset, ss.str().c_str(), keylen)
+        check(last_body.compare(offset, keylen, ss.str().c_str())
               == 0, "Key mismatch in all_keys response");
         offset += keylen;
     }
@@ -11654,9 +11659,9 @@ static enum test_result test_adjusted_time_apis(ENGINE_HANDLE *h,
     h1->unknown_command(h, NULL, request, add_response);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
             "Expected Success");
-    check(last_bodylen == sizeof(int64_t),
+    checkeq(sizeof(int64_t), last_body.size(),
             "Bodylen didn't match expected value");
-    memcpy(&adjusted_time1, last_body, last_bodylen);
+    memcpy(&adjusted_time1, last_body.data(), last_body.size());
     adjusted_time1 = ntohll(adjusted_time1);
 
     set_drift_counter_state(h, h1, 1000000, 0x01);
@@ -11666,9 +11671,9 @@ static enum test_result test_adjusted_time_apis(ENGINE_HANDLE *h,
     h1->unknown_command(h, NULL, request, add_response);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
             "Expected Success");
-    check(last_bodylen == sizeof(int64_t),
+    checkeq(sizeof(int64_t), last_body.size(),
             "Bodylen didn't match expected value");
-    memcpy(&adjusted_time2, last_body, last_bodylen);
+    memcpy(&adjusted_time2, last_body.data(), last_body.size());
     adjusted_time2 = ntohll(adjusted_time2);
 
     // adjusted_time2 should be greater than adjusted_time1 marginally
@@ -11695,9 +11700,9 @@ static enum test_result test_adjusted_time_apis(ENGINE_HANDLE *h,
     h1->unknown_command(h, NULL, request, add_response);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
             "Expected Success");
-    check(last_bodylen == sizeof(int64_t),
+    checkeq(sizeof(int64_t), last_body.size(),
             "Bodylen didn't match expected value");
-    memcpy(&adjusted_time1, last_body, last_bodylen);
+    memcpy(&adjusted_time1, last_body.data(), last_body.size());
     adjusted_time1 = ntohll(adjusted_time1);
 
     // Check that adjusted_time1 should be marginally greater than
@@ -11720,9 +11725,9 @@ static enum test_result test_adjusted_time_apis(ENGINE_HANDLE *h,
     h1->unknown_command(h, NULL, request, add_response);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
             "Expected Success");
-    check(last_bodylen == sizeof(int64_t),
+    checkeq(sizeof(int64_t), last_body.size(),
             "Bodylen didn't match expected value");
-    memcpy(&adjusted_time2, last_body, last_bodylen);
+    memcpy(&adjusted_time2, last_body.data(), last_body.size());
     adjusted_time2 = ntohll(adjusted_time2);
 
     // Check that adjusted_time2 should be marginally greater than
@@ -11903,15 +11908,15 @@ static enum test_result test_observe_single_key(ENGINE_HANDLE *h, ENGINE_HANDLE_
     uint8_t persisted;
     uint64_t cas;
 
-    memcpy(&vb, last_body, sizeof(uint16_t));
+    memcpy(&vb, last_body.data(), sizeof(uint16_t));
     check(ntohs(vb) == 0, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 2, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 2, sizeof(uint16_t));
     check(ntohs(keylen) == 3, "Wrong keylen in result");
-    memcpy(&key, last_body + 4, ntohs(keylen));
+    memcpy(&key, last_body.data() + 4, ntohs(keylen));
     check(strncmp(key, "key", 3) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 7, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 7, sizeof(uint8_t));
     check(persisted == OBS_STATE_NOT_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 8, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 8, sizeof(uint64_t));
     check(ntohll(cas) == cas1, "Wrong cas in result");
 
     return SUCCESS;
@@ -11951,15 +11956,15 @@ static enum test_result test_observe_temp_item(ENGINE_HANDLE *h, ENGINE_HANDLE_V
     uint8_t persisted;
     uint64_t cas;
 
-    memcpy(&vb, last_body, sizeof(uint16_t));
+    memcpy(&vb, last_body.data(), sizeof(uint16_t));
     check(ntohs(vb) == 0, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 2, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 2, sizeof(uint16_t));
     check(ntohs(keylen) == 3, "Wrong keylen in result");
-    memcpy(&key, last_body + 4, ntohs(keylen));
+    memcpy(&key, last_body.data() + 4, ntohs(keylen));
     check(strncmp(key, "key", 3) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 7, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 7, sizeof(uint8_t));
     check(persisted == OBS_STATE_NOT_FOUND, "Expected NOT_FOUND in result");
-    memcpy(&cas, last_body + 8, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 8, sizeof(uint64_t));
     check(ntohll(cas) == 0, "Wrong cas in result");
 
     return SUCCESS;
@@ -12007,37 +12012,37 @@ static enum test_result test_observe_multi_key(ENGINE_HANDLE *h, ENGINE_HANDLE_V
     uint8_t persisted;
     uint64_t cas;
 
-    memcpy(&vb, last_body, sizeof(uint16_t));
+    memcpy(&vb, last_body.data(), sizeof(uint16_t));
     check(ntohs(vb) == 0, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 2, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 2, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 4, ntohs(keylen));
+    memcpy(&key, last_body.data() + 4, ntohs(keylen));
     check(strncmp(key, "key1", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 8, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 8, sizeof(uint8_t));
     check(persisted == OBS_STATE_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 9, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 9, sizeof(uint64_t));
     check(ntohll(cas) == cas1, "Wrong cas in result");
 
-    memcpy(&vb, last_body + 17, sizeof(uint16_t));
+    memcpy(&vb, last_body.data() + 17, sizeof(uint16_t));
     check(ntohs(vb) == 1, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 19, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 19, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 21, ntohs(keylen));
+    memcpy(&key, last_body.data() + 21, ntohs(keylen));
     check(strncmp(key, "key2", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 25, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 25, sizeof(uint8_t));
     check(persisted == OBS_STATE_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 26, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 26, sizeof(uint64_t));
     check(ntohll(cas) == cas2, "Wrong cas in result");
 
-    memcpy(&vb, last_body + 34, sizeof(uint16_t));
+    memcpy(&vb, last_body.data() + 34, sizeof(uint16_t));
     check(ntohs(vb) == 1, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 36, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 36, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 38, ntohs(keylen));
+    memcpy(&key, last_body.data() + 38, ntohs(keylen));
     check(strncmp(key, "key3", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 42, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 42, sizeof(uint8_t));
     check(persisted == OBS_STATE_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 43, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 43, sizeof(uint64_t));
     check(ntohll(cas) == cas3, "Wrong cas in result");
 
     return SUCCESS;
@@ -12072,17 +12077,17 @@ static enum test_result test_multiple_observes(ENGINE_HANDLE *h, ENGINE_HANDLE_V
     observe(h, h1, obskeys);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS, "Expected success");
 
-    memcpy(&vb, last_body, sizeof(uint16_t));
+    memcpy(&vb, last_body.data(), sizeof(uint16_t));
     check(ntohs(vb) == 0, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 2, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 2, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 4, ntohs(keylen));
+    memcpy(&key, last_body.data() + 4, ntohs(keylen));
     check(strncmp(key, "key1", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 8, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 8, sizeof(uint8_t));
     check(persisted == OBS_STATE_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 9, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 9, sizeof(uint64_t));
     check(ntohll(cas) == cas1, "Wrong cas in result");
-    check(last_bodylen == 17, "Incorrect body length");
+    check(last_body.size() == 17, "Incorrect body length");
 
     // Do another observe
     obskeys.clear();
@@ -12090,17 +12095,17 @@ static enum test_result test_multiple_observes(ENGINE_HANDLE *h, ENGINE_HANDLE_V
     observe(h, h1, obskeys);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS, "Expected success");
 
-    memcpy(&vb, last_body, sizeof(uint16_t));
+    memcpy(&vb, last_body.data(), sizeof(uint16_t));
     check(ntohs(vb) == 0, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 2, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 2, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 4, ntohs(keylen));
+    memcpy(&key, last_body.data() + 4, ntohs(keylen));
     check(strncmp(key, "key2", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 8, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 8, sizeof(uint8_t));
     check(persisted == OBS_STATE_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 9, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 9, sizeof(uint64_t));
     check(ntohll(cas) == cas2, "Wrong cas in result");
-    check(last_bodylen == 17, "Incorrect body length");
+    check(last_body.size() == 17, "Incorrect body length");
 
     return SUCCESS;
 }
@@ -12142,33 +12147,33 @@ static enum test_result test_observe_with_not_found(ENGINE_HANDLE *h, ENGINE_HAN
     uint8_t persisted;
     uint64_t cas;
 
-    memcpy(&vb, last_body, sizeof(uint16_t));
+    memcpy(&vb, last_body.data(), sizeof(uint16_t));
     check(ntohs(vb) == 0, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 2, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 2, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 4, ntohs(keylen));
+    memcpy(&key, last_body.data() + 4, ntohs(keylen));
     check(strncmp(key, "key1", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 8, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 8, sizeof(uint8_t));
     check(persisted == OBS_STATE_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 9, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 9, sizeof(uint64_t));
     check(ntohll(cas) == cas1, "Wrong cas in result");
 
-    memcpy(&keylen, last_body + 19, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 19, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 21, ntohs(keylen));
+    memcpy(&key, last_body.data() + 21, ntohs(keylen));
     check(strncmp(key, "key2", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 25, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 25, sizeof(uint8_t));
     check(persisted == OBS_STATE_NOT_FOUND, "Expected key_not_found key status");
 
-    memcpy(&vb, last_body + 34, sizeof(uint16_t));
+    memcpy(&vb, last_body.data() + 34, sizeof(uint16_t));
     check(ntohs(vb) == 1, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 36, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 36, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 38, ntohs(keylen));
+    memcpy(&key, last_body.data() + 38, ntohs(keylen));
     check(strncmp(key, "key3", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 42, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 42, sizeof(uint8_t));
     check(persisted == OBS_STATE_LOGICAL_DEL, "Expected persisted in result");
-    memcpy(&cas, last_body + 43, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 43, sizeof(uint64_t));
     check(ntohll(cas) == cas3 + 1, "Wrong cas in result");
 
     return SUCCESS;
@@ -12477,7 +12482,7 @@ static enum test_result test_gat_locked(ENGINE_HANDLE *h,
 
     gat(h, h1, "key", 0, 10);
     check(last_status == PROTOCOL_BINARY_RESPONSE_ETMPFAIL, "Expected tmp fail");
-    check(strncmp(last_body, "Lock Error", 10) == 0, "Wrong error message");
+    check(last_body == "Lock Error", "Wrong error message");
 
     testHarness.time_travel(16);
     gat(h, h1, "key", 0, 10);
@@ -12572,7 +12577,7 @@ static enum test_result test_touch_locked(ENGINE_HANDLE *h,
 
     touch(h, h1, "key", 0, 10);
     check(last_status == PROTOCOL_BINARY_RESPONSE_ETMPFAIL, "Expected tmp fail");
-    check(strncmp(last_body, "Lock Error", 10) == 0, "Wrong error message");
+    check(last_body == "Lock Error", "Wrong error message");
 
     testHarness.time_travel(16);
     touch(h, h1, "key", 0, 10);
@@ -13233,8 +13238,7 @@ static enum test_result test_gat_with_item_eviction(ENGINE_HANDLE *h,
 
     gat(h, h1, "mykey", 0, 10); // 10 sec as expiration time
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS, "gat mykey");
-    check(memcmp(last_body, "somevalue", sizeof("somevalue")) == 0,
-          "Invalid data returned");
+    check(last_body == "somevalue", "Invalid data returned");
 
     // time-travel 9 secs..
     testHarness.time_travel(9);
@@ -13379,37 +13383,37 @@ static enum test_result test_observe_with_item_eviction(ENGINE_HANDLE *h,
     uint8_t persisted;
     uint64_t cas;
 
-    memcpy(&vb, last_body, sizeof(uint16_t));
+    memcpy(&vb, last_body.data(), sizeof(uint16_t));
     check(ntohs(vb) == 0, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 2, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 2, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 4, ntohs(keylen));
+    memcpy(&key, last_body.data() + 4, ntohs(keylen));
     check(strncmp(key, "key1", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 8, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 8, sizeof(uint8_t));
     check(persisted == OBS_STATE_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 9, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 9, sizeof(uint64_t));
     check(ntohll(cas) == cas1, "Wrong cas in result");
 
-    memcpy(&vb, last_body + 17, sizeof(uint16_t));
+    memcpy(&vb, last_body.data() + 17, sizeof(uint16_t));
     check(ntohs(vb) == 1, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 19, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 19, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 21, ntohs(keylen));
+    memcpy(&key, last_body.data() + 21, ntohs(keylen));
     check(strncmp(key, "key2", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 25, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 25, sizeof(uint8_t));
     check(persisted == OBS_STATE_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 26, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 26, sizeof(uint64_t));
     check(ntohll(cas) == cas2, "Wrong cas in result");
 
-    memcpy(&vb, last_body + 34, sizeof(uint16_t));
+    memcpy(&vb, last_body.data() + 34, sizeof(uint16_t));
     check(ntohs(vb) == 1, "Wrong vbucket in result");
-    memcpy(&keylen, last_body + 36, sizeof(uint16_t));
+    memcpy(&keylen, last_body.data() + 36, sizeof(uint16_t));
     check(ntohs(keylen) == 4, "Wrong keylen in result");
-    memcpy(&key, last_body + 38, ntohs(keylen));
+    memcpy(&key, last_body.data() + 38, ntohs(keylen));
     check(strncmp(key, "key3", 4) == 0, "Wrong key in result");
-    memcpy(&persisted, last_body + 42, sizeof(uint8_t));
+    memcpy(&persisted, last_body.data() + 42, sizeof(uint8_t));
     check(persisted == OBS_STATE_PERSISTED, "Expected persisted in result");
-    memcpy(&cas, last_body + 43, sizeof(uint64_t));
+    memcpy(&cas, last_body.data() + 43, sizeof(uint64_t));
     check(ntohll(cas) == cas3, "Wrong cas in result");
 
     return SUCCESS;
@@ -13424,8 +13428,7 @@ static enum test_result test_expired_item_with_item_eviction(ENGINE_HANDLE *h,
     h1->release(h, NULL, itm);
     gat(h, h1, "mykey", 0, 10); // 10 sec as expiration time
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS, "gat mykey");
-    check(memcmp(last_body, "somevalue", sizeof("somevalue")) == 0,
-          "Invalid data returned");
+    check(last_body == "somevalue", "Invalid data returned");
 
     // Store a dummy item since we do not purge the item with highest seqno
     check(ENGINE_SUCCESS ==
@@ -13804,9 +13807,9 @@ static enum test_result test_hlc_cas(ENGINE_HANDLE *h,
     h1->unknown_command(h, NULL, request, add_response);
     check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
             "Expected Success");
-    check(last_bodylen == sizeof(int64_t),
+    checkeq(sizeof(int64_t), last_body.size(),
             "Bodylen didn't match expected value");
-    memcpy(&adjusted_time, last_body, last_bodylen);
+    memcpy(&adjusted_time, last_body.data(), last_body.size());
     adjusted_time = ntohll(adjusted_time);
     check(adjusted_time < 0, "Adjusted time is supposed to negative");
 
@@ -14122,7 +14125,7 @@ static enum test_result test_mb17517_tap_with_locked_key(ENGINE_HANDLE *h,
 
     uint32_t lock_timeout = 10;
     getl(h, h1, key.c_str(), vbid, lock_timeout);
-    checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status,
+    checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
             "Expected to be able to getl on first try");
 
     wait_for_flusher_to_settle(h, h1);
index 075f802..c548b9f 100644 (file)
 #include "locks.h"
 #include "threadtests.h"
 
-#ifdef _MSC_VER
-#define alarm(a)
-#endif
-
 #define NUM_THREADS 50
-#define NUM_TIMES 100000
+#define NUM_TIMES 10000
 
 class Doodad : public RCValue {
 public:
@@ -135,7 +131,6 @@ static void testOperators() {
 }
 
 int main() {
-    alarm(60);
     testOperators();
     testAtomicPtr();
 }
index 333be1b..c6c3568 100644 (file)
 
 #include "threadtests.h"
 
-#ifdef _MSC_VER
-#define alarm(a)
-#endif
-
 time_t time_offset;
 
 extern "C" {
@@ -152,7 +148,7 @@ static std::vector<std::string> generateKeys(int num, int start=0) {
 // ----------------------------------------------------------------------
 
 static void testHashSize() {
-    HashTable h(global_stats);
+    HashTable h(global_stats, /*size*/0, /*locks*/1);
     cb_assert(count(h) == 0);
 
     std::string k = "testkey";
@@ -162,7 +158,7 @@ static void testHashSize() {
 }
 
 static void testHashSizeTwo() {
-    HashTable h(global_stats);
+    HashTable h(global_stats, /*size*/0, /*locks*/1);
     cb_assert(count(h) == 0);
 
     std::vector<std::string> keys = generateKeys(5);
@@ -174,7 +170,6 @@ static void testHashSizeTwo() {
 }
 
 static void testReverseDeletions() {
-    alarm(10);
     size_t initialSize = global_stats.currentSize.load();
     HashTable h(global_stats, 5, 1);
     cb_assert(count(h) == 0);
@@ -197,7 +192,6 @@ static void testReverseDeletions() {
 }
 
 static void testForwardDeletions() {
-    alarm(10);
     size_t initialSize = global_stats.currentSize.load();
     HashTable h(global_stats, 5, 1);
     cb_assert(h.getSize() == 5);
@@ -317,7 +311,7 @@ private:
 
     std::vector<std::string>  keys;
     HashTable                &ht;
-    size_t                    size;
+    AtomicValue<size_t>       size;
 };
 
 static void testConcurrentAccessResize() {
@@ -603,7 +597,6 @@ int main() {
     putenv(strdup("ALLOW_NO_STATS_UPDATE=yeah"));
     global_stats.setMaxDataSize(64*1024*1024);
     HashTable::setDefaultNumBuckets(3);
-    alarm(60);
     testHashSize();
     testHashSizeTwo();
     testReverseDeletions();