libcouchbase 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|