libcouchbase 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +11 -8
- data/ext/libcouchbase/CMakeLists.txt +1 -1
- data/ext/libcouchbase/README.markdown +38 -6
- data/ext/libcouchbase/RELEASE_NOTES.markdown +151 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/source_files.cmake +1 -0
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +686 -288
- data/ext/libcouchbase/contrib/cJSON/cJSON.h +0 -0
- data/ext/libcouchbase/contrib/cbsasl/src/hash.c +17 -17
- data/ext/libcouchbase/contrib/cliopts/cliopts.c +76 -0
- data/ext/libcouchbase/contrib/cliopts/cliopts.h +66 -15
- data/ext/libcouchbase/contrib/genhash/genhash.c +1 -2
- data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +4 -3
- data/ext/libcouchbase/example/instancepool/main.cc +12 -2
- data/ext/libcouchbase/example/libeventdirect/main.c +99 -25
- data/ext/libcouchbase/example/minimal/minimal.c +7 -5
- data/ext/libcouchbase/example/observe/durability.c +102 -0
- data/ext/libcouchbase/example/observe/observe.c +19 -6
- data/ext/libcouchbase/example/subdoc/subdoc-xattrs.c +1 -2
- data/ext/libcouchbase/include/libcouchbase/cntl-private.h +6 -8
- data/ext/libcouchbase/include/libcouchbase/cntl.h +84 -64
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +295 -78
- data/ext/libcouchbase/include/libcouchbase/deprecated.h +2 -2
- data/ext/libcouchbase/include/libcouchbase/error.h +1 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +9 -9
- data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +2 -2
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +69 -7
- data/ext/libcouchbase/include/libcouchbase/vbucket.h +17 -0
- data/ext/libcouchbase/include/libcouchbase/views.h +3 -3
- data/ext/libcouchbase/include/memcached/protocol_binary.h +62 -1
- data/ext/libcouchbase/packaging/deb/control +1 -1
- data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +37 -36
- data/ext/libcouchbase/src/bootstrap.cc +22 -8
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +1 -1
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -1
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +13 -8
- data/ext/libcouchbase/src/callbacks.c +2 -0
- data/ext/libcouchbase/src/cntl.cc +28 -17
- data/ext/libcouchbase/src/dns-srv.cc +1 -2
- data/ext/libcouchbase/src/dump.cc +4 -0
- data/ext/libcouchbase/src/errmap.h +89 -16
- data/ext/libcouchbase/src/handler.cc +28 -11
- data/ext/libcouchbase/src/http/http-priv.h +4 -1
- data/ext/libcouchbase/src/http/http.cc +3 -0
- data/ext/libcouchbase/src/instance.cc +1 -1
- data/ext/libcouchbase/src/internal.h +1 -0
- data/ext/libcouchbase/src/lcbio/connect.cc +2 -3
- data/ext/libcouchbase/src/lcbio/manager.cc +2 -2
- data/ext/libcouchbase/src/lcbio/ssl.h +10 -0
- data/ext/libcouchbase/src/mc/mcreq.c +8 -0
- data/ext/libcouchbase/src/mcserver/mcserver.cc +14 -1
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +0 -3
- data/ext/libcouchbase/src/n1ql/n1ql.cc +22 -29
- data/ext/libcouchbase/src/n1ql/params.cc +46 -1
- data/ext/libcouchbase/src/newconfig.cc +4 -4
- data/ext/libcouchbase/src/operations/durability-seqno.cc +4 -0
- data/ext/libcouchbase/src/operations/durability.cc +3 -0
- data/ext/libcouchbase/src/operations/ping.cc +315 -0
- data/ext/libcouchbase/src/operations/stats.cc +10 -0
- data/ext/libcouchbase/src/operations/subdoc.cc +13 -1
- data/ext/libcouchbase/src/retrychk.cc +1 -0
- data/ext/libcouchbase/src/settings.c +2 -0
- data/ext/libcouchbase/src/settings.h +13 -7
- data/ext/libcouchbase/src/ssl/ssl_c.c +28 -2
- data/ext/libcouchbase/src/ssl/ssl_common.c +3 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +15 -1
- data/ext/libcouchbase/src/ssl/ssl_iot_common.h +3 -1
- data/ext/libcouchbase/src/timings.c +0 -1
- data/ext/libcouchbase/src/vbucket/vbucket.c +49 -1
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +58 -40
- data/ext/libcouchbase/tests/iotests/mock-environment.h +23 -4
- data/ext/libcouchbase/tests/iotests/mock-unit-test.h +8 -8
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +5 -5
- data/ext/libcouchbase/tests/iotests/t_durability.cc +50 -0
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +4 -2
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +6 -3
- data/ext/libcouchbase/tests/iotests/t_lock.cc +5 -6
- data/ext/libcouchbase/tests/iotests/t_misc.cc +44 -0
- data/ext/libcouchbase/tests/iotests/t_serverops.cc +1 -0
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +28 -0
- data/ext/libcouchbase/tests/iotests/t_views.cc +22 -10
- data/ext/libcouchbase/tools/CMakeLists.txt +21 -1
- data/ext/libcouchbase/tools/cbc-handlers.h +23 -3
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +1 -1
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +126 -26
- data/ext/libcouchbase/tools/cbc-proxy.cc +403 -0
- data/ext/libcouchbase/tools/cbc-subdoc.cc +826 -0
- data/ext/libcouchbase/tools/cbc.cc +149 -37
- data/ext/libcouchbase/tools/common/options.h +5 -2
- data/ext/libcouchbase/tools/linenoise/linenoise.c +15 -15
- data/lib/libcouchbase.rb +4 -0
- data/lib/libcouchbase/bucket.rb +51 -0
- data/lib/libcouchbase/connection.rb +100 -13
- data/lib/libcouchbase/ext/libcouchbase.rb +40 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdsubdoc.rb +13 -1
- data/lib/libcouchbase/ext/libcouchbase/enums.rb +2 -1
- data/lib/libcouchbase/ext/libcouchbase/sdspec.rb +5 -0
- data/lib/libcouchbase/subdoc_request.rb +129 -0
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/bucket_spec.rb +15 -1
- data/spec/connection_spec.rb +1 -1
- data/spec/subdoc_spec.rb +192 -0
- metadata +13 -4
- data/ext/libcouchbase/.travis.yml +0 -19
|
@@ -184,6 +184,7 @@ handle_bcast(mc_PIPELINE *pipeline, mc_PACKET *req, lcb_error_t err,
|
|
|
184
184
|
lcb_RESPVERBOSITY *verbosity;
|
|
185
185
|
lcb_RESPMCVERSION *version;
|
|
186
186
|
lcb_RESPFLUSH *flush;
|
|
187
|
+
lcb_RESPNOOP *noop;
|
|
187
188
|
} u_resp;
|
|
188
189
|
|
|
189
190
|
union {
|
|
@@ -191,6 +192,7 @@ handle_bcast(mc_PIPELINE *pipeline, mc_PACKET *req, lcb_error_t err,
|
|
|
191
192
|
lcb_RESPVERBOSITY verbosity;
|
|
192
193
|
lcb_RESPMCVERSION version;
|
|
193
194
|
lcb_RESPFLUSH flush;
|
|
195
|
+
lcb_RESPNOOP noop;
|
|
194
196
|
} u_empty;
|
|
195
197
|
|
|
196
198
|
memset(&u_empty, 0, sizeof(u_empty));
|
|
@@ -258,6 +260,8 @@ pkt_bcast_simple(lcb_t instance, const void *cookie, lcb_CALLBACKTYPE type)
|
|
|
258
260
|
hdr.request.opcode = PROTOCOL_BINARY_CMD_FLUSH;
|
|
259
261
|
} else if (type == LCB_CALLBACK_VERSIONS) {
|
|
260
262
|
hdr.request.opcode = PROTOCOL_BINARY_CMD_VERSION;
|
|
263
|
+
} else if (type == LCB_CALLBACK_NOOP) {
|
|
264
|
+
hdr.request.opcode = PROTOCOL_BINARY_CMD_NOOP;
|
|
261
265
|
} else {
|
|
262
266
|
fprintf(stderr, "pkt_bcast_simple passed unknown type %u\n", type);
|
|
263
267
|
assert(0);
|
|
@@ -284,6 +288,12 @@ lcb_server_versions3(lcb_t instance, const void *cookie, const lcb_CMDBASE *)
|
|
|
284
288
|
return pkt_bcast_simple(instance, cookie, LCB_CALLBACK_VERSIONS);
|
|
285
289
|
}
|
|
286
290
|
|
|
291
|
+
LIBCOUCHBASE_API
|
|
292
|
+
lcb_error_t
|
|
293
|
+
lcb_noop3(lcb_t instance, const void *cookie, const lcb_CMDNOOP *)
|
|
294
|
+
{
|
|
295
|
+
return pkt_bcast_simple(instance, cookie, LCB_CALLBACK_NOOP);
|
|
296
|
+
}
|
|
287
297
|
|
|
288
298
|
LIBCOUCHBASE_API
|
|
289
299
|
lcb_error_t
|
|
@@ -234,8 +234,20 @@ make_doc_flags(const uint32_t user) {
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
struct MultiBuilder {
|
|
237
|
+
static unsigned infer_mode(const lcb_CMDSUBDOC *cmd) {
|
|
238
|
+
if (cmd->nspecs == 0) {
|
|
239
|
+
return 0;
|
|
240
|
+
}
|
|
241
|
+
const SubdocCmdTraits::Traits& trait = SubdocCmdTraits::find(cmd->specs[0].sdcmd);
|
|
242
|
+
if (!trait.valid()) {
|
|
243
|
+
return 0;
|
|
244
|
+
}
|
|
245
|
+
return trait.mode();
|
|
246
|
+
}
|
|
247
|
+
|
|
237
248
|
MultiBuilder(const lcb_CMDSUBDOC *cmd_)
|
|
238
|
-
: cmd(cmd_), payload_size(0)
|
|
249
|
+
: cmd(cmd_), payload_size(0) {
|
|
250
|
+
mode = infer_mode(cmd_);
|
|
239
251
|
size_t ebufsz = is_lookup() ? cmd->nspecs * 4 : cmd->nspecs * 8;
|
|
240
252
|
extra_body = new char[ebufsz];
|
|
241
253
|
bodysz = 0;
|
|
@@ -60,6 +60,8 @@ void lcb_default_settings(lcb_settings *settings)
|
|
|
60
60
|
settings->select_bucket = LCB_DEFAULT_SELECT_BUCKET;
|
|
61
61
|
settings->tcp_keepalive = LCB_DEFAULT_TCP_KEEPALIVE;
|
|
62
62
|
settings->send_hello = 1;
|
|
63
|
+
settings->config_poll_interval = LCB_DEFAULT_CONFIG_POLL_INTERVAL;
|
|
64
|
+
settings->use_errmap = 1;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
LCB_INTERNAL_API
|
|
@@ -23,21 +23,23 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
/** Convert seconds to millis */
|
|
26
|
-
#define LCB_S2MS(s) ((lcb_uint32_t)s) * 1000
|
|
26
|
+
#define LCB_S2MS(s) (((lcb_uint32_t)s) * 1000)
|
|
27
27
|
|
|
28
28
|
/** Convert seconds to microseconds */
|
|
29
|
-
#define LCB_S2US(s) ((lcb_uint32_t)s) * 1000000
|
|
29
|
+
#define LCB_S2US(s) (((lcb_uint32_t)s) * 1000000)
|
|
30
30
|
|
|
31
31
|
/** Convert seconds to nanoseconds */
|
|
32
|
-
#define LCB_S2NS(s) ((hrtime_t)s) * 1000000000
|
|
32
|
+
#define LCB_S2NS(s) (((hrtime_t)s) * 1000000000)
|
|
33
33
|
|
|
34
34
|
/** Convert nanoseconds to microseconds */
|
|
35
35
|
#define LCB_NS2US(s) (lcb_uint32_t) ((s) / 1000)
|
|
36
36
|
|
|
37
|
-
#define LCB_MS2US(s) (s) * 1000
|
|
37
|
+
#define LCB_MS2US(s) ((s) * 1000)
|
|
38
38
|
|
|
39
39
|
/** Convert microseconds to nanoseconds */
|
|
40
|
-
#define LCB_US2NS(s) ((hrtime_t)s) * 1000
|
|
40
|
+
#define LCB_US2NS(s) (((hrtime_t)s) * 1000)
|
|
41
|
+
/** Convert milliseconds to nanoseconds */
|
|
42
|
+
#define LCB_MS2NS(s) (((hrtime_t)s) * 1000000)
|
|
41
43
|
|
|
42
44
|
|
|
43
45
|
#define LCB_DEFAULT_TIMEOUT LCB_MS2US(2500)
|
|
@@ -56,8 +58,8 @@
|
|
|
56
58
|
#define LCB_DEFAULT_CONFIG_MAXIMUM_REDIRECTS 3
|
|
57
59
|
#define LCB_DEFAULT_CONFIG_ERRORS_THRESHOLD 100
|
|
58
60
|
|
|
59
|
-
/* 10
|
|
60
|
-
#define LCB_DEFAULT_CONFIG_ERRORS_DELAY LCB_MS2US(
|
|
61
|
+
/* 10 milliseconds */
|
|
62
|
+
#define LCB_DEFAULT_CONFIG_ERRORS_DELAY LCB_MS2US(10)
|
|
61
63
|
|
|
62
64
|
/* 1 second */
|
|
63
65
|
#define LCB_DEFAULT_CLCONFIG_GRACE_CYCLE LCB_MS2US(1000)
|
|
@@ -86,6 +88,10 @@
|
|
|
86
88
|
#define LCB_DEFAULT_TCP_NODELAY 1
|
|
87
89
|
#define LCB_DEFAULT_SELECT_BUCKET 1
|
|
88
90
|
#define LCB_DEFAULT_TCP_KEEPALIVE 1
|
|
91
|
+
/* 2.5 s */
|
|
92
|
+
#define LCB_DEFAULT_CONFIG_POLL_INTERVAL LCB_MS2US(2500)
|
|
93
|
+
/* 50 ms */
|
|
94
|
+
#define LCB_CONFIG_POLL_INTERVAL_FLOOR LCB_MS2US(50)
|
|
89
95
|
|
|
90
96
|
#include "config.h"
|
|
91
97
|
#include <libcouchbase/couchbase.h>
|
|
@@ -189,16 +189,26 @@ appdata_read(lcbio_CSSL *cs)
|
|
|
189
189
|
static void
|
|
190
190
|
read_callback(lcb_sockdata_t *sd, lcb_ssize_t nr, void *arg)
|
|
191
191
|
{
|
|
192
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
|
192
193
|
lcbio_CSSL *cs = arg;
|
|
194
|
+
#else
|
|
195
|
+
my_WBUF *rb = arg;
|
|
196
|
+
lcbio_CSSL *cs = rb->parent;
|
|
197
|
+
#endif
|
|
198
|
+
|
|
193
199
|
cs->rdactive = 0;
|
|
194
200
|
cs->entered++;
|
|
195
201
|
|
|
196
202
|
if (nr > 0) {
|
|
203
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
|
197
204
|
BUF_MEM *mb;
|
|
198
205
|
|
|
199
206
|
BIO_clear_retry_flags(cs->rbio);
|
|
200
207
|
BIO_get_mem_ptr(cs->rbio, &mb);
|
|
201
208
|
mb->length += nr;
|
|
209
|
+
#else
|
|
210
|
+
BIO_write(cs->rbio, rb->buf, nr);
|
|
211
|
+
#endif
|
|
202
212
|
|
|
203
213
|
} else if (nr == 0) {
|
|
204
214
|
cs->closed = 1;
|
|
@@ -208,6 +218,9 @@ read_callback(lcb_sockdata_t *sd, lcb_ssize_t nr, void *arg)
|
|
|
208
218
|
cs->error = 1;
|
|
209
219
|
IOTSSL_ERRNO(cs) = IOT_ERRNO(cs->orig);
|
|
210
220
|
}
|
|
221
|
+
#if !LCB_CAN_OPTIMIZE_SSL_BIO
|
|
222
|
+
free(rb);
|
|
223
|
+
#endif
|
|
211
224
|
|
|
212
225
|
appdata_encode(cs);
|
|
213
226
|
appdata_read(cs);
|
|
@@ -271,17 +284,30 @@ schedule_wants(lcbio_CSSL *cs)
|
|
|
271
284
|
|
|
272
285
|
} else if (SSL_want_read(cs->ssl) || (cs->urd_cb && has_appdata == 0)) {
|
|
273
286
|
/* request more data from the socket */
|
|
274
|
-
BUF_MEM *mb;
|
|
275
287
|
lcb_IOV iov;
|
|
288
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
|
289
|
+
BUF_MEM *mb;
|
|
290
|
+
#else
|
|
291
|
+
#define BUFSZ 4096
|
|
292
|
+
my_WBUF *rb = malloc(sizeof(*rb) + BUFSZ);
|
|
293
|
+
rb->parent = cs;
|
|
294
|
+
#endif
|
|
276
295
|
|
|
277
296
|
cs->rdactive = 1;
|
|
297
|
+
lcbio_table_ref(&cs->base_);
|
|
298
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
|
278
299
|
BIO_get_mem_ptr(cs->rbio, &mb);
|
|
279
300
|
iotssl_bm_reserve(mb);
|
|
280
301
|
iov.iov_base = mb->data + mb->length;
|
|
281
302
|
iov.iov_len = mb->max - mb->length;
|
|
282
|
-
lcbio_table_ref(&cs->base_);
|
|
283
303
|
IOT_V1(cs->orig).read2(
|
|
284
304
|
IOT_ARG(cs->orig), cs->sd, &iov, 1, cs, read_callback);
|
|
305
|
+
#else
|
|
306
|
+
iov.iov_base = rb->buf;
|
|
307
|
+
iov.iov_len = BUFSZ;
|
|
308
|
+
IOT_V1(cs->orig).read2(
|
|
309
|
+
IOT_ARG(cs->orig), cs->sd, &iov, 1, rb, read_callback);
|
|
310
|
+
#endif
|
|
285
311
|
}
|
|
286
312
|
|
|
287
313
|
}
|
|
@@ -127,6 +127,7 @@ iotssl_destroy_common(lcbio_XSSL *xs)
|
|
|
127
127
|
lcbio_table_unref(xs->orig);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
|
130
131
|
void
|
|
131
132
|
iotssl_bm_reserve(BUF_MEM *bm)
|
|
132
133
|
{
|
|
@@ -139,6 +140,7 @@ iotssl_bm_reserve(BUF_MEM *bm)
|
|
|
139
140
|
}
|
|
140
141
|
bm->length = oldlen;
|
|
141
142
|
}
|
|
143
|
+
#endif
|
|
142
144
|
|
|
143
145
|
void
|
|
144
146
|
iotssl_log_errors(lcbio_XSSL *xs)
|
|
@@ -428,6 +430,7 @@ ossl_init_locks(void)
|
|
|
428
430
|
for (ii = 0; ii < nlocks; ii++) {
|
|
429
431
|
ossl_lock_init(ossl_locks + ii);
|
|
430
432
|
}
|
|
433
|
+
/* TODO: locking API has been removed in OpenSSL 1.1 */
|
|
431
434
|
CRYPTO_set_locking_callback(ossl_lockfn);
|
|
432
435
|
}
|
|
433
436
|
|
|
@@ -112,24 +112,38 @@ schedule_pending(lcbio_ESSL *es)
|
|
|
112
112
|
static int
|
|
113
113
|
read_ssl_data(lcbio_ESSL *es)
|
|
114
114
|
{
|
|
115
|
-
BUF_MEM *rmb;
|
|
116
115
|
int nr;
|
|
117
116
|
lcbio_pTABLE iot = es->orig;
|
|
118
117
|
|
|
118
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
|
119
|
+
BUF_MEM *rmb;
|
|
120
|
+
|
|
119
121
|
/* This block is an optimization over BIO_write to avoid copying the memory
|
|
120
122
|
* to a temporary buffer and _then_ copying it into the BIO */
|
|
121
123
|
|
|
122
124
|
BIO_get_mem_ptr(es->rbio, &rmb);
|
|
125
|
+
#endif
|
|
126
|
+
|
|
123
127
|
while (1) {
|
|
128
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
|
124
129
|
/* I don't know why this is here, but it's found inside BIO_write */
|
|
125
130
|
BIO_clear_retry_flags(es->rbio);
|
|
126
131
|
iotssl_bm_reserve(rmb);
|
|
127
132
|
nr = IOT_V0IO(iot).recv(IOT_ARG(iot), es->fd,
|
|
128
133
|
rmb->data + rmb->length, rmb->max - rmb->length, 0);
|
|
134
|
+
#else
|
|
135
|
+
#define BUFSZ 4096
|
|
136
|
+
char buf[BUFSZ];
|
|
137
|
+
nr = IOT_V0IO(iot).recv(IOT_ARG(iot), es->fd, buf, BUFSZ, 0);
|
|
138
|
+
#endif
|
|
129
139
|
|
|
130
140
|
if (nr > 0) {
|
|
141
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
|
131
142
|
/* Extend the BIO used length */
|
|
132
143
|
rmb->length += nr;
|
|
144
|
+
#else
|
|
145
|
+
BIO_write(es->rbio, buf, nr);
|
|
146
|
+
#endif
|
|
133
147
|
} else if (nr == 0) {
|
|
134
148
|
es->closed = 1;
|
|
135
149
|
return -1;
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
lcbio_pTABLE orig; /**< Table pointer we are wrapping */ \
|
|
32
32
|
SSL *ssl; /**< SSL object */ \
|
|
33
33
|
BIO *wbio; /**< BIO used for writing data to network */ \
|
|
34
|
-
BIO *rbio;
|
|
34
|
+
BIO *rbio; /**< BIO used for reading data from network */\
|
|
35
35
|
lcb_io_opt_t iops_dummy_; /**< Dummy IOPS structure which is exposed to LCB */ \
|
|
36
36
|
int error; /**< Internal error flag set once a fatal error is detect */\
|
|
37
37
|
lcb_error_t errcode; /**< The error, converted into libcouchbase */
|
|
@@ -113,6 +113,7 @@ iotssl_init_common(lcbio_XSSL *xs, lcbio_TABLE *orig, SSL_CTX *ctx);
|
|
|
113
113
|
void
|
|
114
114
|
iotssl_destroy_common(lcbio_XSSL *xs);
|
|
115
115
|
|
|
116
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
|
116
117
|
/**
|
|
117
118
|
* Reserve a specified amount of bytes for reading into a `BUF_MEM*` structure.
|
|
118
119
|
* Currently the amount reserved is hard coded.
|
|
@@ -132,6 +133,7 @@ iotssl_destroy_common(lcbio_XSSL *xs);
|
|
|
132
133
|
*/
|
|
133
134
|
void
|
|
134
135
|
iotssl_bm_reserve(BUF_MEM *bm);
|
|
136
|
+
#endif
|
|
135
137
|
|
|
136
138
|
/**
|
|
137
139
|
* Prepare the SSL structure so that a subsequent call to SSL_pending will
|
|
@@ -329,6 +329,7 @@ extract_services(lcbvb_CONFIG *cfg, cJSON *jsvc, lcbvb_SERVICES *svc, int is_ssl
|
|
|
329
329
|
EXTRACT_SERVICE("fts", fts);
|
|
330
330
|
EXTRACT_SERVICE("indexAdmin", ixadmin);
|
|
331
331
|
EXTRACT_SERVICE("indexScan", ixquery);
|
|
332
|
+
EXTRACT_SERVICE("cbas", cbas);
|
|
332
333
|
|
|
333
334
|
#undef EXTRACT_SERVICE
|
|
334
335
|
|
|
@@ -360,6 +361,9 @@ build_server_strings(lcbvb_CONFIG *cfg, lcbvb_SERVER *server)
|
|
|
360
361
|
if (server->ftspath == NULL && server->svc.fts) {
|
|
361
362
|
server->ftspath = strdup("/");
|
|
362
363
|
}
|
|
364
|
+
if (server->cbaspath == NULL && server->svc.cbas) {
|
|
365
|
+
server->cbaspath = strdup("/query/service");
|
|
366
|
+
}
|
|
363
367
|
return 1;
|
|
364
368
|
}
|
|
365
369
|
|
|
@@ -538,6 +542,36 @@ lcbvb_load_json(lcbvb_CONFIG *cfg, const char *data)
|
|
|
538
542
|
cfg->revid = -1;
|
|
539
543
|
}
|
|
540
544
|
|
|
545
|
+
cfg->caps = 0;
|
|
546
|
+
{
|
|
547
|
+
cJSON *jcaps = NULL;
|
|
548
|
+
if (get_jarray(cj, "bucketCapabilities", &jcaps)) {
|
|
549
|
+
unsigned ncaps = cJSON_GetArraySize(jcaps);
|
|
550
|
+
for (ii = 0; ii < ncaps; ii++) {
|
|
551
|
+
cJSON *jcap = cJSON_GetArrayItem(jcaps, ii);
|
|
552
|
+
if (jcap || jcap->type == cJSON_String) {
|
|
553
|
+
if (strcmp(jcap->valuestring, "xattr") == 0) {
|
|
554
|
+
cfg->caps |= LCBVB_CAP_XATTR;
|
|
555
|
+
} else if (strcmp(jcap->valuestring, "dcp") == 0) {
|
|
556
|
+
cfg->caps |= LCBVB_CAP_DCP;
|
|
557
|
+
} else if (strcmp(jcap->valuestring, "cbhello") == 0) {
|
|
558
|
+
cfg->caps |= LCBVB_CAP_CBHELLO;
|
|
559
|
+
} else if (strcmp(jcap->valuestring, "touch") == 0) {
|
|
560
|
+
cfg->caps |= LCBVB_CAP_TOUCH;
|
|
561
|
+
} else if (strcmp(jcap->valuestring, "couchapi") == 0) {
|
|
562
|
+
cfg->caps |= LCBVB_CAP_COUCHAPI;
|
|
563
|
+
} else if (strcmp(jcap->valuestring, "cccp") == 0) {
|
|
564
|
+
cfg->caps |= LCBVB_CAP_CCCP;
|
|
565
|
+
} else if (strcmp(jcap->valuestring, "xdcrCheckpointing") == 0) {
|
|
566
|
+
cfg->caps |= LCBVB_CAP_XDCR_CHECKPOINTING;
|
|
567
|
+
} else if (strcmp(jcap->valuestring, "nodesExt") == 0) {
|
|
568
|
+
cfg->caps |= LCBVB_CAP_NODES_EXT;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
541
575
|
/** Get the number of nodes. This traverses the list. Yuck */
|
|
542
576
|
cfg->nsrv = cJSON_GetArraySize(jnodes);
|
|
543
577
|
|
|
@@ -680,6 +714,7 @@ free_service_strs(lcbvb_SERVICES *svc)
|
|
|
680
714
|
free(svc->views_base_);
|
|
681
715
|
free(svc->query_base_);
|
|
682
716
|
free(svc->fts_base_);
|
|
717
|
+
free(svc->cbas_base_);
|
|
683
718
|
}
|
|
684
719
|
|
|
685
720
|
void
|
|
@@ -692,6 +727,7 @@ lcbvb_destroy(lcbvb_CONFIG *conf)
|
|
|
692
727
|
free(srv->viewpath);
|
|
693
728
|
free(srv->querypath);
|
|
694
729
|
free(srv->ftspath);
|
|
730
|
+
free(srv->cbaspath);
|
|
695
731
|
free_service_strs(&srv->svc);
|
|
696
732
|
free_service_strs(&srv->svc_ssl);
|
|
697
733
|
}
|
|
@@ -1115,6 +1151,8 @@ lcbvb_get_port(lcbvb_CONFIG *cfg,
|
|
|
1115
1151
|
return svc->n1ql;
|
|
1116
1152
|
} else if (type == LCBVB_SVCTYPE_FTS) {
|
|
1117
1153
|
return svc->fts;
|
|
1154
|
+
} else if (type == LCBVB_SVCTYPE_CBAS) {
|
|
1155
|
+
return svc->cbas;
|
|
1118
1156
|
} else {
|
|
1119
1157
|
return 0;
|
|
1120
1158
|
}
|
|
@@ -1190,7 +1228,8 @@ lcbvb_get_randhost_ex(const lcbvb_CONFIG *cfg,
|
|
|
1190
1228
|
(type == LCBVB_SVCTYPE_MGMT && svcs->mgmt) ||
|
|
1191
1229
|
(type == LCBVB_SVCTYPE_N1QL && svcs->n1ql) ||
|
|
1192
1230
|
(type == LCBVB_SVCTYPE_FTS && svcs->fts) ||
|
|
1193
|
-
(type == LCBVB_SVCTYPE_VIEWS && svcs->views)
|
|
1231
|
+
(type == LCBVB_SVCTYPE_VIEWS && svcs->views) ||
|
|
1232
|
+
(type == LCBVB_SVCTYPE_CBAS && svcs->cbas);
|
|
1194
1233
|
|
|
1195
1234
|
if (has_svc) {
|
|
1196
1235
|
cfg->randbuf[oix++] = (int)nn;
|
|
@@ -1251,6 +1290,9 @@ lcbvb_get_resturl(lcbvb_CONFIG *cfg, unsigned ix,
|
|
|
1251
1290
|
} else if (svc == LCBVB_SVCTYPE_FTS) {
|
|
1252
1291
|
path = srv->ftspath;
|
|
1253
1292
|
strp = &svcs->fts_base_;
|
|
1293
|
+
} else if (svc == LCBVB_SVCTYPE_CBAS) {
|
|
1294
|
+
path = srv->cbaspath;
|
|
1295
|
+
strp = &svcs->cbas_base_;
|
|
1254
1296
|
} else {
|
|
1255
1297
|
/* Unknown service! */
|
|
1256
1298
|
return NULL;
|
|
@@ -1310,6 +1352,9 @@ copy_service(const char *hostname,
|
|
|
1310
1352
|
if (src->fts_base_) {
|
|
1311
1353
|
dst->fts_base_ = strdup(src->fts_base_);
|
|
1312
1354
|
}
|
|
1355
|
+
if (src->cbas_base_) {
|
|
1356
|
+
dst->cbas_base_ = strdup(src->cbas_base_);
|
|
1357
|
+
}
|
|
1313
1358
|
if (dst->data) {
|
|
1314
1359
|
sprintf(buf, "%s:%d", hostname, dst->data);
|
|
1315
1360
|
dst->hoststrs[LCBVB_SVCTYPE_DATA] = strdup(buf);
|
|
@@ -1401,6 +1446,9 @@ lcbvb_genconfig_ex(lcbvb_CONFIG *vb,
|
|
|
1401
1446
|
if (src->ftspath) {
|
|
1402
1447
|
dst->ftspath = strdup(src->ftspath);
|
|
1403
1448
|
}
|
|
1449
|
+
if (src->cbaspath) {
|
|
1450
|
+
dst->cbaspath = strdup(src->cbaspath);
|
|
1451
|
+
}
|
|
1404
1452
|
|
|
1405
1453
|
copy_service(src->hostname, &src->svc, &dst->svc);
|
|
1406
1454
|
copy_service(src->hostname, &src->svc_ssl, &dst->svc_ssl);
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
#include <mocksupport/server.h>
|
|
22
22
|
#include "mock-environment.h"
|
|
23
23
|
#include <sstream>
|
|
24
|
+
#include "internal.h" /* settings from lcb_t for logging */
|
|
25
|
+
|
|
26
|
+
#define LOGARGS(instance, lvl) instance->settings, "tests-ENV", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
24
27
|
|
|
25
28
|
MockEnvironment *MockEnvironment::instance;
|
|
26
29
|
|
|
@@ -66,9 +69,10 @@ MockEnvironment::MockEnvironment(const char **args, std::string bucketname)
|
|
|
66
69
|
SetUp();
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
void MockEnvironment::failoverNode(int index, std::string bucket)
|
|
72
|
+
void MockEnvironment::failoverNode(int index, std::string bucket, bool rebalance)
|
|
70
73
|
{
|
|
71
74
|
MockBucketCommand bCmd(MockCommand::FAILOVER, index, bucket);
|
|
75
|
+
bCmd.set("rebalance", rebalance);
|
|
72
76
|
sendCommand(bCmd);
|
|
73
77
|
getResponse();
|
|
74
78
|
}
|
|
@@ -250,44 +254,61 @@ void MockEnvironment::createConnection(lcb_t &instance)
|
|
|
250
254
|
|
|
251
255
|
}
|
|
252
256
|
|
|
253
|
-
#define
|
|
257
|
+
#define STAT_VERSION "version"
|
|
254
258
|
|
|
255
259
|
extern "C" {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
MockEnvironment *me = (MockEnvironment *)cookie;
|
|
261
|
-
ASSERT_EQ(LCB_SUCCESS, err);
|
|
262
|
-
|
|
263
|
-
if (resp->v.v0.server_endpoint == NULL) {
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (!resp->v.v0.nkey) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
260
|
+
static void statsCallback(lcb_t instance, const void *cookie, lcb_error_t err, const lcb_server_stat_resp_t *resp)
|
|
261
|
+
{
|
|
262
|
+
MockEnvironment *me = (MockEnvironment *)cookie;
|
|
263
|
+
ASSERT_EQ(LCB_SUCCESS, err);
|
|
270
264
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
int version = ((const char *)resp->v.v0.bytes)[0] - '0';
|
|
277
|
-
if (version == 1) {
|
|
278
|
-
me->setServerVersion(MockEnvironment::VERSION_10);
|
|
279
|
-
} else if (version == 2) {
|
|
280
|
-
me->setServerVersion(MockEnvironment::VERSION_20);
|
|
265
|
+
if (resp->v.v0.server_endpoint == NULL) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
281
268
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
resp->v.v0.nbytes);
|
|
286
|
-
std::cerr << "' assuming 1.x" << std::endl;
|
|
269
|
+
if (!resp->v.v0.nkey) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
287
272
|
|
|
288
|
-
|
|
273
|
+
if (resp->v.v0.nkey != sizeof(STAT_VERSION) - 1 ||
|
|
274
|
+
memcmp(resp->v.v0.key, STAT_VERSION, sizeof(STAT_VERSION) - 1) != 0) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
MockEnvironment::ServerVersion version = MockEnvironment::VERSION_UNKNOWN;
|
|
278
|
+
if (resp->v.v0.nbytes > 2) {
|
|
279
|
+
int major = ((const char *)resp->v.v0.bytes)[0] - '0';
|
|
280
|
+
int minor = ((const char *)resp->v.v0.bytes)[2] - '0';
|
|
281
|
+
switch (major) {
|
|
282
|
+
case 4:
|
|
283
|
+
switch (minor) {
|
|
284
|
+
case 0:
|
|
285
|
+
version = MockEnvironment::VERSION_40;
|
|
286
|
+
break;
|
|
287
|
+
case 1:
|
|
288
|
+
version = MockEnvironment::VERSION_41;
|
|
289
|
+
break;
|
|
290
|
+
case 5:
|
|
291
|
+
version = MockEnvironment::VERSION_45;
|
|
292
|
+
break;
|
|
293
|
+
case 6:
|
|
294
|
+
version = MockEnvironment::VERSION_46;
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
break;
|
|
298
|
+
case 5:
|
|
299
|
+
version = MockEnvironment::VERSION_50;
|
|
300
|
+
break;
|
|
289
301
|
}
|
|
290
302
|
}
|
|
303
|
+
if (version == MockEnvironment::VERSION_UNKNOWN) {
|
|
304
|
+
lcb_log(LOGARGS(instance, ERROR), "Unable to determine version from string '%.*s', assuming 4.0",
|
|
305
|
+
(int)resp->v.v0.nbytes, (const char *)resp->v.v0.bytes);
|
|
306
|
+
version = MockEnvironment::VERSION_40;
|
|
307
|
+
}
|
|
308
|
+
me->setServerVersion(version);
|
|
309
|
+
lcb_log(LOGARGS(instance, INFO), "Using real cluster version %.*s (id=%d)", (int)resp->v.v0.nbytes,
|
|
310
|
+
(const char *)resp->v.v0.bytes, version);
|
|
311
|
+
}
|
|
291
312
|
}
|
|
292
313
|
|
|
293
314
|
void MockEnvironment::bootstrapRealCluster()
|
|
@@ -318,14 +339,11 @@ void MockEnvironment::bootstrapRealCluster()
|
|
|
318
339
|
// no body
|
|
319
340
|
}
|
|
320
341
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
featureRegistry.insert("replica_read");
|
|
327
|
-
featureRegistry.insert("lock");
|
|
328
|
-
}
|
|
342
|
+
featureRegistry.insert("observe");
|
|
343
|
+
featureRegistry.insert("views");
|
|
344
|
+
featureRegistry.insert("http");
|
|
345
|
+
featureRegistry.insert("replica_read");
|
|
346
|
+
featureRegistry.insert("lock");
|
|
329
347
|
|
|
330
348
|
numNodes = ii;
|
|
331
349
|
lcb_destroy(tmphandle);
|