1ccdfed7dSMike Wiederhold/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2ccdfed7dSMike Wiederhold/*
366eb94d0SMike Wiederhold *     Copyright 2012 Couchbase, Inc
4ccdfed7dSMike Wiederhold *
5ccdfed7dSMike Wiederhold *   Licensed under the Apache License, Version 2.0 (the "License");
6ccdfed7dSMike Wiederhold *   you may not use this file except in compliance with the License.
7ccdfed7dSMike Wiederhold *   You may obtain a copy of the License at
8ccdfed7dSMike Wiederhold *
9ccdfed7dSMike Wiederhold *       http://www.apache.org/licenses/LICENSE-2.0
10ccdfed7dSMike Wiederhold *
11ccdfed7dSMike Wiederhold *   Unless required by applicable law or agreed to in writing, software
12ccdfed7dSMike Wiederhold *   distributed under the License is distributed on an "AS IS" BASIS,
13ccdfed7dSMike Wiederhold *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14ccdfed7dSMike Wiederhold *   See the License for the specific language governing permissions and
15ccdfed7dSMike Wiederhold *   limitations under the License.
16ccdfed7dSMike Wiederhold */
17244c0146SMike Wiederhold
18d8d92ef7STrond Norbye#include "config.h"
194bf968b7SSundar Sridharan#include "ep_test_apis.h"
20ccdfed7dSMike Wiederhold
21244c0146SMike Wiederhold#include <memcached/util.h>
224bf968b7SSundar Sridharan#include <platform/platform.h>
23ccdfed7dSMike Wiederhold#include <stdlib.h>
24ccdfed7dSMike Wiederhold#include <string.h>
25244c0146SMike Wiederhold
26244c0146SMike Wiederhold#include <algorithm>
27244c0146SMike Wiederhold#include <iostream>
28244c0146SMike Wiederhold#include <sstream>
29ccdfed7dSMike Wiederhold
305ad7924aSMike Wiederhold#include "mock/mock_dcp.h"
31ccdfed7dSMike Wiederhold
32ccdfed7dSMike Wiederhold#define check(expr, msg) \
33ccdfed7dSMike Wiederhold    static_cast<void>((expr) ? 0 : abort_msg(#expr, msg, __LINE__))
34ccdfed7dSMike Wiederhold
35ccdfed7dSMike Wiederholdextern "C" bool abort_msg(const char *expr, const char *msg, int line);
36ccdfed7dSMike Wiederhold
37ccdfed7dSMike Wiederholdstd::map<std::string, std::string> vals;
38ccdfed7dSMike Wiederholdbool dump_stats = false;
39ccdfed7dSMike Wiederholdprotocol_binary_response_status last_status =
40ccdfed7dSMike Wiederhold    static_cast<protocol_binary_response_status>(0);
41ccdfed7dSMike Wiederholduint32_t last_bodylen = 0;
42ccdfed7dSMike Wiederholdchar *last_key = NULL;
43ccdfed7dSMike Wiederholdchar *last_body = NULL;
44ccdfed7dSMike Wiederholdbool last_deleted_flag = false;
45ccdfed7dSMike Wiederholduint64_t last_cas = 0;
46c7dadb61Sabhinavdangetiuint8_t last_datatype = 0x00;
47b4a94111SMike WiederholdItemMetaData last_meta;
48ccdfed7dSMike Wiederhold
49d8d92ef7STrond Norbyeextern "C" bool add_response_get_meta(const void *key, uint16_t keylen,
50d8d92ef7STrond Norbye                                      const void *ext, uint8_t extlen,
51d8d92ef7STrond Norbye                                      const void *body, uint32_t bodylen,
52d8d92ef7STrond Norbye                                      uint8_t datatype, uint16_t status,
53d8d92ef7STrond Norbye                                      uint64_t cas, const void *cookie);
54ccdfed7dSMike Wiederholdvoid encodeExt(char *buffer, uint32_t val);
55ccdfed7dSMike Wiederholdvoid encodeWithMetaExt(char *buffer, ItemMetaData *meta);
56ccdfed7dSMike Wiederhold
57ccdfed7dSMike Wiederholdvoid decayingSleep(useconds_t *sleepTime) {
58ccdfed7dSMike Wiederhold    static const useconds_t maxSleepTime = 500000;
59ccdfed7dSMike Wiederhold    usleep(*sleepTime);
60ccdfed7dSMike Wiederhold    *sleepTime = std::min(*sleepTime << 1, maxSleepTime);
61ccdfed7dSMike Wiederhold}
62ccdfed7dSMike Wiederhold
63de6d1bf1SabhinavdangetiENGINE_ERROR_CODE vb_map_response(const void *cookie,
64de6d1bf1Sabhinavdangeti                                  const void *map,
65de6d1bf1Sabhinavdangeti                                  size_t mapsize) {
66de6d1bf1Sabhinavdangeti    (void)cookie;
67de6d1bf1Sabhinavdangeti    last_bodylen = mapsize;
68de6d1bf1Sabhinavdangeti    if (last_body) {
69de6d1bf1Sabhinavdangeti        free(last_body);
70de6d1bf1Sabhinavdangeti        last_body = NULL;
71de6d1bf1Sabhinavdangeti    }
72de6d1bf1Sabhinavdangeti    if (mapsize > 0) {
73de6d1bf1Sabhinavdangeti        last_body = static_cast<char*>(malloc(mapsize));
74c649b2d9STrond Norbye        cb_assert(last_body);
75de6d1bf1Sabhinavdangeti        memcpy(last_body, map, mapsize);
76de6d1bf1Sabhinavdangeti    }
77de6d1bf1Sabhinavdangeti    return ENGINE_SUCCESS;
78de6d1bf1Sabhinavdangeti}
79de6d1bf1Sabhinavdangeti
80ccdfed7dSMike Wiederholdbool add_response(const void *key, uint16_t keylen, const void *ext,
81ccdfed7dSMike Wiederhold                  uint8_t extlen, const void *body, uint32_t bodylen,
82ccdfed7dSMike Wiederhold                  uint8_t datatype, uint16_t status, uint64_t cas,
83ccdfed7dSMike Wiederhold                  const void *cookie) {
84ccdfed7dSMike Wiederhold    (void)ext;
85ccdfed7dSMike Wiederhold    (void)extlen;
86ccdfed7dSMike Wiederhold    (void)cookie;
87ccdfed7dSMike Wiederhold    last_bodylen = bodylen;
88ccdfed7dSMike Wiederhold    last_status = static_cast<protocol_binary_response_status>(status);
89ccdfed7dSMike Wiederhold    if (last_body) {
90ccdfed7dSMike Wiederhold        free(last_body);
91ccdfed7dSMike Wiederhold        last_body = NULL;
92ccdfed7dSMike Wiederhold    }
93ccdfed7dSMike Wiederhold    if (bodylen > 0) {
94ccdfed7dSMike Wiederhold        last_body = static_cast<char*>(malloc(bodylen + 1));
95c649b2d9STrond Norbye        cb_assert(last_body);
96ccdfed7dSMike Wiederhold        memcpy(last_body, body, bodylen);
97ccdfed7dSMike Wiederhold        last_body[bodylen] = '\0';
98ccdfed7dSMike Wiederhold    }
99ccdfed7dSMike Wiederhold    if (last_key) {
100ccdfed7dSMike Wiederhold        free(last_key);
101ccdfed7dSMike Wiederhold        last_key = NULL;
102ccdfed7dSMike Wiederhold    }
103ccdfed7dSMike Wiederhold    if (keylen > 0) {
104ccdfed7dSMike Wiederhold        last_key = static_cast<char*>(malloc(keylen + 1));
105c649b2d9STrond Norbye        cb_assert(last_key);
106ccdfed7dSMike Wiederhold        memcpy(last_key, key, keylen);
107ccdfed7dSMike Wiederhold        last_key[keylen] = '\0';
108ccdfed7dSMike Wiederhold    }
109ccdfed7dSMike Wiederhold    last_cas = cas;
110c7dadb61Sabhinavdangeti    last_datatype = datatype;
111ccdfed7dSMike Wiederhold    return true;
112ccdfed7dSMike Wiederhold}
113ccdfed7dSMike Wiederhold
114ccdfed7dSMike Wiederholdbool add_response_get_meta(const void *key, uint16_t keylen, const void *ext,
115ccdfed7dSMike Wiederhold                           uint8_t extlen, const void *body, uint32_t bodylen,
116ccdfed7dSMike Wiederhold                           uint8_t datatype, uint16_t status, uint64_t cas,
117ccdfed7dSMike Wiederhold                           const void *cookie) {
118ccdfed7dSMike Wiederhold    (void)cookie;
119b4a94111SMike Wiederhold    const uint8_t* ext_bytes = reinterpret_cast<const uint8_t*> (ext);
120ccdfed7dSMike Wiederhold    if (ext && extlen > 0) {
121ccdfed7dSMike Wiederhold        uint32_t flags;
122b4a94111SMike Wiederhold        memcpy(&flags, ext_bytes, 4);
123ccdfed7dSMike Wiederhold        last_deleted_flag = ntohl(flags) & GET_META_ITEM_DELETED_FLAG;
124b4a94111SMike Wiederhold        memcpy(&last_meta.flags, ext_bytes + 4, 4);
125b4a94111SMike Wiederhold        memcpy(&last_meta.exptime, ext_bytes + 8, 4);
126b4a94111SMike Wiederhold        last_meta.exptime = ntohl(last_meta.exptime);
127e07dbb19SMike Wiederhold        memcpy(&last_meta.revSeqno, ext_bytes + 12, 8);
128bd27ce7dSTrond Norbye        last_meta.revSeqno = ntohll(last_meta.revSeqno);
129b4a94111SMike Wiederhold        last_meta.cas = cas;
130ccdfed7dSMike Wiederhold    }
131ccdfed7dSMike Wiederhold    return add_response(key, keylen, ext, extlen, body, bodylen, datatype,
132ccdfed7dSMike Wiederhold                        status, cas, cookie);
133ccdfed7dSMike Wiederhold}
134ccdfed7dSMike Wiederhold
135b4fc25d3SMike Wiederholdbool add_response_ret_meta(const void *key, uint16_t keylen, const void *ext,
136b4fc25d3SMike Wiederhold                           uint8_t extlen, const void *body, uint32_t bodylen,
137b4fc25d3SMike Wiederhold                           uint8_t datatype, uint16_t status, uint64_t cas,
138b4fc25d3SMike Wiederhold                           const void *cookie) {
139b4fc25d3SMike Wiederhold    (void)cookie;
140b4fc25d3SMike Wiederhold    const uint8_t* ext_bytes = reinterpret_cast<const uint8_t*> (ext);
141b4fc25d3SMike Wiederhold    if (ext && extlen == 16) {
142b4fc25d3SMike Wiederhold        memcpy(&last_meta.flags, ext_bytes, 4);
143b4fc25d3SMike Wiederhold        memcpy(&last_meta.exptime, ext_bytes + 4, 4);
144b4fc25d3SMike Wiederhold        last_meta.exptime = ntohl(last_meta.exptime);
145e07dbb19SMike Wiederhold        memcpy(&last_meta.revSeqno, ext_bytes + 8, 8);
146bd27ce7dSTrond Norbye        last_meta.revSeqno = ntohll(last_meta.revSeqno);
147b4fc25d3SMike Wiederhold        last_meta.cas = cas;
148b4fc25d3SMike Wiederhold    }
149b4fc25d3SMike Wiederhold    return add_response(key, keylen, ext, extlen, body, bodylen, datatype,
150b4fc25d3SMike Wiederhold                        status, cas, cookie);
151b4fc25d3SMike Wiederhold}
152b4fc25d3SMike Wiederhold
153ccdfed7dSMike Wiederholdvoid add_stats(const char *key, const uint16_t klen, const char *val,
154ccdfed7dSMike Wiederhold               const uint32_t vlen, const void *cookie) {
155ccdfed7dSMike Wiederhold    (void)cookie;
156ccdfed7dSMike Wiederhold    std::string k(key, klen);
157ccdfed7dSMike Wiederhold    std::string v(val, vlen);
158ccdfed7dSMike Wiederhold
159ccdfed7dSMike Wiederhold    if (dump_stats) {
160ccdfed7dSMike Wiederhold        std::cout << "stat[" << k << "] = " << v << std::endl;
161ccdfed7dSMike Wiederhold    }
162ccdfed7dSMike Wiederhold
163ccdfed7dSMike Wiederhold    vals[k] = v;
164ccdfed7dSMike Wiederhold}
165ccdfed7dSMike Wiederhold
166ccdfed7dSMike Wiederholdvoid encodeExt(char *buffer, uint32_t val) {
167ccdfed7dSMike Wiederhold    val = htonl(val);
168ccdfed7dSMike Wiederhold    memcpy(buffer, (char*)&val, sizeof(val));
169ccdfed7dSMike Wiederhold}
170ccdfed7dSMike Wiederhold
171ccdfed7dSMike Wiederholdvoid encodeWithMetaExt(char *buffer, ItemMetaData *meta) {
172de42c8caSMike Wiederhold    uint32_t flags = meta->flags;
173ccdfed7dSMike Wiederhold    uint32_t exp = htonl(meta->exptime);
174e07dbb19SMike Wiederhold    uint64_t seqno = htonll(meta->revSeqno);
175ccdfed7dSMike Wiederhold    uint64_t cas = htonll(meta->cas);
176ccdfed7dSMike Wiederhold
177ccdfed7dSMike Wiederhold    memcpy(buffer, (char*)&flags, sizeof(flags));
178ccdfed7dSMike Wiederhold    memcpy(buffer + 4, (char*)&exp, sizeof(exp));
179ccdfed7dSMike Wiederhold    memcpy(buffer + 8, (char*)&seqno, sizeof(seqno));
180ccdfed7dSMike Wiederhold    memcpy(buffer + 16, (char*)&cas, sizeof(cas));
181ccdfed7dSMike Wiederhold}
182ccdfed7dSMike Wiederhold
183ccdfed7dSMike Wiederholdprotocol_binary_request_header* createPacket(uint8_t opcode,
184ccdfed7dSMike Wiederhold                                             uint16_t vbid,
185ccdfed7dSMike Wiederhold                                             uint64_t cas,
186ccdfed7dSMike Wiederhold                                             const char *ext,
187e158e16eSSundar Sridharan                                             uint8_t extlen,
188ccdfed7dSMike Wiederhold                                             const char *key,
189ccdfed7dSMike Wiederhold                                             uint32_t keylen,
190ccdfed7dSMike Wiederhold                                             const char *val,
191284f2826Sabhinavdangeti                                             uint32_t vallen,
192284f2826Sabhinavdangeti                                             uint8_t datatype) {
193ccdfed7dSMike Wiederhold    char *pkt_raw;
194ccdfed7dSMike Wiederhold    uint32_t headerlen = sizeof(protocol_binary_request_header);
195ccdfed7dSMike Wiederhold    pkt_raw = static_cast<char*>(calloc(1, headerlen + extlen + keylen + vallen));
196c649b2d9STrond Norbye    cb_assert(pkt_raw);
197ccdfed7dSMike Wiederhold    protocol_binary_request_header *req =
198ccdfed7dSMike Wiederhold        (protocol_binary_request_header*)pkt_raw;
199ccdfed7dSMike Wiederhold    req->request.opcode = opcode;
200ccdfed7dSMike Wiederhold    req->request.keylen = htons(keylen);
201ccdfed7dSMike Wiederhold    req->request.extlen = extlen;
202ccdfed7dSMike Wiederhold    req->request.vbucket = htons(vbid);
203ccdfed7dSMike Wiederhold    req->request.bodylen = htonl(keylen + vallen + extlen);
204619e0ff3Sabhinavdangeti    req->request.cas = htonll(cas);
205284f2826Sabhinavdangeti    req->request.datatype = datatype;
206ccdfed7dSMike Wiederhold
207ccdfed7dSMike Wiederhold    if (extlen > 0) {
208ccdfed7dSMike Wiederhold        memcpy(pkt_raw + headerlen, ext, extlen);
209ccdfed7dSMike Wiederhold    }
210ccdfed7dSMike Wiederhold
211ccdfed7dSMike Wiederhold    if (keylen > 0) {
212ccdfed7dSMike Wiederhold        memcpy(pkt_raw + headerlen + extlen, key, keylen);
213ccdfed7dSMike Wiederhold    }
214ccdfed7dSMike Wiederhold
215ccdfed7dSMike Wiederhold    if (vallen > 0) {
216ccdfed7dSMike Wiederhold        memcpy(pkt_raw + headerlen + extlen + keylen, val, vallen);
217ccdfed7dSMike Wiederhold    }
218ccdfed7dSMike Wiederhold
219ccdfed7dSMike Wiederhold    return req;
220ccdfed7dSMike Wiederhold}
221ccdfed7dSMike Wiederhold
222ccdfed7dSMike Wiederholdvoid add_with_meta(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
223ccdfed7dSMike Wiederhold                   const size_t keylen, const char *val, const size_t vallen,
224d43a1deeSMike Wiederhold                   const uint32_t vb, ItemMetaData *itemMeta,
225d43a1deeSMike Wiederhold                   bool skipConflictResolution) {
226d43a1deeSMike Wiederhold    int blen = skipConflictResolution ? 28 : 24;
227dc02f4e6SMike Wiederhold    char *ext = new char[blen];
228ccdfed7dSMike Wiederhold    encodeWithMetaExt(ext, itemMeta);
229d43a1deeSMike Wiederhold
230d43a1deeSMike Wiederhold    if (skipConflictResolution) {
231d43a1deeSMike Wiederhold        uint32_t flag = SKIP_CONFLICT_RESOLUTION_FLAG;
232d43a1deeSMike Wiederhold        flag = htonl(flag);
233d43a1deeSMike Wiederhold        memcpy(ext + 24, (char*)&flag, sizeof(flag));
234d43a1deeSMike Wiederhold    }
235d43a1deeSMike Wiederhold
236ccdfed7dSMike Wiederhold    protocol_binary_request_header *pkt;
2370389c521STrond Norbye    pkt = createPacket(PROTOCOL_BINARY_CMD_ADD_WITH_META, vb, 0, ext, blen, key, keylen,
238ccdfed7dSMike Wiederhold                       val, vallen);
239ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, pkt, add_response) == ENGINE_SUCCESS,
240ccdfed7dSMike Wiederhold          "Expected to be able to store with meta");
241dc02f4e6SMike Wiederhold    delete[] ext;
242ccdfed7dSMike Wiederhold}
243ccdfed7dSMike Wiederhold
244ccdfed7dSMike Wiederholdvoid changeVBFilter(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, std::string name,
2456823c66eSMike Wiederhold                    std::map<uint16_t, uint64_t> &filtermap) {
246ccdfed7dSMike Wiederhold    std::stringstream value;
247ccdfed7dSMike Wiederhold    uint16_t vbs = htons(filtermap.size());
248ccdfed7dSMike Wiederhold    std::map<uint16_t, uint64_t>::iterator it;
249ccdfed7dSMike Wiederhold
250ccdfed7dSMike Wiederhold    value.write((char*) &vbs, sizeof(uint16_t));
2519f94013eSMike Wiederhold    for (it = filtermap.begin(); it != filtermap.end(); ++it) {
252ccdfed7dSMike Wiederhold        uint16_t vb = htons(it->first);
2536823c66eSMike Wiederhold        uint64_t chkid = htonll(it->second);
254ccdfed7dSMike Wiederhold        value.write((char*) &vb, sizeof(uint16_t));
255ccdfed7dSMike Wiederhold        value.write((char*) &chkid, sizeof(uint64_t));
256ccdfed7dSMike Wiederhold    }
257ccdfed7dSMike Wiederhold
258ccdfed7dSMike Wiederhold    protocol_binary_request_header *request;
2590389c521STrond Norbye    request = createPacket(PROTOCOL_BINARY_CMD_CHANGE_VB_FILTER, 0, 0, NULL, 0, name.c_str(),
260ccdfed7dSMike Wiederhold                       name.length(), value.str().data(), value.str().length());
261ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, request, add_response) == ENGINE_SUCCESS,
262ccdfed7dSMike Wiederhold          "Failed to change the TAP VB filter.");
263ccdfed7dSMike Wiederhold    free(request);
264ccdfed7dSMike Wiederhold}
265ccdfed7dSMike Wiederhold
266ccdfed7dSMike Wiederholdvoid createCheckpoint(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
2670389c521STrond Norbye    protocol_binary_request_header *request = createPacket(PROTOCOL_BINARY_CMD_CREATE_CHECKPOINT);
268ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, request, add_response) == ENGINE_SUCCESS,
269ccdfed7dSMike Wiederhold          "Failed to create a new checkpoint.");
270ccdfed7dSMike Wiederhold    free(request);
271ccdfed7dSMike Wiederhold}
272ccdfed7dSMike Wiederhold
2730b8fd7deSMike WiederholdENGINE_ERROR_CODE del(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
2740b8fd7deSMike Wiederhold                      uint64_t cas, uint16_t vbucket, const void* cookie) {
2750b8fd7deSMike Wiederhold    return h1->remove(h, cookie, key, strlen(key), &cas, vbucket);
2760b8fd7deSMike Wiederhold}
2770b8fd7deSMike Wiederhold
278ccdfed7dSMike Wiederholdvoid del_with_meta(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
279ccdfed7dSMike Wiederhold                   const size_t keylen, const uint32_t vb,
280d43a1deeSMike Wiederhold                   ItemMetaData *itemMeta, uint64_t cas_for_delete,
281d43a1deeSMike Wiederhold                   bool skipConflictResolution) {
282d43a1deeSMike Wiederhold    int blen = skipConflictResolution ? 28 : 24;
283dc02f4e6SMike Wiederhold    char *ext = new char[blen];
284ccdfed7dSMike Wiederhold    encodeWithMetaExt(ext, itemMeta);
285d43a1deeSMike Wiederhold
286d43a1deeSMike Wiederhold    if (skipConflictResolution) {
287d43a1deeSMike Wiederhold        uint32_t flag = SKIP_CONFLICT_RESOLUTION_FLAG;
288d43a1deeSMike Wiederhold        flag = htonl(flag);
289d43a1deeSMike Wiederhold        memcpy(ext + 24, (char*)&flag, sizeof(flag));
290d43a1deeSMike Wiederhold    }
291ccdfed7dSMike Wiederhold    protocol_binary_request_header *pkt;
2920389c521STrond Norbye    pkt = createPacket(PROTOCOL_BINARY_CMD_DEL_WITH_META, vb, cas_for_delete, ext, blen, key,
293d43a1deeSMike Wiederhold                       keylen);
294ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, pkt, add_response) == ENGINE_SUCCESS,
295ccdfed7dSMike Wiederhold          "Expected to be able to delete with meta");
296dc02f4e6SMike Wiederhold    delete[] ext;
297ccdfed7dSMike Wiederhold}
298ccdfed7dSMike Wiederhold
299ccdfed7dSMike Wiederholdvoid evict_key(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
300ccdfed7dSMike Wiederhold               uint16_t vbucketId, const char *msg, bool expectError) {
301ccdfed7dSMike Wiederhold    int nonResidentItems = get_int_stat(h, h1, "ep_num_non_resident");
302ccdfed7dSMike Wiederhold    int numEjectedItems = get_int_stat(h, h1, "ep_num_value_ejects");
3030389c521STrond Norbye    protocol_binary_request_header *pkt = createPacket(PROTOCOL_BINARY_CMD_EVICT_KEY, 0, 0,
304ccdfed7dSMike Wiederhold                                                       NULL, 0, key, strlen(key));
305ccdfed7dSMike Wiederhold    pkt->request.vbucket = htons(vbucketId);
306ccdfed7dSMike Wiederhold
307ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, pkt, add_response) == ENGINE_SUCCESS,
308ccdfed7dSMike Wiederhold          "Failed to evict key.");
309ccdfed7dSMike Wiederhold
310ccdfed7dSMike Wiederhold    if (expectError) {
311ccdfed7dSMike Wiederhold        check(last_status == PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS,
312ccdfed7dSMike Wiederhold              "Expected exists when evicting key.");
313ccdfed7dSMike Wiederhold    } else {
314ccdfed7dSMike Wiederhold        if (strcmp(last_body, "Already ejected.") != 0) {
315ccdfed7dSMike Wiederhold            nonResidentItems++;
316ccdfed7dSMike Wiederhold            numEjectedItems++;
317ccdfed7dSMike Wiederhold        }
318ccdfed7dSMike Wiederhold        check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
319ccdfed7dSMike Wiederhold              "Expected success evicting key.");
320ccdfed7dSMike Wiederhold    }
321ccdfed7dSMike Wiederhold
322ccdfed7dSMike Wiederhold    check(get_int_stat(h, h1, "ep_num_non_resident") == nonResidentItems,
323ccdfed7dSMike Wiederhold          "Incorrect number of non-resident items");
324ccdfed7dSMike Wiederhold    check(get_int_stat(h, h1, "ep_num_value_ejects") == numEjectedItems,
325ccdfed7dSMike Wiederhold          "Incorrect number of ejected items");
326ccdfed7dSMike Wiederhold
327ccdfed7dSMike Wiederhold    if (msg != NULL && strcmp(last_body, msg) != 0) {
328ccdfed7dSMike Wiederhold        fprintf(stderr, "Expected evict to return ``%s'', but it returned ``%s''\n",
329ccdfed7dSMike Wiederhold                msg, last_body);
330ccdfed7dSMike Wiederhold        abort();
331ccdfed7dSMike Wiederhold    }
332ccdfed7dSMike Wiederhold}
333ccdfed7dSMike Wiederhold
334ad6475b0SMike Wiederholdsize_t estimateVBucketMove(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1,
335ad6475b0SMike Wiederhold                         uint16_t vbid, const char* tap_name) {
336ad6475b0SMike Wiederhold    std::stringstream ss;
337ad6475b0SMike Wiederhold    ss << "tap-vbtakeover " << vbid;
338ad6475b0SMike Wiederhold    if (tap_name) {
339ad6475b0SMike Wiederhold      ss << " " << tap_name;
340ad6475b0SMike Wiederhold    }
341ad6475b0SMike Wiederhold    return get_int_stat(h, h1, "estimate", ss.str().c_str());
342ad6475b0SMike Wiederhold}
343ad6475b0SMike Wiederhold
344e9ce8770SChiyoung SeoENGINE_ERROR_CODE checkpointPersistence(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1,
34592cd2dedSMike Wiederhold                                        uint64_t checkpoint_id, uint16_t vb) {
346e9ce8770SChiyoung Seo    checkpoint_id = htonll(checkpoint_id);
347e9ce8770SChiyoung Seo    protocol_binary_request_header *request;
3480389c521STrond Norbye    request = createPacket(PROTOCOL_BINARY_CMD_CHECKPOINT_PERSISTENCE, vb, 0, NULL, 0, NULL, 0,
349e9ce8770SChiyoung Seo                           (const char *)&checkpoint_id, sizeof(uint64_t));
350e9ce8770SChiyoung Seo    ENGINE_ERROR_CODE rv = h1->unknown_command(h, NULL, request, add_response);
35179a9d87dSDavid Liao    free(request);
35279a9d87dSDavid Liao    return rv;
35379a9d87dSDavid Liao}
35479a9d87dSDavid Liao
35579a9d87dSDavid LiaoENGINE_ERROR_CODE seqnoPersistence(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1,
35687e974b8SMike Wiederhold                                   uint16_t vbucket, uint64_t seqno) {
35779a9d87dSDavid Liao    seqno = htonll(seqno);
35887e974b8SMike Wiederhold    char buffer[8];
35987e974b8SMike Wiederhold    memcpy(buffer, &seqno, sizeof(uint64_t));
36079a9d87dSDavid Liao    protocol_binary_request_header* request =
3610389c521STrond Norbye        createPacket(PROTOCOL_BINARY_CMD_SEQNO_PERSISTENCE, vbucket, 0, buffer, 8);
36279a9d87dSDavid Liao
36379a9d87dSDavid Liao    ENGINE_ERROR_CODE rv = h1->unknown_command(h, NULL, request, add_response);
364e9ce8770SChiyoung Seo    free(request);
365e9ce8770SChiyoung Seo    return rv;
366e9ce8770SChiyoung Seo}
367e9ce8770SChiyoung Seo
368ccdfed7dSMike Wiederholdvoid gat(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char* key,
369ccdfed7dSMike Wiederhold         uint16_t vb, uint32_t exp, bool quiet) {
370ccdfed7dSMike Wiederhold    char ext[4];
371ccdfed7dSMike Wiederhold    uint8_t opcode = quiet ? PROTOCOL_BINARY_CMD_GATQ : PROTOCOL_BINARY_CMD_GAT;
372ccdfed7dSMike Wiederhold    uint32_t keylen = key ? strlen(key) : 0;
373ccdfed7dSMike Wiederhold    protocol_binary_request_header *request;
374ccdfed7dSMike Wiederhold    encodeExt(ext, exp);
375ccdfed7dSMike Wiederhold    request = createPacket(opcode, vb, 0, ext, 4, key, keylen);
376ccdfed7dSMike Wiederhold
377ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, request, add_response) == ENGINE_SUCCESS,
378ccdfed7dSMike Wiederhold          "Failed to call gat");
379ccdfed7dSMike Wiederhold    free(request);
380ccdfed7dSMike Wiederhold}
381ccdfed7dSMike Wiederhold
382ecc1177cSMike Wiederholdbool get_item_info(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, item_info *info,
383ecc1177cSMike Wiederhold                   const char* key, uint16_t vb) {
384ecc1177cSMike Wiederhold    item *i = NULL;
385ecc1177cSMike Wiederhold    if (h1->get(h, NULL, &i, key, strlen(key), vb) != ENGINE_SUCCESS) {
386ecc1177cSMike Wiederhold        return false;
387ecc1177cSMike Wiederhold    }
388ecc1177cSMike Wiederhold    info->nvalue = 1;
389ecc1177cSMike Wiederhold    if (!h1->get_item_info(h, NULL, i, info)) {
390ecc1177cSMike Wiederhold        h1->release(h, NULL, i);
391ecc1177cSMike Wiederhold        fprintf(stderr, "get_item_info failed\n");
392ecc1177cSMike Wiederhold        return false;
393ecc1177cSMike Wiederhold    }
394ecc1177cSMike Wiederhold
395ecc1177cSMike Wiederhold    h1->release(h, NULL, i);
396ecc1177cSMike Wiederhold    return true;
397ecc1177cSMike Wiederhold}
398ecc1177cSMike Wiederhold
399ccdfed7dSMike Wiederholdbool get_key(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, item *i,
400ccdfed7dSMike Wiederhold             std::string &key) {
401ccdfed7dSMike Wiederhold
402ccdfed7dSMike Wiederhold    item_info info;
403ccdfed7dSMike Wiederhold    info.nvalue = 1;
404ccdfed7dSMike Wiederhold    if (!h1->get_item_info(h, NULL, i, &info)) {
405ccdfed7dSMike Wiederhold        fprintf(stderr, "get_item_info failed\n");
406ccdfed7dSMike Wiederhold        return false;
407ccdfed7dSMike Wiederhold    }
408ccdfed7dSMike Wiederhold
409ccdfed7dSMike Wiederhold    key.assign((const char*)info.key, info.nkey);
410ccdfed7dSMike Wiederhold    return true;
411ccdfed7dSMike Wiederhold}
412ccdfed7dSMike Wiederhold
413ccdfed7dSMike Wiederholdvoid getl(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char* key,
414ccdfed7dSMike Wiederhold          uint16_t vb, uint32_t lock_timeout) {
415ccdfed7dSMike Wiederhold    char ext[4];
416ccdfed7dSMike Wiederhold    uint32_t keylen = key ? strlen(key) : 0;
417ccdfed7dSMike Wiederhold    protocol_binary_request_header *request;
418ccdfed7dSMike Wiederhold    encodeExt(ext, lock_timeout);
4190389c521STrond Norbye    request = createPacket(PROTOCOL_BINARY_CMD_GET_LOCKED, vb, 0, ext, 4, key, keylen);
420ccdfed7dSMike Wiederhold
421ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, request, add_response) == ENGINE_SUCCESS,
422ccdfed7dSMike Wiederhold          "Failed to call getl");
423ccdfed7dSMike Wiederhold    free(request);
424ccdfed7dSMike Wiederhold}
425ccdfed7dSMike Wiederhold
426b4a94111SMike Wiederholdbool get_meta(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char* key) {
4270389c521STrond Norbye    protocol_binary_request_header *req = createPacket(PROTOCOL_BINARY_CMD_GET_META, 0, 0, NULL,
428ccdfed7dSMike Wiederhold                                                       0, key, strlen(key));
429ccdfed7dSMike Wiederhold
430ccdfed7dSMike Wiederhold    ENGINE_ERROR_CODE ret = h1->unknown_command(h, NULL, req,
431ccdfed7dSMike Wiederhold                                                add_response_get_meta);
432ccdfed7dSMike Wiederhold    check(ret == ENGINE_SUCCESS, "Expected get_meta call to be successful");
433ccdfed7dSMike Wiederhold    if (last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
434b4a94111SMike Wiederhold        return true;
435ccdfed7dSMike Wiederhold    }
436b4a94111SMike Wiederhold    return false;
437ccdfed7dSMike Wiederhold}
438ccdfed7dSMike Wiederhold
439ccdfed7dSMike Wiederholdvoid observe(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1,
440ccdfed7dSMike Wiederhold             std::map<std::string, uint16_t> obskeys) {
441ccdfed7dSMike Wiederhold    std::stringstream value;
442ccdfed7dSMike Wiederhold    std::map<std::string, uint16_t>::iterator it;
4439f94013eSMike Wiederhold    for (it = obskeys.begin(); it != obskeys.end(); ++it) {
444ccdfed7dSMike Wiederhold        uint16_t vb = htons(it->second);
445ccdfed7dSMike Wiederhold        uint16_t keylen = htons(it->first.length());
446ccdfed7dSMike Wiederhold        value.write((char*) &vb, sizeof(uint16_t));
447ccdfed7dSMike Wiederhold        value.write((char*) &keylen, sizeof(uint16_t));
448ccdfed7dSMike Wiederhold        value.write(it->first.c_str(), it->first.length());
449ccdfed7dSMike Wiederhold    }
450ccdfed7dSMike Wiederhold
451ccdfed7dSMike Wiederhold    protocol_binary_request_header *request;
4520389c521STrond Norbye    request = createPacket(PROTOCOL_BINARY_CMD_OBSERVE, 0, 0, NULL, 0, NULL, 0,
453ccdfed7dSMike Wiederhold                           value.str().data(), value.str().length());
454ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, request, add_response) == ENGINE_SUCCESS,
455ccdfed7dSMike Wiederhold          "Observe call failed");
456ccdfed7dSMike Wiederhold    free(request);
457ccdfed7dSMike Wiederhold}
458ccdfed7dSMike Wiederhold
4598f0f3d4fSMike Wiederholdvoid get_replica(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char* key,
4608f0f3d4fSMike Wiederhold                 uint16_t vbid) {
4618f0f3d4fSMike Wiederhold    protocol_binary_request_header *pkt;
4620389c521STrond Norbye    pkt = createPacket(PROTOCOL_BINARY_CMD_GET_REPLICA, vbid, 0, NULL, 0, key, strlen(key));
4638f0f3d4fSMike Wiederhold    check(h1->unknown_command(h, NULL, pkt, add_response) == ENGINE_SUCCESS,
4648f0f3d4fSMike Wiederhold                              "Get Replica Failed");
4658f0f3d4fSMike Wiederhold    free(pkt);
4668f0f3d4fSMike Wiederhold}
4678f0f3d4fSMike Wiederhold
468ccdfed7dSMike Wiederholdprotocol_binary_request_header* prepare_get_replica(ENGINE_HANDLE *h,
469ccdfed7dSMike Wiederhold                                                    ENGINE_HANDLE_V1 *h1,
470ccdfed7dSMike Wiederhold                                                    vbucket_state_t state,
471ccdfed7dSMike Wiederhold                                                    bool makeinvalidkey) {
472ccdfed7dSMike Wiederhold    uint16_t id = 0;
473ccdfed7dSMike Wiederhold    const char *key = "k0";
474ccdfed7dSMike Wiederhold    protocol_binary_request_header *pkt;
4750389c521STrond Norbye    pkt = createPacket(PROTOCOL_BINARY_CMD_GET_REPLICA, id, 0, NULL, 0, key, strlen(key));
476ccdfed7dSMike Wiederhold
477ccdfed7dSMike Wiederhold    if (!makeinvalidkey) {
478ccdfed7dSMike Wiederhold        item *i = NULL;
479ccdfed7dSMike Wiederhold        check(store(h, h1, NULL, OPERATION_SET, key, "replicadata", &i, 0, id)
480ccdfed7dSMike Wiederhold              == ENGINE_SUCCESS, "Get Replica Failed");
481ccdfed7dSMike Wiederhold        h1->release(h, NULL, i);
482ccdfed7dSMike Wiederhold
483ccdfed7dSMike Wiederhold        check(set_vbucket_state(h, h1, id, state),
484ccdfed7dSMike Wiederhold              "Failed to set vbucket active state, Get Replica Failed");
485ccdfed7dSMike Wiederhold    }
486ccdfed7dSMike Wiederhold
487ccdfed7dSMike Wiederhold    return pkt;
488ccdfed7dSMike Wiederhold}
489ccdfed7dSMike Wiederhold
4900389c521STrond Norbyebool set_param(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, protocol_binary_engine_param_t paramtype,
491ccdfed7dSMike Wiederhold               const char *param, const char *val) {
492ccdfed7dSMike Wiederhold    char ext[4];
493ccdfed7dSMike Wiederhold    protocol_binary_request_header *pkt;
494ccdfed7dSMike Wiederhold    encodeExt(ext, static_cast<uint32_t>(paramtype));
4950389c521STrond Norbye    pkt = createPacket(PROTOCOL_BINARY_CMD_SET_PARAM, 0, 0, ext, sizeof(protocol_binary_engine_param_t), param,
496ccdfed7dSMike Wiederhold                       strlen(param), val, strlen(val));
497ccdfed7dSMike Wiederhold
498ccdfed7dSMike Wiederhold    if (h1->unknown_command(h, NULL, pkt, add_response) != ENGINE_SUCCESS) {
499ccdfed7dSMike Wiederhold        return false;
500ccdfed7dSMike Wiederhold    }
501ccdfed7dSMike Wiederhold
502ccdfed7dSMike Wiederhold    return last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS;
503ccdfed7dSMike Wiederhold}
504ccdfed7dSMike Wiederhold
505ccdfed7dSMike Wiederholdbool set_vbucket_state(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1,
506ccdfed7dSMike Wiederhold                       uint16_t vb, vbucket_state_t state) {
507ccdfed7dSMike Wiederhold
508ccdfed7dSMike Wiederhold    char ext[4];
509ccdfed7dSMike Wiederhold    protocol_binary_request_header *pkt;
510ccdfed7dSMike Wiederhold    encodeExt(ext, static_cast<uint32_t>(state));
511ccdfed7dSMike Wiederhold    pkt = createPacket(PROTOCOL_BINARY_CMD_SET_VBUCKET, vb, 0, ext, 4);
512ccdfed7dSMike Wiederhold
513ccdfed7dSMike Wiederhold    if (h1->unknown_command(h, NULL, pkt, add_response) != ENGINE_SUCCESS) {
514ccdfed7dSMike Wiederhold        return false;
515ccdfed7dSMike Wiederhold    }
516ccdfed7dSMike Wiederhold
5173c0f0d0bSMike Wiederhold    free(pkt);
518ccdfed7dSMike Wiederhold    return last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS;
519ccdfed7dSMike Wiederhold}
520ccdfed7dSMike Wiederhold
521ccdfed7dSMike Wiederholdvoid set_with_meta(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
522ccdfed7dSMike Wiederhold                   const size_t keylen, const char *val, const size_t vallen,
523ccdfed7dSMike Wiederhold                   const uint32_t vb, ItemMetaData *itemMeta,
5245e1d9fb4Sabhinavdangeti                   uint64_t cas_for_set, bool skipConflictResolution,
5255e1d9fb4Sabhinavdangeti                   uint8_t datatype) {
526d43a1deeSMike Wiederhold    int blen = skipConflictResolution ? 28 : 24;
527dc02f4e6SMike Wiederhold    char *ext = new char[blen];
528ccdfed7dSMike Wiederhold    encodeWithMetaExt(ext, itemMeta);
529d43a1deeSMike Wiederhold
530d43a1deeSMike Wiederhold    if (skipConflictResolution) {
531d43a1deeSMike Wiederhold        uint32_t flag = SKIP_CONFLICT_RESOLUTION_FLAG;
532d43a1deeSMike Wiederhold        flag = htonl(flag);
533d43a1deeSMike Wiederhold        memcpy(ext + 24, (char*)&flag, sizeof(flag));
534d43a1deeSMike Wiederhold    }
535d43a1deeSMike Wiederhold
536ccdfed7dSMike Wiederhold    protocol_binary_request_header *pkt;
5370389c521STrond Norbye    pkt = createPacket(PROTOCOL_BINARY_CMD_SET_WITH_META, vb, cas_for_set, ext, blen, key, keylen,
5385e1d9fb4Sabhinavdangeti                       val, vallen, datatype);
539ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, pkt, add_response) == ENGINE_SUCCESS,
540ccdfed7dSMike Wiederhold          "Expected to be able to store with meta");
541dc02f4e6SMike Wiederhold    delete[] ext;
542ccdfed7dSMike Wiederhold}
543ccdfed7dSMike Wiederhold
544b4fc25d3SMike Wiederholdvoid return_meta(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
545b4fc25d3SMike Wiederhold                 const size_t keylen, const char *val, const size_t vallen,
546b4fc25d3SMike Wiederhold                 const uint32_t vb, const uint64_t cas, const uint32_t flags,
547029716c5Sabhinavdangeti                 const uint32_t exp, const uint32_t type, uint8_t datatype) {
548b4fc25d3SMike Wiederhold    char ext[12];
549b4fc25d3SMike Wiederhold    encodeExt(ext, type);
550b4fc25d3SMike Wiederhold    encodeExt(ext + 4, flags);
551b4fc25d3SMike Wiederhold    encodeExt(ext + 8, exp);
552b4fc25d3SMike Wiederhold    protocol_binary_request_header *pkt;
5530389c521STrond Norbye    pkt = createPacket(PROTOCOL_BINARY_CMD_RETURN_META, vb, cas, ext, 12, key, keylen, val,
554029716c5Sabhinavdangeti                       vallen, datatype);
555b4fc25d3SMike Wiederhold    check(h1->unknown_command(h, NULL, pkt, add_response_ret_meta)
556b4fc25d3SMike Wiederhold              == ENGINE_SUCCESS, "Expected to be able to store ret meta");
557b4fc25d3SMike Wiederhold    free(pkt);
558b4fc25d3SMike Wiederhold}
559b4fc25d3SMike Wiederhold
560b4fc25d3SMike Wiederholdvoid set_ret_meta(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
561b4fc25d3SMike Wiederhold                  const size_t keylen, const char *val, const size_t vallen,
562b4fc25d3SMike Wiederhold                  const uint32_t vb, const uint64_t cas, const uint32_t flags,
563029716c5Sabhinavdangeti                  const uint32_t exp, uint8_t datatype) {
564b4fc25d3SMike Wiederhold    return_meta(h, h1, key, keylen, val, vallen, vb, cas, flags, exp,
565029716c5Sabhinavdangeti                SET_RET_META, datatype);
566b4fc25d3SMike Wiederhold}
567b4fc25d3SMike Wiederhold
568b4fc25d3SMike Wiederholdvoid add_ret_meta(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
569b4fc25d3SMike Wiederhold                  const size_t keylen, const char *val, const size_t vallen,
570b4fc25d3SMike Wiederhold                  const uint32_t vb, const uint64_t cas, const uint32_t flags,
571029716c5Sabhinavdangeti                  const uint32_t exp, uint8_t datatype) {
572b4fc25d3SMike Wiederhold    return_meta(h, h1, key, keylen, val, vallen, vb, cas, flags, exp,
573029716c5Sabhinavdangeti                ADD_RET_META, datatype);
574b4fc25d3SMike Wiederhold}
575b4fc25d3SMike Wiederhold
576b4fc25d3SMike Wiederholdvoid del_ret_meta(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1, const char *key,
577b4fc25d3SMike Wiederhold                  const size_t keylen, const uint32_t vb, const uint64_t cas) {
578b4fc25d3SMike Wiederhold    return_meta(h, h1, key, keylen, NULL, 0, vb, cas, 0, 0,
579b4fc25d3SMike Wiederhold                DEL_RET_META);
580b4fc25d3SMike Wiederhold}
581b4fc25d3SMike Wiederhold
582b4fc25d3SMike Wiederholdvoid disable_traffic(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
5830389c521STrond Norbye    protocol_binary_request_header *pkt = createPacket(PROTOCOL_BINARY_CMD_DISABLE_TRAFFIC);
584b4fc25d3SMike Wiederhold    check(h1->unknown_command(h, NULL, pkt, add_response) == ENGINE_SUCCESS,
585b4fc25d3SMike Wiederhold          "Failed to send data traffic command to the server");
586b4fc25d3SMike Wiederhold    check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
587b4fc25d3SMike Wiederhold          "Failed to disable data traffic");
588b4fc25d3SMike Wiederhold    free(pkt);
589b4fc25d3SMike Wiederhold}
590b4fc25d3SMike Wiederhold
591b4fc25d3SMike Wiederholdvoid enable_traffic(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
5920389c521STrond Norbye    protocol_binary_request_header *pkt = createPacket(PROTOCOL_BINARY_CMD_ENABLE_TRAFFIC);
593b4fc25d3SMike Wiederhold    check(h1->unknown_command(h, NULL, pkt, add_response) == ENGINE_SUCCESS,
594b4fc25d3SMike Wiederhold          "Failed to send data traffic command to the server");
595b4fc25d3SMike Wiederhold    check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
596b4fc25d3SMike Wiederhold          "Failed to enable data traffic");
597b4fc25d3SMike Wiederhold    free(pkt);
598b4fc25d3SMike Wiederhold}
599b4fc25d3SMike Wiederhold
600ccdfed7dSMike Wiederholdvoid start_persistence(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
6010389c521STrond Norbye    protocol_binary_request_header *pkt = createPacket(PROTOCOL_BINARY_CMD_START_PERSISTENCE);
602ccdfed7dSMike Wiederhold    check(h1->unknown_command(h, NULL, pkt, add_response) == ENGINE_SUCCESS,
603ccdfed7dSMike Wiederhold          "Failed to stop persistence.");
604ccdfed7dSMike Wiederhold    check(last_status == PROTOCOL_BINARY_RESPONSE_SUCCESS,
605ccdfed7dSMike Wiederhold          "Error starting persistence.");
60624e9a1dfSMike Wiederhold    free(pkt);
607ccdfed7dSMike Wiederhold}
608ccdfed7dSMike Wiederhold
609ccdfed7dSMike Wiederholdvoid stop_persistence(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1) {
61046df358fSSundar Sridharan    useconds_t sleepTime = 128;
611ccdfed7dSMike Wiederhold    while (true) {
612ccdfed7dSMike Wiederhold        if (get_str_stat(h, h1, "ep_flusher_state", 0) == "running") {
613