couchbase 3.2.3 → 3.2.4
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.
- package/deps/lcb/CMakeLists.txt +1 -1
- package/deps/lcb/CONTRIBUTING.md +1 -1
- package/deps/lcb/README.markdown +2 -2
- package/deps/lcb/RELEASE_NOTES.markdown +72 -17
- package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
- package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
- package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -6
- package/deps/lcb/doc/Doxyfile +1 -1
- package/deps/lcb/example/minimal/query.c +9 -7
- package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
- package/deps/lcb/include/libcouchbase/couchbase.h +3 -1
- package/deps/lcb/include/libcouchbase/error.h +2 -0
- package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
- package/deps/lcb/include/libcouchbase/tracing.h +2 -2
- package/deps/lcb/include/memcached/protocol_binary.h +21 -0
- package/deps/lcb/libcouchbase.gyp +347 -349
- package/deps/lcb/packaging/deb/control +1 -1
- package/deps/lcb/src/analytics/analytics_handle.cc +7 -5
- package/deps/lcb/src/analytics/analytics_handle.hh +28 -0
- package/deps/lcb/src/capi/cmd_counter.hh +6 -0
- package/deps/lcb/src/capi/cmd_exists.hh +6 -0
- package/deps/lcb/src/capi/cmd_get.hh +5 -0
- package/deps/lcb/src/capi/cmd_get_replica.hh +6 -0
- package/deps/lcb/src/capi/cmd_remove.hh +6 -0
- package/deps/lcb/src/capi/cmd_search.hh +6 -0
- package/deps/lcb/src/capi/cmd_store.hh +16 -21
- package/deps/lcb/src/capi/cmd_subdoc.hh +18 -0
- package/deps/lcb/src/capi/cmd_touch.hh +6 -0
- package/deps/lcb/src/capi/cmd_unlock.hh +6 -0
- package/deps/lcb/src/capi/cmd_view.hh +6 -0
- package/deps/lcb/src/capi/collection_qualifier.hh +2 -2
- package/deps/lcb/src/cntl.cc +42 -8
- package/deps/lcb/src/dns-srv.cc +5 -3
- package/deps/lcb/src/errmap.cc +5 -9
- package/deps/lcb/src/errmap.h +7 -3
- package/deps/lcb/src/handler.cc +24 -18
- package/deps/lcb/src/lcbio/ctx.cc +4 -2
- package/deps/lcb/src/mcserver/mcserver.cc +8 -5
- package/deps/lcb/src/mcserver/negotiate.cc +39 -17
- package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
- package/deps/lcb/src/n1ql/query_handle.cc +27 -16
- package/deps/lcb/src/n1ql/query_handle.hh +27 -1
- package/deps/lcb/src/operations/counter.cc +1 -1
- package/deps/lcb/src/operations/exists.cc +2 -2
- package/deps/lcb/src/operations/get.cc +2 -2
- package/deps/lcb/src/operations/observe.cc +1 -1
- package/deps/lcb/src/operations/remove.cc +1 -1
- package/deps/lcb/src/operations/store.cc +1 -1
- package/deps/lcb/src/operations/subdoc.cc +1 -2
- package/deps/lcb/src/operations/touch.cc +2 -2
- package/deps/lcb/src/operations/unlock.cc +2 -2
- package/deps/lcb/src/search/search_handle.cc +27 -8
- package/deps/lcb/src/search/search_handle.hh +29 -0
- package/deps/lcb/src/ssl/ssl_common.c +6 -7
- package/deps/lcb/src/tracing/span.cc +43 -10
- package/deps/lcb/src/tracing/tracing-internal.h +105 -93
- package/deps/lcb/src/views/view_handle.cc +13 -5
- package/deps/lcb/src/views/view_handle.hh +29 -0
- package/deps/lcb/tests/CMakeLists.txt +21 -0
- package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
- package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
- package/deps/lcb/tests/iotests/mock-environment.cc +15 -0
- package/deps/lcb/tests/iotests/mock-environment.h +47 -0
- package/deps/lcb/tests/iotests/mock-unit-test.cc +96 -5
- package/deps/lcb/tests/iotests/mock-unit-test.h +32 -0
- package/deps/lcb/tests/iotests/t_collections.cc +1 -1
- package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
- package/deps/lcb/tests/iotests/t_get.cc +14 -4
- package/deps/lcb/tests/iotests/t_n1ql.cc +17 -1
- package/deps/lcb/tests/iotests/t_views.cc +1 -0
- package/deps/lcb/tests/iotests/testutil.cc +168 -0
- package/deps/lcb/tests/iotests/testutil.h +111 -0
- package/deps/lcb/tests/mocksupport/procutil.c +32 -28
- package/deps/lcb/tests/mocksupport/server.c +0 -1
- package/deps/lcb/tools/cbc.cc +7 -0
- package/dist/analyticsindexmanager.js +3 -3
- package/dist/binding.d.ts +2 -0
- package/dist/bindingutilities.js +4 -0
- package/dist/bucketmanager.d.ts +31 -1
- package/dist/bucketmanager.js +28 -2
- package/dist/collection.js +2 -2
- package/dist/collectionmanager.js +2 -2
- package/dist/connection.js +3 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.js +26 -2
- package/dist/eventingfunctionmanager.js +6 -6
- package/dist/queryindexmanager.js +3 -3
- package/dist/searchexecutor.js +3 -0
- package/dist/searchindexmanager.js +1 -1
- package/dist/searchquery.d.ts +17 -0
- package/dist/searchquery.js +22 -1
- package/dist/searchtypes.d.ts +7 -2
- package/dist/searchtypes.js +2 -2
- package/dist/usermanager.js +1 -1
- package/dist/viewindexmanager.js +1 -1
- package/package.json +1 -1
- package/src/connection.cpp +2 -0
- package/src/constants.cpp +2 -0
- package/src/instance.cpp +8 -1
- package/src/instance.h +1 -0
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
#include "internal.h" /* vbucket_* things from lcb_INSTANCE **/
|
|
22
22
|
#include <lcbio/iotable.h>
|
|
23
|
-
#include "
|
|
23
|
+
#include "libcouchbase/couchbase.h"
|
|
24
24
|
|
|
25
25
|
#define LOGARGS(instance, lvl) instance->settings, "tests-MUT", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
26
26
|
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
*/
|
|
30
30
|
void MockUnitTest::SetUp()
|
|
31
31
|
{
|
|
32
|
-
srand(time(
|
|
32
|
+
srand(time(nullptr));
|
|
33
33
|
MockEnvironment::Reset();
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -42,8 +42,8 @@ void checkConnectCommon(lcb_INSTANCE *instance)
|
|
|
42
42
|
|
|
43
43
|
void MockUnitTest::createClusterConnection(HandleWrap &handle, lcb_INSTANCE **instance)
|
|
44
44
|
{
|
|
45
|
-
lcb_CREATEOPTS *options =
|
|
46
|
-
MockEnvironment::getInstance()->makeConnectParams(options,
|
|
45
|
+
lcb_CREATEOPTS *options = nullptr;
|
|
46
|
+
MockEnvironment::getInstance()->makeConnectParams(options, nullptr, LCB_TYPE_CLUSTER);
|
|
47
47
|
MockEnvironment::getInstance()->createConnection(handle, instance, options);
|
|
48
48
|
checkConnectCommon(handle.getLcb());
|
|
49
49
|
lcb_createopts_destroy(options);
|
|
@@ -70,7 +70,7 @@ void MockUnitTest::createConnection(lcb_INSTANCE **instance)
|
|
|
70
70
|
|
|
71
71
|
void MockUnitTest::createConnection(HandleWrap &handle)
|
|
72
72
|
{
|
|
73
|
-
lcb_INSTANCE *instance =
|
|
73
|
+
lcb_INSTANCE *instance = nullptr;
|
|
74
74
|
createConnection(handle, &instance);
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -81,3 +81,94 @@ lcb_STATUS MockUnitTest::tryCreateConnection(HandleWrap &hw, lcb_INSTANCE **inst
|
|
|
81
81
|
lcb_wait(*instance, LCB_WAIT_DEFAULT);
|
|
82
82
|
return lcb_get_bootstrap_status(*instance);
|
|
83
83
|
}
|
|
84
|
+
|
|
85
|
+
void MockUnitTest::assert_kv_span(const std::shared_ptr<TestSpan> &span, const std::string &expectedName,
|
|
86
|
+
const KVSpanAssertions &assertions)
|
|
87
|
+
{
|
|
88
|
+
auto bucket = MockEnvironment::getInstance()->getBucket();
|
|
89
|
+
ASSERT_EQ(expectedName, span->name);
|
|
90
|
+
ASSERT_EQ("couchbase", span->str_tags["db.system"]);
|
|
91
|
+
ASSERT_TRUE(span->int_tags.find("db.couchbase.server_duration") != span->int_tags.end());
|
|
92
|
+
ASSERT_EQ(bucket, span->str_tags["db.name"]);
|
|
93
|
+
ASSERT_EQ(assertions.scope, span->str_tags["db.couchbase.scope"]);
|
|
94
|
+
ASSERT_EQ(assertions.collection, span->str_tags["db.couchbase.collection"]);
|
|
95
|
+
ASSERT_EQ("kv", span->str_tags["db.couchbase.service"]);
|
|
96
|
+
ASSERT_EQ(expectedName, span->str_tags["db.operation"]);
|
|
97
|
+
ASSERT_EQ("IP.TCP", span->str_tags["net.transport"]);
|
|
98
|
+
ASSERT_TRUE(span->str_tags.count("db.couchbase.operation_id") > 0);
|
|
99
|
+
ASSERT_TRUE(span->str_tags.count("db.couchbase.local_id") > 0);
|
|
100
|
+
ASSERT_TRUE(span->str_tags.count("net.host.name") > 0);
|
|
101
|
+
ASSERT_TRUE(span->str_tags.count("net.host.port") > 0);
|
|
102
|
+
ASSERT_TRUE(span->str_tags.count("net.peer.name") > 0);
|
|
103
|
+
ASSERT_TRUE(span->str_tags.count("net.peer.port") > 0);
|
|
104
|
+
ASSERT_TRUE(span->int_tags.count("db.couchbase.retries") > 0);
|
|
105
|
+
if (assertions.durability_level == LCB_DURABILITYLEVEL_NONE) {
|
|
106
|
+
ASSERT_TRUE(span->str_tags.count("db.couchbase.durability") == 0);
|
|
107
|
+
} else {
|
|
108
|
+
ASSERT_EQ(dur_level_to_string(assertions.durability_level), span->str_tags["db.couchbase.durability"]);
|
|
109
|
+
}
|
|
110
|
+
ASSERT_TRUE(span->finished);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
void MockUnitTest::assert_http_span(const std::shared_ptr<TestSpan> &span, const std::string &expectedName,
|
|
114
|
+
const HTTPSpanAssertions &assertions)
|
|
115
|
+
{
|
|
116
|
+
ASSERT_EQ(expectedName, span->name);
|
|
117
|
+
ASSERT_EQ("couchbase", span->str_tags["db.system"]);
|
|
118
|
+
if (!assertions.bucket.empty()) {
|
|
119
|
+
ASSERT_EQ(assertions.bucket, span->str_tags["db.name"]);
|
|
120
|
+
}
|
|
121
|
+
if (!assertions.scope.empty()) {
|
|
122
|
+
ASSERT_EQ(assertions.scope, span->str_tags["db.couchbase.scope"]);
|
|
123
|
+
}
|
|
124
|
+
if (!assertions.collection.empty()) {
|
|
125
|
+
ASSERT_EQ(assertions.collection, span->str_tags["db.couchbase.collection"]);
|
|
126
|
+
}
|
|
127
|
+
if (!assertions.service.empty()) {
|
|
128
|
+
ASSERT_EQ(assertions.service, span->str_tags["db.couchbase.service"]);
|
|
129
|
+
}
|
|
130
|
+
if (!assertions.op.empty()) {
|
|
131
|
+
ASSERT_EQ(assertions.op, span->str_tags["db.operation"]);
|
|
132
|
+
}
|
|
133
|
+
ASSERT_EQ("IP.TCP", span->str_tags["net.transport"]);
|
|
134
|
+
if (assertions.operation_id.empty()) {
|
|
135
|
+
ASSERT_TRUE(span->str_tags.find("db.couchbase.operation_id") == span->str_tags.end());
|
|
136
|
+
} else if (assertions.operation_id == "any") {
|
|
137
|
+
ASSERT_TRUE(span->str_tags.find("db.couchbase.operation_id") != span->str_tags.end());
|
|
138
|
+
} else {
|
|
139
|
+
ASSERT_EQ(assertions.operation_id, span->str_tags["db.couchbase.operation_id"]);
|
|
140
|
+
}
|
|
141
|
+
ASSERT_TRUE(span->str_tags.find("net.host.name") != span->str_tags.end());
|
|
142
|
+
ASSERT_TRUE(span->str_tags.find("net.host.port") != span->str_tags.end());
|
|
143
|
+
ASSERT_TRUE(span->str_tags.find("net.peer.name") != span->str_tags.end());
|
|
144
|
+
ASSERT_TRUE(span->str_tags.find("net.peer.port") != span->str_tags.end());
|
|
145
|
+
ASSERT_TRUE(span->int_tags.find("db.couchbase.retries") != span->int_tags.end());
|
|
146
|
+
if (!assertions.statement.empty()) {
|
|
147
|
+
ASSERT_EQ(assertions.statement, span->str_tags["db.statement"]);
|
|
148
|
+
}
|
|
149
|
+
ASSERT_TRUE(span->finished);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
void MockUnitTest::assert_kv_metrics(const std::string &metric_name, const std::string &op, uint32_t length,
|
|
153
|
+
bool at_least_len)
|
|
154
|
+
{
|
|
155
|
+
std::string key = metric_name + ":kv";
|
|
156
|
+
if (op != "") {
|
|
157
|
+
key = key + ":" + op;
|
|
158
|
+
}
|
|
159
|
+
assert_metrics(key, length, at_least_len);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
void MockUnitTest::assert_metrics(const std::string &key, uint32_t length, bool at_least_len)
|
|
163
|
+
{
|
|
164
|
+
auto meter = MockEnvironment::getInstance()->getMeter();
|
|
165
|
+
ASSERT_TRUE(meter.recorders.find(key) != meter.recorders.end());
|
|
166
|
+
if (at_least_len) {
|
|
167
|
+
ASSERT_TRUE(meter.recorders[key]->values.size() >= length);
|
|
168
|
+
} else {
|
|
169
|
+
ASSERT_TRUE(meter.recorders[key]->values.size() == length);
|
|
170
|
+
}
|
|
171
|
+
for (const auto value : meter.recorders[key]->values) {
|
|
172
|
+
ASSERT_NE(0, value);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
#include <gtest/gtest.h>
|
|
22
22
|
#include <libcouchbase/couchbase.h>
|
|
23
23
|
#include "mock-environment.h"
|
|
24
|
+
#include "testutil.h"
|
|
24
25
|
|
|
25
26
|
class HandleWrap;
|
|
26
27
|
|
|
@@ -44,6 +45,22 @@ class HandleWrap;
|
|
|
44
45
|
return; \
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
struct KVSpanAssertions {
|
|
49
|
+
lcb_DURABILITY_LEVEL durability_level{LCB_DURABILITYLEVEL_NONE};
|
|
50
|
+
std::string scope{"_default"};
|
|
51
|
+
std::string collection{"_default"};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
struct HTTPSpanAssertions {
|
|
55
|
+
std::string statement{};
|
|
56
|
+
std::string scope{};
|
|
57
|
+
std::string collection{};
|
|
58
|
+
std::string bucket{};
|
|
59
|
+
std::string op{};
|
|
60
|
+
std::string operation_id{};
|
|
61
|
+
std::string service{};
|
|
62
|
+
};
|
|
63
|
+
|
|
47
64
|
class MockUnitTest : public ::testing::Test
|
|
48
65
|
{
|
|
49
66
|
protected:
|
|
@@ -56,6 +73,13 @@ class MockUnitTest : public ::testing::Test
|
|
|
56
73
|
virtual void createClusterConnection(HandleWrap &handle, lcb_INSTANCE **instance);
|
|
57
74
|
virtual lcb_STATUS tryCreateConnection(HandleWrap &hw, lcb_INSTANCE **instance, lcb_CREATEOPTS *&crparams);
|
|
58
75
|
|
|
76
|
+
static void assert_kv_span(const std::shared_ptr<TestSpan> &span, const std::string &expectedName,
|
|
77
|
+
const KVSpanAssertions &assertions);
|
|
78
|
+
static void assert_http_span(const std::shared_ptr<TestSpan> &span, const std::string &expectedName,
|
|
79
|
+
const HTTPSpanAssertions &assertions);
|
|
80
|
+
void assert_kv_metrics(const std::string &metric_name, const std::string &op, uint32_t length, bool at_least_len);
|
|
81
|
+
void assert_metrics(const std::string &key, uint32_t length, bool at_least_len);
|
|
82
|
+
|
|
59
83
|
// A mock "Transaction"
|
|
60
84
|
void doMockTxn(MockCommand &cmd)
|
|
61
85
|
{
|
|
@@ -66,4 +90,12 @@ class MockUnitTest : public ::testing::Test
|
|
|
66
90
|
}
|
|
67
91
|
};
|
|
68
92
|
|
|
93
|
+
/*
|
|
94
|
+
* This test class groups tests that might be problematic when executed together with all other tests.
|
|
95
|
+
* Every test case in this suite must start with Jira ticket number for future.
|
|
96
|
+
*/
|
|
97
|
+
class ContaminatingUnitTest : public MockUnitTest
|
|
98
|
+
{
|
|
99
|
+
};
|
|
100
|
+
|
|
69
101
|
#endif
|
|
@@ -572,7 +572,7 @@ TEST_F(CollectionUnitTest, testDroppedScope)
|
|
|
572
572
|
*
|
|
573
573
|
* Collection creations are successful
|
|
574
574
|
*/
|
|
575
|
-
TEST_F(
|
|
575
|
+
TEST_F(ContaminatingUnitTest, test_CCBC_1483_MaxCollectionsPerScope)
|
|
576
576
|
{
|
|
577
577
|
SKIP_IF_MOCK()
|
|
578
578
|
SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_70)
|
|
@@ -24,6 +24,9 @@ struct evstop_listener : Listener {
|
|
|
24
24
|
|
|
25
25
|
void clconfig_lsn(EventType event, ConfigInfo *)
|
|
26
26
|
{
|
|
27
|
+
if (event == CLCONFIG_EVENT_PROVIDERS_CYCLED) {
|
|
28
|
+
return IOT_STOP(io);
|
|
29
|
+
}
|
|
27
30
|
if (event != CLCONFIG_EVENT_GOT_NEW_CONFIG) {
|
|
28
31
|
return;
|
|
29
32
|
}
|
|
@@ -40,7 +43,6 @@ static void listen_callback1(Listener *lsn, EventType event, ConfigInfo *info) {
|
|
|
40
43
|
|
|
41
44
|
TEST_F(ConfmonTest, testBasic)
|
|
42
45
|
{
|
|
43
|
-
SKIP_UNLESS_MOCK();
|
|
44
46
|
HandleWrap hw;
|
|
45
47
|
lcb_INSTANCE *instance;
|
|
46
48
|
MockEnvironment::getInstance()->createConnection(hw, &instance);
|
|
@@ -68,8 +70,8 @@ TEST_F(ConfmonTest, testBasic)
|
|
|
68
70
|
mon->start();
|
|
69
71
|
|
|
70
72
|
IOT_START(instance->iotable);
|
|
71
|
-
ASSERT_NE(0, listener.called);
|
|
72
73
|
delete mon;
|
|
74
|
+
ASSERT_NE(0, listener.called);
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
struct listener2 : Listener {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
#include "iotests.h"
|
|
22
22
|
#include "logging.h"
|
|
23
23
|
#include "internal.h"
|
|
24
|
+
#include "testutil.h"
|
|
24
25
|
|
|
25
26
|
#define LOGARGS(instance, lvl) instance->settings, "tests-GET", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
26
27
|
|
|
@@ -106,6 +107,9 @@ static void testGetHitGetCallback(lcb_INSTANCE *, lcb_CALLBACK_TYPE, const lcb_R
|
|
|
106
107
|
*/
|
|
107
108
|
TEST_F(GetUnitTest, testGetHit)
|
|
108
109
|
{
|
|
110
|
+
MockEnvironment *mock = MockEnvironment::getInstance();
|
|
111
|
+
tracing_guard use_tracing;
|
|
112
|
+
metrics_guard use_metrics;
|
|
109
113
|
HandleWrap hw;
|
|
110
114
|
lcb_INSTANCE *instance;
|
|
111
115
|
createConnection(hw, &instance);
|
|
@@ -129,6 +133,16 @@ TEST_F(GetUnitTest, testGetHit)
|
|
|
129
133
|
|
|
130
134
|
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
131
135
|
EXPECT_EQ(2, numcallbacks);
|
|
136
|
+
|
|
137
|
+
auto spans = mock->getTracer().spans;
|
|
138
|
+
ASSERT_EQ(4, spans.size());
|
|
139
|
+
auto span = spans[0];
|
|
140
|
+
assert_kv_span(span, "upsert", {});
|
|
141
|
+
span = spans[2];
|
|
142
|
+
assert_kv_span(span, "get", {});
|
|
143
|
+
|
|
144
|
+
assert_kv_metrics(METRICS_OPS_METER_NAME, "get", 2, false);
|
|
145
|
+
assert_kv_metrics(METRICS_OPS_METER_NAME, "upsert", 2, false);
|
|
132
146
|
}
|
|
133
147
|
|
|
134
148
|
extern "C" {
|
|
@@ -1097,10 +1111,6 @@ TEST_F(GetUnitTest, testChangePassword)
|
|
|
1097
1111
|
createConnection(hwHttp, &instanceHttp);
|
|
1098
1112
|
(void)lcb_install_callback(instanceHttp, LCB_CALLBACK_HTTP, (lcb_RESPCALLBACK)change_password_http_callback);
|
|
1099
1113
|
|
|
1100
|
-
// Set short timeout
|
|
1101
|
-
lcb_uint32_t tmoval = 100000;
|
|
1102
|
-
lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_OP_TIMEOUT, &tmoval);
|
|
1103
|
-
|
|
1104
1114
|
// store keys
|
|
1105
1115
|
// run one set to connect to only one node
|
|
1106
1116
|
// the goal is to change the password then try to connect others nodes
|
|
@@ -165,6 +165,8 @@ class QueryUnitTest : public MockUnitTest
|
|
|
165
165
|
|
|
166
166
|
TEST_F(QueryUnitTest, testSimple)
|
|
167
167
|
{
|
|
168
|
+
MockEnvironment *mock = MockEnvironment::getInstance();
|
|
169
|
+
tracing_guard use_tracing;
|
|
168
170
|
lcb_INSTANCE *instance;
|
|
169
171
|
HandleWrap hw;
|
|
170
172
|
if (!createQueryConnection(hw, &instance)) {
|
|
@@ -172,12 +174,26 @@ TEST_F(QueryUnitTest, testSimple)
|
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
N1QLResult res;
|
|
175
|
-
|
|
177
|
+
const char *query = "SELECT mockrow";
|
|
178
|
+
makeCommand(query);
|
|
179
|
+
|
|
180
|
+
const char *context_id = "context_id";
|
|
181
|
+
lcb_cmdquery_client_context_id(cmd, context_id, strlen(context_id));
|
|
182
|
+
|
|
176
183
|
lcb_STATUS rc = lcb_query(instance, &res, cmd);
|
|
177
184
|
ASSERT_STATUS_EQ(LCB_SUCCESS, rc);
|
|
178
185
|
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
179
186
|
ASSERT_STATUS_EQ(LCB_SUCCESS, res.rc);
|
|
180
187
|
ASSERT_EQ(1, res.rows.size());
|
|
188
|
+
|
|
189
|
+
auto spans = mock->getTracer().spans;
|
|
190
|
+
ASSERT_EQ(1, spans.size());
|
|
191
|
+
auto span = spans[0];
|
|
192
|
+
HTTPSpanAssertions assertions;
|
|
193
|
+
assertions.statement = query;
|
|
194
|
+
assertions.operation_id = context_id;
|
|
195
|
+
assertions.service = "query";
|
|
196
|
+
assert_http_span(span, "query", assertions);
|
|
181
197
|
}
|
|
182
198
|
|
|
183
199
|
TEST_F(QueryUnitTest, testQueryError)
|
|
@@ -316,6 +316,10 @@ static std::uint64_t get_manifest_id(lcb_INSTANCE *instance)
|
|
|
316
316
|
lcb_cmdgetmanifest_destroy(cmd);
|
|
317
317
|
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
318
318
|
|
|
319
|
+
if (result.rc == LCB_ERR_TIMEOUT) {
|
|
320
|
+
return 0;
|
|
321
|
+
}
|
|
322
|
+
|
|
319
323
|
Json::Value payload;
|
|
320
324
|
EXPECT_EQ(LCB_SUCCESS, result.rc);
|
|
321
325
|
EXPECT_FALSE(result.value.empty());
|
|
@@ -461,3 +465,167 @@ std::string unique_name(const std::string &prefix)
|
|
|
461
465
|
ss << prefix << lcb_next_rand32();
|
|
462
466
|
return ss.str();
|
|
463
467
|
}
|
|
468
|
+
|
|
469
|
+
void TestSpan::SetAttribute(std::string key, uint64_t value)
|
|
470
|
+
{
|
|
471
|
+
int_tags[std::move(key)] = value;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
void TestSpan::SetAttribute(std::string key, std::string value)
|
|
475
|
+
{
|
|
476
|
+
str_tags[std::move(key)] = std::move(value);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
void TestSpan::End()
|
|
480
|
+
{
|
|
481
|
+
finished = true;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
TestSpan::TestSpan(std::string span_name)
|
|
485
|
+
{
|
|
486
|
+
name = std::move(span_name);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
std::shared_ptr<TestSpan> TestTracer::StartSpan(std::string name)
|
|
490
|
+
{
|
|
491
|
+
auto t_span = std::make_shared<TestSpan>(name);
|
|
492
|
+
spans.push_back(t_span);
|
|
493
|
+
return t_span;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
void TestTracer::reset()
|
|
497
|
+
{
|
|
498
|
+
spans.clear();
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
static void *start_span(lcbtrace_TRACER *tracer, const char *name, void *parent)
|
|
502
|
+
{
|
|
503
|
+
auto test_tracer = static_cast<TestTracer *>(tracer->cookie);
|
|
504
|
+
if (!test_tracer->enabled()) {
|
|
505
|
+
return nullptr;
|
|
506
|
+
}
|
|
507
|
+
auto test_span = test_tracer->StartSpan(std::string(name));
|
|
508
|
+
return test_span.get();
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
static void end_span(void *span)
|
|
512
|
+
{
|
|
513
|
+
if (span == nullptr) {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
static_cast<TestSpan *>(span)->End();
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
static void add_tag_string(void *span, const char *name, const char *value, size_t value_len)
|
|
520
|
+
{
|
|
521
|
+
if (span == nullptr) {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
std::string val;
|
|
525
|
+
val.append(value, value_len);
|
|
526
|
+
static_cast<TestSpan *>(span)->SetAttribute(std::string(name), val);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
static void add_tag_uint64(void *span, const char *name, uint64_t value)
|
|
530
|
+
{
|
|
531
|
+
if (span == nullptr) {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
static_cast<TestSpan *>(span)->SetAttribute(name, value);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
void TestTracer::create_lcb_tracer()
|
|
538
|
+
{
|
|
539
|
+
lcbtracer_ = lcbtrace_new(nullptr, LCBTRACE_F_EXTERNAL);
|
|
540
|
+
lcbtracer_->version = 1;
|
|
541
|
+
lcbtracer_->v.v1.start_span = start_span;
|
|
542
|
+
lcbtracer_->v.v1.end_span = end_span;
|
|
543
|
+
lcbtracer_->v.v1.add_tag_string = add_tag_string;
|
|
544
|
+
lcbtracer_->v.v1.add_tag_uint64 = add_tag_uint64;
|
|
545
|
+
lcbtracer_->cookie = static_cast<void *>(this);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
void TestTracer::destroy_lcb_tracer()
|
|
549
|
+
{
|
|
550
|
+
if (lcbtracer_ != nullptr) {
|
|
551
|
+
lcbtrace_destroy(lcbtracer_);
|
|
552
|
+
delete lcbtracer_;
|
|
553
|
+
lcbtracer_ = nullptr;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
TestTracer::~TestTracer()
|
|
558
|
+
{
|
|
559
|
+
destroy_lcb_tracer();
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
TestMeter::TestMeter() = default;
|
|
563
|
+
|
|
564
|
+
void TestMeter::reset()
|
|
565
|
+
{
|
|
566
|
+
recorders.clear();
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
void TestValueRecorder::RecordValue(uint64_t value)
|
|
570
|
+
{
|
|
571
|
+
values.push_back(value);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
std::shared_ptr<TestValueRecorder> TestMeter::ValueRecorder(std::string name,
|
|
575
|
+
std::unordered_map<std::string, std::string> tags)
|
|
576
|
+
{
|
|
577
|
+
auto key = name + ":" + tags["db.couchbase.service"];
|
|
578
|
+
auto op = tags["db.operation"];
|
|
579
|
+
if (!op.empty()) {
|
|
580
|
+
key = key + ":" + op;
|
|
581
|
+
}
|
|
582
|
+
std::shared_ptr<TestValueRecorder> test_recorder;
|
|
583
|
+
if (recorders.find(key) == recorders.end()) {
|
|
584
|
+
test_recorder = std::make_shared<TestValueRecorder>();
|
|
585
|
+
recorders[key] = test_recorder;
|
|
586
|
+
} else {
|
|
587
|
+
test_recorder = recorders[key];
|
|
588
|
+
}
|
|
589
|
+
return test_recorder;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
static void record_callback(const lcbmetrics_VALUERECORDER *recorder, uint64_t value)
|
|
593
|
+
{
|
|
594
|
+
void *test_recorder;
|
|
595
|
+
lcbmetrics_valuerecorder_cookie(recorder, &test_recorder);
|
|
596
|
+
static_cast<TestValueRecorder *>(test_recorder)->RecordValue(value);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
static const lcbmetrics_VALUERECORDER *new_recorder(const lcbmetrics_METER *meter, const char *name,
|
|
600
|
+
const lcbmetrics_TAG *tags, size_t ntags)
|
|
601
|
+
{
|
|
602
|
+
std::unordered_map<std::string, std::string> recorder_tags;
|
|
603
|
+
for (int i = 0; i < ntags; i++) {
|
|
604
|
+
recorder_tags[tags[i].key] = tags[i].value;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
void *test_meter_;
|
|
608
|
+
lcbmetrics_meter_cookie(meter, &test_meter_);
|
|
609
|
+
auto test_meter = static_cast<TestMeter *>(test_meter_);
|
|
610
|
+
auto test_value_recorder = test_meter->ValueRecorder(std::string(name), recorder_tags);
|
|
611
|
+
|
|
612
|
+
lcbmetrics_VALUERECORDER *recorder;
|
|
613
|
+
lcbmetrics_valuerecorder_create(&recorder, test_value_recorder.get());
|
|
614
|
+
lcbmetrics_valuerecorder_record_value_callback(recorder, record_callback);
|
|
615
|
+
|
|
616
|
+
return recorder;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
void TestMeter::create_lcb_meter()
|
|
620
|
+
{
|
|
621
|
+
lcbmetrics_meter_create(&lcbmeter_, static_cast<void *>(this));
|
|
622
|
+
lcbmetrics_meter_value_recorder_callback(lcbmeter_, new_recorder);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
void TestMeter::destroy_lcb_meter()
|
|
626
|
+
{
|
|
627
|
+
if (lcbmeter_ != nullptr) {
|
|
628
|
+
lcbmetrics_meter_destroy(lcbmeter_);
|
|
629
|
+
lcbmeter_ = nullptr;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
#include <libcouchbase/couchbase.h>
|
|
21
21
|
#include <libcouchbase/vbucket.h>
|
|
22
22
|
#include <string>
|
|
23
|
+
#include <memory>
|
|
24
|
+
#include <unordered_map>
|
|
23
25
|
|
|
24
26
|
#define ASSERT_STATUS_EQ(expected, actual) \
|
|
25
27
|
lcb_STATUS GTEST_CONCAT_TOKEN_(actual_code__, __LINE__) = (actual); \
|
|
@@ -212,4 +214,113 @@ void drop_scope(lcb_INSTANCE *instance, const std::string &scope, bool wait = tr
|
|
|
212
214
|
void drop_collection(lcb_INSTANCE *instance, const std::string &scope, const std::string &collection, bool wait = true);
|
|
213
215
|
|
|
214
216
|
std::string unique_name(const std::string &);
|
|
217
|
+
|
|
218
|
+
class TestSpan
|
|
219
|
+
{
|
|
220
|
+
public:
|
|
221
|
+
explicit TestSpan(std::string name);
|
|
222
|
+
void SetAttribute(std::string key, std::string value);
|
|
223
|
+
void SetAttribute(std::string key, uint64_t value);
|
|
224
|
+
void End();
|
|
225
|
+
|
|
226
|
+
std::unordered_map<std::string, std::string> str_tags{};
|
|
227
|
+
std::unordered_map<std::string, uint64_t> int_tags{};
|
|
228
|
+
bool finished{false};
|
|
229
|
+
std::string name{};
|
|
230
|
+
|
|
231
|
+
TestSpan *parent{nullptr};
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
class TestTracer
|
|
235
|
+
{
|
|
236
|
+
public:
|
|
237
|
+
TestTracer() = default;
|
|
238
|
+
~TestTracer();
|
|
239
|
+
std::shared_ptr<TestSpan> StartSpan(std::string name);
|
|
240
|
+
|
|
241
|
+
std::vector<std::shared_ptr<TestSpan>> spans{};
|
|
242
|
+
|
|
243
|
+
void reset();
|
|
244
|
+
|
|
245
|
+
bool set_enabled(bool new_value)
|
|
246
|
+
{
|
|
247
|
+
bool old_value = enabled_;
|
|
248
|
+
enabled_ = new_value;
|
|
249
|
+
|
|
250
|
+
reset();
|
|
251
|
+
destroy_lcb_tracer();
|
|
252
|
+
if (new_value) {
|
|
253
|
+
create_lcb_tracer();
|
|
254
|
+
}
|
|
255
|
+
return old_value;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
bool enabled() const
|
|
259
|
+
{
|
|
260
|
+
return enabled_;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
lcbtrace_TRACER *lcb_tracer()
|
|
264
|
+
{
|
|
265
|
+
return lcbtracer_;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private:
|
|
269
|
+
void create_lcb_tracer();
|
|
270
|
+
void destroy_lcb_tracer();
|
|
271
|
+
|
|
272
|
+
lcbtrace_TRACER *lcbtracer_{nullptr};
|
|
273
|
+
bool enabled_{false};
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
class TestValueRecorder
|
|
277
|
+
{
|
|
278
|
+
public:
|
|
279
|
+
TestValueRecorder() = default;
|
|
280
|
+
void RecordValue(uint64_t value);
|
|
281
|
+
|
|
282
|
+
std::vector<uint64_t> values{};
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
class TestMeter
|
|
286
|
+
{
|
|
287
|
+
public:
|
|
288
|
+
TestMeter();
|
|
289
|
+
void reset();
|
|
290
|
+
std::shared_ptr<TestValueRecorder> ValueRecorder(std::string name,
|
|
291
|
+
std::unordered_map<std::string, std::string> tags);
|
|
292
|
+
|
|
293
|
+
std::unordered_map<std::string, std::shared_ptr<TestValueRecorder>> recorders{};
|
|
294
|
+
|
|
295
|
+
bool set_enabled(bool new_value)
|
|
296
|
+
{
|
|
297
|
+
bool old_value = enabled_;
|
|
298
|
+
enabled_ = new_value;
|
|
299
|
+
|
|
300
|
+
reset();
|
|
301
|
+
destroy_lcb_meter();
|
|
302
|
+
if (new_value) {
|
|
303
|
+
create_lcb_meter();
|
|
304
|
+
}
|
|
305
|
+
return old_value;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
bool enabled() const
|
|
309
|
+
{
|
|
310
|
+
return enabled_;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
lcbmetrics_METER *lcb_meter()
|
|
314
|
+
{
|
|
315
|
+
return lcbmeter_;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
private:
|
|
319
|
+
void create_lcb_meter();
|
|
320
|
+
void destroy_lcb_meter();
|
|
321
|
+
|
|
322
|
+
lcbmetrics_METER *lcbmeter_{nullptr};
|
|
323
|
+
bool enabled_{false};
|
|
324
|
+
};
|
|
325
|
+
|
|
215
326
|
#endif
|