libcouchbase 0.0.9 → 0.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 +4 -4
- data/README.md +4 -0
- data/ext/libcouchbase/CMakeLists.txt +1 -1
- data/ext/libcouchbase/RELEASE_NOTES.markdown +42 -0
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/source_files.cmake +1 -0
- data/ext/libcouchbase/include/libcouchbase/cntl.h +27 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +0 -10
- data/ext/libcouchbase/include/libcouchbase/error.h +8 -1
- data/ext/libcouchbase/include/memcached/protocol_binary.h +12 -3
- data/ext/libcouchbase/src/auth.cc +0 -4
- data/ext/libcouchbase/src/cntl.cc +11 -1
- data/ext/libcouchbase/src/connspec.cc +18 -0
- data/ext/libcouchbase/src/connspec.h +10 -0
- data/ext/libcouchbase/src/dns-srv.cc +13 -14
- data/ext/libcouchbase/src/errmap.cc +107 -0
- data/ext/libcouchbase/src/errmap.h +113 -0
- data/ext/libcouchbase/src/hostlist.cc +0 -35
- data/ext/libcouchbase/src/hostlist.h +38 -64
- data/ext/libcouchbase/src/http/http.cc +6 -1
- data/ext/libcouchbase/src/instance.cc +1 -1
- data/ext/libcouchbase/src/internal.h +10 -0
- data/ext/libcouchbase/src/mcserver/mcserver.cc +119 -3
- data/ext/libcouchbase/src/mcserver/mcserver.h +3 -1
- data/ext/libcouchbase/src/mcserver/negotiate.cc +130 -37
- data/ext/libcouchbase/src/nodeinfo.cc +1 -1
- data/ext/libcouchbase/src/settings.c +3 -0
- data/ext/libcouchbase/src/settings.h +5 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/iotests/mock-environment.h +2 -1
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +3 -4
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +97 -0
- data/lib/libcouchbase/bucket.rb +27 -12
- data/lib/libcouchbase/callbacks.rb +1 -1
- data/lib/libcouchbase/connection.rb +18 -5
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/connection_spec.rb +1 -1
- metadata +5 -2
@@ -173,10 +173,12 @@ public:
|
|
173
173
|
|
174
174
|
enum ReadState {
|
175
175
|
PKT_READ_COMPLETE,
|
176
|
-
PKT_READ_PARTIAL
|
176
|
+
PKT_READ_PARTIAL,
|
177
|
+
PKT_READ_ABORT
|
177
178
|
};
|
178
179
|
|
179
180
|
ReadState try_read(lcbio_CTX *ctx, rdb_IOROPE *ior);
|
181
|
+
bool handle_unknown_error(const MemcachedResponse& resinfo, lcb_error_t& newerr);
|
180
182
|
bool handle_nmv(MemcachedResponse& resinfo, mc_PACKET *oldpkt);
|
181
183
|
bool maybe_retry_packet(mc_PACKET *pkt, lcb_error_t err);
|
182
184
|
bool maybe_reconnect_on_fake_timeout(lcb_error_t received_error);
|
@@ -16,6 +16,10 @@
|
|
16
16
|
*/
|
17
17
|
|
18
18
|
#include <algorithm>
|
19
|
+
#include <string>
|
20
|
+
#include <sstream>
|
21
|
+
#include <vector>
|
22
|
+
|
19
23
|
#include "packetutils.h"
|
20
24
|
#include "mcserver.h"
|
21
25
|
#include "logging.h"
|
@@ -26,6 +30,7 @@
|
|
26
30
|
#include <cbsasl/cbsasl.h>
|
27
31
|
#include "negotiate.h"
|
28
32
|
#include "ctx-log-inl.h"
|
33
|
+
#include "auth-priv.h"
|
29
34
|
|
30
35
|
using namespace lcb;
|
31
36
|
|
@@ -34,6 +39,7 @@ static void cleanup_negotiated(SessionInfo* info);
|
|
34
39
|
static void handle_ioerr(lcbio_CTX *ctx, lcb_error_t err);
|
35
40
|
#define SESSREQ_LOGFMT "<%s:%s> (SASLREQ=%p) "
|
36
41
|
|
42
|
+
|
37
43
|
static void timeout_handler(void *arg);
|
38
44
|
|
39
45
|
#define SESSREQ_LOGID(s) get_ctx_host(s->ctx), get_ctx_port(s->ctx), (void*)s
|
@@ -65,9 +71,12 @@ public:
|
|
65
71
|
bool read_hello(const lcb::MemcachedResponse& packet);
|
66
72
|
void send_auth(const char *sasl_data, unsigned ndata);
|
67
73
|
void handle_read(lcbio_CTX *ioctx);
|
74
|
+
bool maybe_select_bucket();
|
68
75
|
|
69
76
|
enum MechStatus { MECH_UNAVAILABLE, MECH_NOT_NEEDED, MECH_OK };
|
70
77
|
MechStatus set_chosen_mech(std::string& mechlist, const char **data, unsigned int *ndata);
|
78
|
+
bool request_errmap();
|
79
|
+
bool update_errmap(const lcb::MemcachedResponse& packet);
|
71
80
|
|
72
81
|
SessionRequestImpl(lcbio_CONNDONE_cb callback, void *data, uint32_t timeout, lcbio_TABLE *iot, lcb_settings* settings_)
|
73
82
|
: ctx(NULL), cb(callback), cbdata(data),
|
@@ -324,6 +333,10 @@ SessionRequestImpl::send_hello()
|
|
324
333
|
unsigned nfeatures = 0;
|
325
334
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TLS;
|
326
335
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_XATTR;
|
336
|
+
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_SELECT_BUCKET;
|
337
|
+
if (settings->use_errmap) {
|
338
|
+
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_XERROR;
|
339
|
+
}
|
327
340
|
if (settings->tcp_nodelay) {
|
328
341
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TCPNODELAY;
|
329
342
|
}
|
@@ -360,6 +373,7 @@ SessionRequestImpl::send_hello()
|
|
360
373
|
lcb_U16 tmp = htons(features[ii]);
|
361
374
|
lcbio_ctx_put(ctx, &tmp, sizeof tmp);
|
362
375
|
}
|
376
|
+
|
363
377
|
lcbio_ctx_rwant(ctx, 24);
|
364
378
|
return true;
|
365
379
|
}
|
@@ -381,12 +395,68 @@ SessionRequestImpl::read_hello(const lcb::MemcachedResponse& resp)
|
|
381
395
|
return true;
|
382
396
|
}
|
383
397
|
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
398
|
+
bool
|
399
|
+
SessionRequestImpl::request_errmap() {
|
400
|
+
lcb::MemcachedRequest hdr(PROTOCOL_BINARY_CMD_GET_ERROR_MAP);
|
401
|
+
uint16_t version = htons(1);
|
402
|
+
hdr.sizes(0, 0, 2);
|
403
|
+
const char *p = reinterpret_cast<const char *>(&version);
|
404
|
+
|
405
|
+
lcbio_ctx_put(ctx, hdr.data(), hdr.size());
|
406
|
+
lcbio_ctx_put(ctx, p, 2);
|
407
|
+
lcbio_ctx_rwant(ctx, 24);
|
408
|
+
return true;
|
409
|
+
}
|
410
|
+
|
411
|
+
bool
|
412
|
+
SessionRequestImpl::update_errmap(const lcb::MemcachedResponse& resp)
|
413
|
+
{
|
414
|
+
// Get the error map object
|
415
|
+
using lcb::errmap::ErrorMap;
|
416
|
+
|
417
|
+
std::string errmsg;
|
418
|
+
ErrorMap& mm = *settings->errmap;
|
419
|
+
ErrorMap::ParseStatus status = mm.parse(
|
420
|
+
resp.body<const char*>(), resp.bodylen(), errmsg);
|
421
|
+
|
422
|
+
if (status != ErrorMap::UPDATED && status != ErrorMap::NOT_UPDATED) {
|
423
|
+
errmsg = "Couldn't update error map: " + errmsg;
|
424
|
+
set_error(LCB_PROTOCOL_ERROR, errmsg.c_str());
|
425
|
+
return false;
|
426
|
+
}
|
427
|
+
|
428
|
+
return true;
|
429
|
+
}
|
430
|
+
|
431
|
+
// Returns true if sending the SELECT_BUCKET command, false otherwise.
|
432
|
+
bool
|
433
|
+
SessionRequestImpl::maybe_select_bucket() {
|
434
|
+
|
435
|
+
// Only send a SELECT_BUCKET if we have the SELECT_BUCKET bit enabled.
|
436
|
+
if (!info->has_feature(PROTOCOL_BINARY_FEATURE_SELECT_BUCKET)) {
|
437
|
+
return false;
|
438
|
+
}
|
439
|
+
|
440
|
+
if (!settings->select_bucket) {
|
441
|
+
lcb_log(LOGARGS(this, WARN), SESSREQ_LOGFMT "SELECT_BUCKET Disabled by application", SESSREQ_LOGID(this));
|
442
|
+
return false;
|
443
|
+
}
|
444
|
+
|
445
|
+
// send the SELECT_BUCKET command:
|
446
|
+
lcb_log(LOGARGS(this, INFO), SESSREQ_LOGFMT "Sending SELECT_BUCKET", SESSREQ_LOGID(this));
|
447
|
+
lcb::MemcachedRequest req(PROTOCOL_BINARY_CMD_SELECT_BUCKET);
|
448
|
+
req.sizes(0, strlen(settings->bucket), 0);
|
449
|
+
lcbio_ctx_put(ctx, req.data(), req.size());
|
450
|
+
lcbio_ctx_put(ctx, settings->bucket, strlen(settings->bucket));
|
451
|
+
LCBIO_CTX_RSCHEDULE(ctx, 24);
|
452
|
+
return true;
|
453
|
+
}
|
454
|
+
|
455
|
+
static bool isUnsupported(uint16_t status) {
|
456
|
+
return status == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED ||
|
457
|
+
status == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND ||
|
458
|
+
status == PROTOCOL_BINARY_RESPONSE_EACCESS;
|
459
|
+
}
|
390
460
|
|
391
461
|
/**
|
392
462
|
* It's assumed the server buffers will be reset upon close(), so we must make
|
@@ -397,7 +467,7 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
397
467
|
{
|
398
468
|
lcb::MemcachedResponse resp;
|
399
469
|
unsigned required;
|
400
|
-
|
470
|
+
bool completed = false;
|
401
471
|
|
402
472
|
GT_NEXT_PACKET:
|
403
473
|
|
@@ -416,66 +486,92 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
416
486
|
MechStatus mechrc = set_chosen_mech(mechs, &mechlist_data, &nmechlist_data);
|
417
487
|
if (mechrc == MECH_OK) {
|
418
488
|
send_auth(mechlist_data, nmechlist_data);
|
419
|
-
state = SREQ_S_WAIT;
|
420
489
|
} else if (mechrc == MECH_UNAVAILABLE) {
|
421
|
-
|
490
|
+
// Do nothing - error already set
|
422
491
|
} else {
|
423
|
-
|
492
|
+
completed = !maybe_select_bucket();
|
424
493
|
}
|
425
494
|
break;
|
426
495
|
}
|
427
496
|
|
428
497
|
case PROTOCOL_BINARY_CMD_SASL_AUTH: {
|
429
498
|
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
430
|
-
|
431
|
-
state = SREQ_S_AUTHDONE;
|
499
|
+
completed = !maybe_select_bucket();
|
432
500
|
break;
|
433
|
-
}
|
434
|
-
|
435
|
-
|
501
|
+
} else if (status == PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE) {
|
502
|
+
send_step(resp);
|
503
|
+
} else {
|
436
504
|
set_error(LCB_AUTH_ERROR, "SASL AUTH failed");
|
437
|
-
state = SREQ_S_ERROR;
|
438
505
|
break;
|
439
506
|
}
|
440
|
-
if (send_step(resp) && send_hello()) {
|
441
|
-
state = SREQ_S_WAIT;
|
442
|
-
} else {
|
443
|
-
state = SREQ_S_ERROR;
|
444
|
-
}
|
445
507
|
break;
|
446
508
|
}
|
447
509
|
|
448
510
|
case PROTOCOL_BINARY_CMD_SASL_STEP: {
|
449
|
-
if (status
|
511
|
+
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
512
|
+
completed = !maybe_select_bucket();
|
513
|
+
} else {
|
450
514
|
lcb_log(LOGARGS(this, WARN), SESSREQ_LOGFMT "SASL auth failed with STATUS=0x%x", SESSREQ_LOGID(this), status);
|
451
515
|
set_error(LCB_AUTH_ERROR, "SASL Step Failed");
|
452
|
-
state = SREQ_S_ERROR;
|
453
|
-
} else {
|
454
|
-
/* Wait for pipelined HELLO response */
|
455
|
-
state = SREQ_S_AUTHDONE;
|
456
516
|
}
|
457
517
|
break;
|
458
518
|
}
|
459
519
|
|
460
520
|
case PROTOCOL_BINARY_CMD_HELLO: {
|
461
|
-
state = SREQ_S_HELLODONE;
|
462
521
|
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
463
522
|
if (!read_hello(resp)) {
|
464
523
|
set_error(LCB_PROTOCOL_ERROR, "Couldn't parse HELLO");
|
524
|
+
break;
|
465
525
|
}
|
466
|
-
} else if (status
|
467
|
-
status == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED) {
|
526
|
+
} else if (isUnsupported(status)) {
|
468
527
|
lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Server does not support HELLO", SESSREQ_LOGID(this));
|
469
|
-
/* nothing */
|
470
528
|
} else {
|
471
529
|
set_error(LCB_PROTOCOL_ERROR, "Hello response unexpected");
|
472
|
-
|
530
|
+
break;
|
531
|
+
}
|
532
|
+
|
533
|
+
if (info->has_feature(PROTOCOL_BINARY_FEATURE_XERROR)) {
|
534
|
+
request_errmap();
|
535
|
+
} else {
|
536
|
+
lcb_log(LOGARGS(this, TRACE), SESSREQ_LOGFMT "GET_ERRORMAP unsupported/disabled", SESSREQ_LOGID(this));
|
537
|
+
}
|
538
|
+
|
539
|
+
// In any event, it's also time to send the LIST_MECHS request
|
540
|
+
lcb::MemcachedRequest req(PROTOCOL_BINARY_CMD_SASL_LIST_MECHS);
|
541
|
+
lcbio_ctx_put(ctx, req.data(), req.size());
|
542
|
+
LCBIO_CTX_RSCHEDULE(ctx, 24);
|
543
|
+
|
544
|
+
break;
|
545
|
+
}
|
546
|
+
|
547
|
+
case PROTOCOL_BINARY_CMD_GET_ERROR_MAP: {
|
548
|
+
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
549
|
+
if (!update_errmap(resp)) {
|
550
|
+
}
|
551
|
+
} else if (isUnsupported(status)) {
|
552
|
+
lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Server does not support GET_ERRMAP (0x%x)", SESSREQ_LOGID(this), status);
|
553
|
+
} else {
|
554
|
+
lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Unexpected status 0x%x received for GET_ERRMAP", SESSREQ_LOGID(this), status);
|
555
|
+
set_error(LCB_PROTOCOL_ERROR, "GET_ERRMAP response unexpected");
|
556
|
+
}
|
557
|
+
// Note, there is no explicit state transition here. LIST_MECHS is
|
558
|
+
// pipelined after this request.
|
559
|
+
break;
|
560
|
+
}
|
561
|
+
|
562
|
+
case PROTOCOL_BINARY_CMD_SELECT_BUCKET: {
|
563
|
+
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
564
|
+
completed = true;
|
565
|
+
} else if (status == PROTOCOL_BINARY_RESPONSE_EACCESS) {
|
566
|
+
set_error(LCB_AUTH_ERROR, "Provided credentials not allowed for bucket");
|
567
|
+
} else {
|
568
|
+
lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Unexpected status 0x%x received for SELECT_BUCKET", SESSREQ_LOGID(this), status);
|
569
|
+
set_error(LCB_PROTOCOL_ERROR, "Other auth error");
|
473
570
|
}
|
474
571
|
break;
|
475
572
|
}
|
476
573
|
|
477
574
|
default: {
|
478
|
-
state = SREQ_S_ERROR;
|
479
575
|
lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Received unknown response. OP=0x%x. RC=0x%x", SESSREQ_LOGID(this), resp.opcode(), resp.status());
|
480
576
|
set_error(LCB_NOT_SUPPORTED, "Received unknown response");
|
481
577
|
break;
|
@@ -490,9 +586,7 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
490
586
|
// or fail the request, potentially destroying the underlying connection
|
491
587
|
if (has_error()) {
|
492
588
|
fail();
|
493
|
-
} else if (
|
494
|
-
fail(LCB_ERROR, "FIXME: Error code set without description");
|
495
|
-
} else if (state == SREQ_S_HELLODONE) {
|
589
|
+
} else if (completed) {
|
496
590
|
success();
|
497
591
|
} else {
|
498
592
|
goto GT_NEXT_PACKET;
|
@@ -537,8 +631,7 @@ SessionRequestImpl::start(lcbio_SOCKET *sock) {
|
|
537
631
|
return;
|
538
632
|
}
|
539
633
|
|
540
|
-
|
541
|
-
lcbio_ctx_put(ctx, hdr.data(), hdr.size());
|
634
|
+
send_hello();
|
542
635
|
LCBIO_CTX_RSCHEDULE(ctx, 24);
|
543
636
|
}
|
544
637
|
|
@@ -167,7 +167,7 @@ lcb_int32_t lcb_get_num_nodes(lcb_t instance)
|
|
167
167
|
LIBCOUCHBASE_API
|
168
168
|
const char *const *lcb_get_server_list(lcb_t instance)
|
169
169
|
{
|
170
|
-
return
|
170
|
+
return instance->ht_nodes->get_strlist();
|
171
171
|
}
|
172
172
|
|
173
173
|
LIBCOUCHBASE_API
|
@@ -57,6 +57,7 @@ void lcb_default_settings(lcb_settings *settings)
|
|
57
57
|
settings->tcp_nodelay = LCB_DEFAULT_TCP_NODELAY;
|
58
58
|
settings->retry_nmv_interval = LCB_DEFAULT_RETRY_NMV_INTERVAL;
|
59
59
|
settings->vb_noguess = LCB_DEFAULT_VB_NOGUESS;
|
60
|
+
settings->select_bucket = LCB_DEFAULT_SELECT_BUCKET;
|
60
61
|
}
|
61
62
|
|
62
63
|
LCB_INTERNAL_API
|
@@ -67,6 +68,7 @@ lcb_settings_new(void)
|
|
67
68
|
lcb_default_settings(settings);
|
68
69
|
settings->refcount = 1;
|
69
70
|
settings->auth = lcbauth_new();
|
71
|
+
settings->errmap = lcb_errmap_new();
|
70
72
|
return settings;
|
71
73
|
}
|
72
74
|
|
@@ -83,6 +85,7 @@ lcb_settings_unref(lcb_settings *settings)
|
|
83
85
|
free(settings->client_string);
|
84
86
|
|
85
87
|
lcbauth_unref(settings->auth);
|
88
|
+
lcb_errmap_free(settings->errmap);
|
86
89
|
|
87
90
|
if (settings->ssl_ctx) {
|
88
91
|
lcbio_ssl_free(settings->ssl_ctx);
|
@@ -84,9 +84,11 @@
|
|
84
84
|
#define LCB_DEFAULT_RETRY_NMV_INTERVAL LCB_MS2US(100)
|
85
85
|
#define LCB_DEFAULT_VB_NOGUESS 1
|
86
86
|
#define LCB_DEFAULT_TCP_NODELAY 1
|
87
|
+
#define LCB_DEFAULT_SELECT_BUCKET 0
|
87
88
|
|
88
89
|
#include "config.h"
|
89
90
|
#include <libcouchbase/couchbase.h>
|
91
|
+
#include "errmap.h"
|
90
92
|
|
91
93
|
#ifdef __cplusplus
|
92
94
|
extern "C" {
|
@@ -148,6 +150,8 @@ typedef struct lcb_settings_st {
|
|
148
150
|
unsigned ipv6 : 2;
|
149
151
|
unsigned tcp_nodelay : 1;
|
150
152
|
unsigned readj_ts_wait : 1;
|
153
|
+
unsigned use_errmap : 1;
|
154
|
+
unsigned select_bucket : 1;
|
151
155
|
|
152
156
|
short max_redir;
|
153
157
|
unsigned refcount;
|
@@ -165,6 +169,7 @@ typedef struct lcb_settings_st {
|
|
165
169
|
void (*dtorcb)(const void *);
|
166
170
|
void *dtorarg;
|
167
171
|
char *client_string;
|
172
|
+
lcb_pERRMAP errmap;
|
168
173
|
lcb_U32 retry_nmv_interval;
|
169
174
|
} lcb_settings;
|
170
175
|
|
@@ -156,7 +156,9 @@ iotssl_log_errors(lcbio_XSSL *xs)
|
|
156
156
|
if (ERR_GET_LIB(curerr) == ERR_LIB_SSL) {
|
157
157
|
switch (ERR_GET_REASON(curerr)) {
|
158
158
|
case SSL_R_CERTIFICATE_VERIFY_FAILED:
|
159
|
+
#ifdef SSL_R_MISSING_VERIFY_MESSAGE
|
159
160
|
case SSL_R_MISSING_VERIFY_MESSAGE:
|
161
|
+
#endif
|
160
162
|
xs->errcode = LCB_SSL_CANTVERIFY;
|
161
163
|
break;
|
162
164
|
|
@@ -82,117 +82,109 @@ TEST_F(Hostlist, testEquals)
|
|
82
82
|
|
83
83
|
TEST_F(Hostlist, testParseList)
|
84
84
|
{
|
85
|
-
|
86
|
-
ASSERT_FALSE(NULL == hosts);
|
85
|
+
lcb::Hostlist hosts;
|
87
86
|
|
88
87
|
lcb_error_t err;
|
89
|
-
err =
|
88
|
+
err = hosts.add("1.1.1.1", 8091);
|
90
89
|
ASSERT_EQ(LCB_SUCCESS, err);
|
91
|
-
ASSERT_EQ(1, hosts
|
92
|
-
ASSERT_TRUE(hosts
|
90
|
+
ASSERT_EQ(1, hosts.size());
|
91
|
+
ASSERT_TRUE(hosts.exists("1.1.1.1:8091"));
|
93
92
|
|
94
|
-
|
95
|
-
|
96
|
-
err = hostlist_add_stringz(hosts, "1.1.1.1;", 8091);
|
93
|
+
hosts.clear();
|
94
|
+
err = hosts.add("1.1.1.1;", 8091);
|
97
95
|
ASSERT_EQ(LCB_SUCCESS, err);
|
98
|
-
ASSERT_EQ(1, hosts
|
99
|
-
ASSERT_TRUE(hosts
|
96
|
+
ASSERT_EQ(1, hosts.size());
|
97
|
+
ASSERT_TRUE(hosts.exists("1.1.1.1:8091"));
|
100
98
|
|
101
|
-
|
102
|
-
err =
|
99
|
+
hosts.clear();
|
100
|
+
err = hosts.add(";", 8091);
|
103
101
|
ASSERT_EQ(LCB_SUCCESS, err);
|
104
|
-
ASSERT_EQ(0, hosts
|
102
|
+
ASSERT_EQ(0, hosts.size());
|
105
103
|
|
106
|
-
|
107
|
-
err =
|
104
|
+
hosts.clear();
|
105
|
+
err = hosts.add(";;;;", 8091);
|
108
106
|
ASSERT_EQ(LCB_SUCCESS, err);
|
109
|
-
ASSERT_EQ(0, hosts
|
107
|
+
ASSERT_EQ(0, hosts.size());
|
110
108
|
|
111
|
-
|
112
|
-
err =
|
109
|
+
hosts.clear();
|
110
|
+
err = hosts.add("1.1.1.1;2.2.2.2", 8091);
|
113
111
|
ASSERT_EQ(LCB_SUCCESS, err);
|
114
|
-
ASSERT_EQ(2, hosts
|
115
|
-
ASSERT_TRUE(hosts
|
116
|
-
ASSERT_TRUE(hosts
|
117
|
-
|
112
|
+
ASSERT_EQ(2, hosts.size());
|
113
|
+
ASSERT_TRUE(hosts.exists("1.1.1.1:8091"));
|
114
|
+
ASSERT_TRUE(hosts.exists("2.2.2.2:8091"));
|
118
115
|
|
119
|
-
|
120
|
-
err =
|
116
|
+
hosts.clear();
|
117
|
+
err = hosts.add("1.1.1.1:1000;2.2.2.2:2000;3.3.3.3", 8091);
|
121
118
|
ASSERT_EQ(LCB_SUCCESS, err);
|
122
|
-
ASSERT_EQ(3, hosts
|
123
|
-
ASSERT_TRUE(hosts
|
124
|
-
ASSERT_TRUE(hosts
|
125
|
-
ASSERT_TRUE(hosts
|
119
|
+
ASSERT_EQ(3, hosts.size());
|
120
|
+
ASSERT_TRUE(hosts.exists("1.1.1.1:1000"));
|
121
|
+
ASSERT_TRUE(hosts.exists("2.2.2.2:2000"));
|
122
|
+
ASSERT_TRUE(hosts.exists("3.3.3.3:8091"));
|
126
123
|
|
127
|
-
|
128
|
-
err =
|
124
|
+
hosts.clear();
|
125
|
+
err = hosts.add("1.1.1.1;1.1.1.1;1.1.1.1", 8091);
|
129
126
|
ASSERT_EQ(LCB_SUCCESS, err);
|
130
|
-
ASSERT_EQ(1, hosts
|
131
|
-
ASSERT_TRUE(hosts
|
127
|
+
ASSERT_EQ(1, hosts.size());
|
128
|
+
ASSERT_TRUE(hosts.exists("1.1.1.1:8091"));
|
132
129
|
|
133
130
|
|
134
|
-
|
135
|
-
err =
|
131
|
+
hosts.clear();
|
132
|
+
err = hosts.add("1.1.1.1:9000;1.1.1.1:9001;1.1.1.1:9002", 8091);
|
136
133
|
ASSERT_EQ(LCB_SUCCESS, err);
|
137
|
-
ASSERT_EQ(3, hosts
|
138
|
-
ASSERT_TRUE(hosts
|
139
|
-
ASSERT_TRUE(hosts
|
140
|
-
ASSERT_TRUE(hosts
|
141
|
-
|
142
|
-
|
143
|
-
ASSERT_EQ(LCB_SUCCESS,
|
144
|
-
ASSERT_EQ(LCB_SUCCESS,
|
145
|
-
ASSERT_EQ(LCB_SUCCESS,
|
146
|
-
ASSERT_EQ(3, hosts
|
147
|
-
|
148
|
-
ASSERT_TRUE(hosts
|
149
|
-
ASSERT_TRUE(hosts
|
150
|
-
ASSERT_TRUE(hosts
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
hostlist_destroy(hosts);
|
134
|
+
ASSERT_EQ(3, hosts.size());
|
135
|
+
ASSERT_TRUE(hosts.exists("1.1.1.1:9000"));
|
136
|
+
ASSERT_TRUE(hosts.exists("1.1.1.1:9001"));
|
137
|
+
ASSERT_TRUE(hosts.exists("1.1.1.1:9002"));
|
138
|
+
|
139
|
+
hosts.clear();
|
140
|
+
ASSERT_EQ(LCB_SUCCESS, hosts.add("1.1.1.1", 8091));
|
141
|
+
ASSERT_EQ(LCB_SUCCESS, hosts.add("2.2.2.2", 8091));
|
142
|
+
ASSERT_EQ(LCB_SUCCESS, hosts.add("3.3.3.3", 8091));
|
143
|
+
ASSERT_EQ(3, hosts.size());
|
144
|
+
|
145
|
+
ASSERT_TRUE(hosts.exists("1.1.1.1:8091"));
|
146
|
+
ASSERT_TRUE(hosts.exists("2.2.2.2:8091"));
|
147
|
+
ASSERT_TRUE(hosts.exists("3.3.3.3:8091"));
|
148
|
+
|
149
|
+
hosts.randomize();
|
150
|
+
hosts.clear();
|
151
|
+
hosts.randomize();
|
157
152
|
}
|
158
153
|
|
159
154
|
TEST_F(Hostlist, testCycle)
|
160
155
|
{
|
161
|
-
|
156
|
+
lcb::Hostlist hosts;
|
162
157
|
lcb_host_t *curhost;
|
163
158
|
|
164
|
-
|
165
159
|
// Empty list
|
166
|
-
ASSERT_EQ(NULL,
|
167
|
-
ASSERT_EQ(NULL,
|
168
|
-
hostlist_destroy(hosts);
|
169
|
-
hosts = hostlist_create();
|
160
|
+
ASSERT_EQ(NULL, hosts.next(false));
|
161
|
+
ASSERT_EQ(NULL, hosts.next(true));
|
170
162
|
|
171
|
-
|
172
|
-
|
163
|
+
hosts.clear();
|
164
|
+
hosts.add("1.1.1.1", 8091);
|
165
|
+
curhost = hosts.next(false);
|
173
166
|
ASSERT_TRUE(curhost != NULL);
|
174
167
|
ASSERT_TRUE(hostEquals(*curhost, "1.1.1.1", "8091"));
|
175
168
|
|
176
|
-
curhost =
|
177
|
-
ASSERT_TRUE(
|
178
|
-
ASSERT_TRUE(
|
179
|
-
ASSERT_TRUE(hosts
|
169
|
+
curhost = hosts.next(false);
|
170
|
+
ASSERT_TRUE(hosts.next(false) == NULL);
|
171
|
+
ASSERT_TRUE(hosts.next(false) == NULL);
|
172
|
+
ASSERT_TRUE(hosts.ix == 1);
|
180
173
|
|
181
|
-
curhost =
|
174
|
+
curhost = hosts.next(true);
|
182
175
|
ASSERT_TRUE(curhost != NULL);
|
183
176
|
ASSERT_TRUE(hostEquals(*curhost, "1.1.1.1", "8091"));
|
184
177
|
|
185
|
-
|
186
|
-
curhost =
|
178
|
+
hosts.add("2.2.2.2", 8091);
|
179
|
+
curhost = hosts.next(false);
|
187
180
|
ASSERT_TRUE(hostEquals(*curhost, "2.2.2.2", "8091"));
|
188
|
-
ASSERT_TRUE(
|
181
|
+
ASSERT_TRUE(hosts.next(false) == NULL);
|
189
182
|
|
190
|
-
curhost =
|
183
|
+
curhost = hosts.next(true);
|
191
184
|
ASSERT_TRUE(hostEquals(*curhost, "1.1.1.1", "8091"));
|
192
|
-
curhost =
|
185
|
+
curhost = hosts.next(false);
|
193
186
|
ASSERT_TRUE(hostEquals(*curhost, "2.2.2.2", "8091"));
|
194
187
|
|
195
|
-
|
196
|
-
ASSERT_TRUE(
|
197
|
-
hostlist_destroy(hosts);
|
188
|
+
hosts.clear();
|
189
|
+
ASSERT_TRUE(hosts.next(true) == NULL);
|
198
190
|
}
|