libcouchbase 1.2.8 → 1.3.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.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -4
  3. data/README.md +16 -8
  4. data/ext/libcouchbase/CMakeLists.txt +34 -32
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +277 -6
  6. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +14 -0
  7. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +2 -0
  8. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +2 -1
  9. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
  10. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +8 -1
  11. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  12. data/ext/libcouchbase/cmake/config-cmake.h.in +14 -0
  13. data/ext/libcouchbase/cmake/configure +8 -26
  14. data/ext/libcouchbase/cmake/defs.mk.in +2 -2
  15. data/ext/libcouchbase/cmake/libcouchbase.stp.in +829 -0
  16. data/ext/libcouchbase/cmake/source_files.cmake +11 -2
  17. data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +18 -2
  18. data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +44 -2
  19. data/ext/libcouchbase/contrib/cbsasl/src/client.c +285 -73
  20. data/ext/libcouchbase/contrib/cbsasl/src/common.c +4 -0
  21. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.c +500 -0
  22. data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.h +99 -0
  23. data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +1 -1
  24. data/ext/libcouchbase/contrib/cliopts/cliopts.h +14 -1
  25. data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +2 -3
  26. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +4 -0
  27. data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +7 -5
  28. data/ext/libcouchbase/contrib/snappy/snappy.cc +7 -2
  29. data/ext/libcouchbase/example/crypto/.gitignore +2 -0
  30. data/ext/libcouchbase/example/crypto/Makefile +13 -0
  31. data/ext/libcouchbase/example/crypto/common_provider.c +24 -0
  32. data/ext/libcouchbase/example/crypto/common_provider.h +31 -0
  33. data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +139 -0
  34. data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +147 -0
  35. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +281 -0
  36. data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.h +29 -0
  37. data/ext/libcouchbase/example/tracing/.gitignore +2 -0
  38. data/ext/libcouchbase/example/tracing/Makefile +8 -0
  39. data/ext/libcouchbase/example/tracing/cJSON.c +1 -0
  40. data/ext/libcouchbase/example/tracing/cJSON.h +1 -0
  41. data/ext/libcouchbase/example/tracing/tracing.c +439 -0
  42. data/ext/libcouchbase/example/tracing/views.c +444 -0
  43. data/ext/libcouchbase/include/libcouchbase/auth.h +56 -4
  44. data/ext/libcouchbase/include/libcouchbase/cbft.h +8 -0
  45. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +55 -1
  46. data/ext/libcouchbase/include/libcouchbase/cntl.h +101 -1
  47. data/ext/libcouchbase/include/libcouchbase/configuration.h.in +6 -0
  48. data/ext/libcouchbase/include/libcouchbase/couchbase.h +109 -6
  49. data/ext/libcouchbase/include/libcouchbase/crypto.h +140 -0
  50. data/ext/libcouchbase/include/libcouchbase/error.h +38 -2
  51. data/ext/libcouchbase/include/libcouchbase/kvbuf.h +6 -1
  52. data/ext/libcouchbase/include/libcouchbase/metrics.h +79 -0
  53. data/ext/libcouchbase/include/libcouchbase/n1ql.h +9 -0
  54. data/ext/libcouchbase/include/libcouchbase/tracing.h +319 -0
  55. data/ext/libcouchbase/include/libcouchbase/vbucket.h +1 -1
  56. data/ext/libcouchbase/include/libcouchbase/views.h +8 -0
  57. data/ext/libcouchbase/include/memcached/protocol_binary.h +40 -10
  58. data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +6 -14
  59. data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +3 -0
  60. data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +1 -0
  61. data/ext/libcouchbase/plugins/io/select/plugin-select.c +4 -1
  62. data/ext/libcouchbase/src/auth-priv.h +36 -4
  63. data/ext/libcouchbase/src/auth.cc +66 -27
  64. data/ext/libcouchbase/src/bootstrap.cc +1 -1
  65. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +12 -7
  66. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +26 -17
  67. data/ext/libcouchbase/src/bucketconfig/bc_http.h +1 -1
  68. data/ext/libcouchbase/src/bucketconfig/clconfig.h +4 -2
  69. data/ext/libcouchbase/src/bucketconfig/confmon.cc +6 -3
  70. data/ext/libcouchbase/src/cbft.cc +48 -0
  71. data/ext/libcouchbase/src/cntl.cc +138 -2
  72. data/ext/libcouchbase/src/config_static.h +17 -0
  73. data/ext/libcouchbase/src/connspec.cc +54 -6
  74. data/ext/libcouchbase/src/connspec.h +9 -1
  75. data/ext/libcouchbase/src/crypto.cc +386 -0
  76. data/ext/libcouchbase/src/ctx-log-inl.h +23 -6
  77. data/ext/libcouchbase/src/dump.cc +4 -0
  78. data/ext/libcouchbase/src/getconfig.cc +1 -2
  79. data/ext/libcouchbase/src/handler.cc +65 -27
  80. data/ext/libcouchbase/src/hostlist.cc +35 -7
  81. data/ext/libcouchbase/src/hostlist.h +7 -0
  82. data/ext/libcouchbase/src/http/http-priv.h +2 -0
  83. data/ext/libcouchbase/src/http/http.cc +77 -37
  84. data/ext/libcouchbase/src/http/http_io.cc +19 -2
  85. data/ext/libcouchbase/src/instance.cc +90 -17
  86. data/ext/libcouchbase/src/internal.h +5 -0
  87. data/ext/libcouchbase/src/lcbio/connect.cc +39 -4
  88. data/ext/libcouchbase/src/lcbio/connect.h +27 -0
  89. data/ext/libcouchbase/src/lcbio/ctx.c +49 -23
  90. data/ext/libcouchbase/src/lcbio/ioutils.cc +30 -3
  91. data/ext/libcouchbase/src/lcbio/ioutils.h +2 -0
  92. data/ext/libcouchbase/src/lcbio/manager.cc +44 -8
  93. data/ext/libcouchbase/src/lcbio/manager.h +2 -0
  94. data/ext/libcouchbase/src/lcbio/rw-inl.h +1 -0
  95. data/ext/libcouchbase/src/lcbio/ssl.h +3 -5
  96. data/ext/libcouchbase/src/logging.c +1 -1
  97. data/ext/libcouchbase/src/logging.h +2 -0
  98. data/ext/libcouchbase/src/mc/compress.cc +164 -0
  99. data/ext/libcouchbase/src/mc/compress.h +7 -12
  100. data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +5 -1
  101. data/ext/libcouchbase/src/mc/mcreq.c +11 -1
  102. data/ext/libcouchbase/src/mc/mcreq.h +35 -4
  103. data/ext/libcouchbase/src/mcserver/mcserver.cc +30 -7
  104. data/ext/libcouchbase/src/mcserver/mcserver.h +7 -0
  105. data/ext/libcouchbase/src/mcserver/negotiate.cc +103 -57
  106. data/ext/libcouchbase/src/mcserver/negotiate.h +2 -2
  107. data/ext/libcouchbase/src/mctx-helper.h +11 -0
  108. data/ext/libcouchbase/src/metrics.cc +132 -0
  109. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
  110. data/ext/libcouchbase/src/n1ql/n1ql.cc +66 -0
  111. data/ext/libcouchbase/src/newconfig.cc +9 -2
  112. data/ext/libcouchbase/src/operations/counter.cc +2 -1
  113. data/ext/libcouchbase/src/operations/durability-cas.cc +11 -0
  114. data/ext/libcouchbase/src/operations/durability-seqno.cc +3 -0
  115. data/ext/libcouchbase/src/operations/durability.cc +24 -2
  116. data/ext/libcouchbase/src/operations/durability_internal.h +19 -0
  117. data/ext/libcouchbase/src/operations/get.cc +4 -2
  118. data/ext/libcouchbase/src/operations/observe-seqno.cc +1 -0
  119. data/ext/libcouchbase/src/operations/observe.cc +113 -62
  120. data/ext/libcouchbase/src/operations/ping.cc +246 -67
  121. data/ext/libcouchbase/src/operations/remove.cc +2 -1
  122. data/ext/libcouchbase/src/operations/store.cc +17 -14
  123. data/ext/libcouchbase/src/operations/touch.cc +3 -0
  124. data/ext/libcouchbase/src/packetutils.h +68 -4
  125. data/ext/libcouchbase/src/probes.d +132 -161
  126. data/ext/libcouchbase/src/rdb/bigalloc.c +1 -1
  127. data/ext/libcouchbase/src/retryq.cc +6 -2
  128. data/ext/libcouchbase/src/rnd.cc +68 -0
  129. data/ext/libcouchbase/src/rnd.h +39 -0
  130. data/ext/libcouchbase/src/settings.c +27 -0
  131. data/ext/libcouchbase/src/settings.h +67 -3
  132. data/ext/libcouchbase/src/ssl/CMakeLists.txt +0 -12
  133. data/ext/libcouchbase/src/ssl/ssl_common.c +23 -4
  134. data/ext/libcouchbase/src/strcodecs/base64.c +141 -16
  135. data/ext/libcouchbase/src/strcodecs/strcodecs.h +16 -1
  136. data/ext/libcouchbase/src/trace.h +68 -61
  137. data/ext/libcouchbase/src/tracing/span.cc +289 -0
  138. data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +171 -0
  139. data/ext/libcouchbase/src/tracing/tracer.cc +53 -0
  140. data/ext/libcouchbase/src/tracing/tracing-internal.h +213 -0
  141. data/ext/libcouchbase/src/utilities.c +5 -0
  142. data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -2
  143. data/ext/libcouchbase/src/vbucket/vbucket.c +50 -18
  144. data/ext/libcouchbase/src/views/docreq.cc +26 -1
  145. data/ext/libcouchbase/src/views/docreq.h +17 -0
  146. data/ext/libcouchbase/src/views/viewreq.cc +64 -1
  147. data/ext/libcouchbase/src/views/viewreq.h +21 -0
  148. data/ext/libcouchbase/tests/CMakeLists.txt +6 -6
  149. data/ext/libcouchbase/tests/basic/t_base64.cc +34 -6
  150. data/ext/libcouchbase/tests/basic/t_connstr.cc +14 -0
  151. data/ext/libcouchbase/tests/basic/t_creds.cc +10 -10
  152. data/ext/libcouchbase/tests/basic/t_host.cc +22 -2
  153. data/ext/libcouchbase/tests/basic/t_scram.cc +514 -0
  154. data/ext/libcouchbase/tests/check-all.cc +6 -2
  155. data/ext/libcouchbase/tests/iotests/mock-environment.cc +64 -0
  156. data/ext/libcouchbase/tests/iotests/mock-environment.h +27 -1
  157. data/ext/libcouchbase/tests/iotests/t_confmon.cc +2 -2
  158. data/ext/libcouchbase/tests/iotests/t_forward.cc +8 -0
  159. data/ext/libcouchbase/tests/iotests/t_netfail.cc +124 -0
  160. data/ext/libcouchbase/tests/iotests/t_smoke.cc +1 -1
  161. data/ext/libcouchbase/tests/iotests/t_snappy.cc +316 -0
  162. data/ext/libcouchbase/tests/socktests/socktest.cc +2 -2
  163. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  164. data/ext/libcouchbase/tests/socktests/t_manager.cc +1 -1
  165. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  166. data/ext/libcouchbase/tools/CMakeLists.txt +1 -1
  167. data/ext/libcouchbase/tools/cbc-handlers.h +17 -0
  168. data/ext/libcouchbase/tools/cbc-n1qlback.cc +7 -4
  169. data/ext/libcouchbase/tools/cbc-pillowfight.cc +408 -100
  170. data/ext/libcouchbase/tools/cbc-proxy.cc +134 -3
  171. data/ext/libcouchbase/tools/cbc-subdoc.cc +1 -2
  172. data/ext/libcouchbase/tools/cbc.cc +113 -8
  173. data/ext/libcouchbase/tools/common/histogram.cc +1 -0
  174. data/ext/libcouchbase/tools/common/options.cc +28 -1
  175. data/ext/libcouchbase/tools/common/options.h +5 -0
  176. data/ext/libcouchbase/tools/docgen/docgen.h +36 -10
  177. data/ext/libcouchbase/tools/docgen/loc.h +5 -4
  178. data/ext/libcouchbase/tools/docgen/seqgen.h +28 -0
  179. data/lib/libcouchbase/ext/libcouchbase/enums.rb +10 -0
  180. data/lib/libcouchbase/n1ql.rb +6 -1
  181. data/lib/libcouchbase/version.rb +1 -1
  182. data/spec/connection_spec.rb +6 -6
  183. metadata +38 -5
  184. data/ext/libcouchbase/cmake/Modules/FindCouchbaseSnappy.cmake +0 -11
  185. data/ext/libcouchbase/src/mc/compress.c +0 -90
  186. data/ext/libcouchbase/tools/common/my_inttypes.h +0 -22
@@ -404,7 +404,7 @@ static void setLinkerEnvironment(std::string &path)
404
404
  newenv += ":";
405
405
  }
406
406
  newenv += path;
407
- fprintf(stderr, "%s=%s\n", varname, newenv.c_str());
407
+ fprintf(stderr, "export %s=%s\n", varname, newenv.c_str());
408
408
  setenv(varname, newenv.c_str(), 1);
409
409
  }
410
410
 
@@ -562,6 +562,7 @@ static bool runSingleCycle(TestConfiguration &config)
562
562
  iterbins++) {
563
563
 
564
564
  std::string cmdline = config.setupCommandline(*iterbins);
565
+ fprintf(stderr, "Command line '%s'\n", cmdline.c_str());
565
566
  scheduler.schedule(Process(*iter, *iterbins, cmdline, config));
566
567
  }
567
568
 
@@ -584,19 +585,22 @@ int main(int argc, char **argv)
584
585
 
585
586
  // Set the environment for 'srcdir'
586
587
  std::stringstream ss;
587
- fprintf(stderr, "%s=%s\n", LCB_SRCROOT_ENV_VAR, config.srcroot.c_str());
588
+ fprintf(stderr, "export %s=%s\n", LCB_SRCROOT_ENV_VAR, config.srcroot.c_str());
588
589
  setenv(LCB_SRCROOT_ENV_VAR, config.srcroot.c_str(), 1);
590
+ fprintf(stderr, "export LCB_VERBOSE_TESTS=1\n");
589
591
  setenv("LCB_VERBOSE_TESTS", "1", 1);
590
592
 
591
593
  char loglevel_s[4096] = { 0 };
592
594
  if (config.getVerbosityLevel() > 0) {
593
595
  sprintf(loglevel_s, "%d", config.getVerbosityLevel());
594
596
  setenv("LCB_LOGLEVEL", loglevel_s, 0);
597
+ fprintf(stderr, "export LCB_LOGLEVEL=%s\n", loglevel_s);
595
598
  }
596
599
 
597
600
  if (!config.realClusterEnv.empty()) {
598
601
  // format the string
599
602
  setenv("LCB_TEST_CLUSTER_CONF", config.realClusterEnv.c_str(), 0);
603
+ fprintf(stderr, "export LCB_TEST_CLUSTER_CONF=%s\n", config.realClusterEnv.c_str());
600
604
  }
601
605
 
602
606
  for (int ii = 0; ii < config.maxCycles; ii++) {
@@ -122,6 +122,35 @@ std::vector<int> MockEnvironment::getMcPorts(std::string bucket)
122
122
  return ret;
123
123
  }
124
124
 
125
+ void MockEnvironment::setSaslMechs(std::vector<std::string>& mechanisms, std::string bucket,
126
+ const std::vector<int>* nodes)
127
+ {
128
+ MockCommand cmd(MockCommand::SET_SASL_MECHANISMS);
129
+ Json::Value mechs(Json::arrayValue);
130
+ for (std::vector<std::string>::const_iterator ii = mechanisms.begin(); ii != mechanisms.end(); ii++) {
131
+ mechs.append(*ii);
132
+ }
133
+ cmd.set("mechs", mechs);
134
+
135
+ if (!bucket.empty()) {
136
+ cmd.set("bucket", bucket);
137
+ }
138
+
139
+ if (nodes != NULL) {
140
+ const std::vector<int>& v = *nodes;
141
+ Json::Value array(Json::arrayValue);
142
+
143
+ for (std::vector<int>::const_iterator ii = v.begin(); ii != v.end(); ii++) {
144
+ array.append(*ii);
145
+ }
146
+
147
+ cmd.set("servers", array);
148
+ }
149
+
150
+ sendCommand(cmd);
151
+ getResponse();
152
+ }
153
+
125
154
  void MockEnvironment::setCCCP(bool enabled, std::string bucket,
126
155
  const std::vector<int>* nodes)
127
156
  {
@@ -172,6 +201,41 @@ void MockEnvironment::setEnhancedErrors(bool enabled, std::string bucket,
172
201
  getResponse();
173
202
  }
174
203
 
204
+ void MockEnvironment::setCompression(std::string mode, std::string bucket,
205
+ const std::vector<int>* nodes)
206
+ {
207
+ MockCommand cmd(MockCommand::SET_COMPRESSION);
208
+ cmd.set("mode", mode);
209
+
210
+ if (!bucket.empty()) {
211
+ cmd.set("bucket", bucket);
212
+ }
213
+
214
+ if (nodes != NULL) {
215
+ const std::vector<int>& v = *nodes;
216
+ Json::Value array(Json::arrayValue);
217
+
218
+ for (std::vector<int>::const_iterator ii = v.begin(); ii != v.end(); ii++) {
219
+ array.append(*ii);
220
+ }
221
+
222
+ cmd.set("servers", array);
223
+ }
224
+
225
+ sendCommand(cmd);
226
+ getResponse();
227
+ }
228
+
229
+ const Json::Value MockEnvironment::getKeyInfo(std::string key, std::string bucket)
230
+ {
231
+ MockKeyCommand cmd(MockCommand::KEYINFO, key);
232
+ cmd.bucket = bucket;
233
+ sendCommand(cmd);
234
+ MockResponse resp;
235
+ getResponse(resp);
236
+ return resp.constResp()["payload"];
237
+ }
238
+
175
239
  void MockEnvironment::sendCommand(MockCommand &cmd)
176
240
  {
177
241
  std::string s = cmd.encode();
@@ -75,7 +75,9 @@ class MockCommand
75
75
  X(OPFAIL) \
76
76
  X(START_RETRY_VERIFY) \
77
77
  X(CHECK_RETRY_VERIFY) \
78
- X(SET_ENHANCED_ERRORS)
78
+ X(SET_ENHANCED_ERRORS) \
79
+ X(SET_COMPRESSION) \
80
+ X(SET_SASL_MECHANISMS)
79
81
 
80
82
  public:
81
83
  enum Code {
@@ -305,6 +307,16 @@ public:
305
307
  */
306
308
  std::vector<int> getMcPorts(std::string bucket = "default");
307
309
 
310
+ /**
311
+ * Enable SASL mechanisms on the mock cluster
312
+ * @param mechanisms list of mechanisms to enable
313
+ * @param bucket the bucket on which to enable these mechanisms
314
+ * @param nodes a list of by-index nodes on which to enable mechanisms. If NULL
315
+ * then all nodes are enabled
316
+ */
317
+ void setSaslMechs(std::vector<std::string>& mechanisms, std::string bucket = "",
318
+ const std::vector<int>* nodes = NULL);
319
+
308
320
  /**
309
321
  * Enable CCCP on the mock cluster
310
322
  * @param bucket the bucket on which to enable CCCP
@@ -329,6 +341,20 @@ public:
329
341
  std::string bucket = "",
330
342
  const std::vector<int>* nodes = NULL);
331
343
 
344
+ /**
345
+ * Change compression mode on the server
346
+ *
347
+ * @param mode compression mode ("off", "passive", "active")
348
+ * @param bucket the bucket on which to enable compression
349
+ * @param nodes a list of by-index nodes on which to enable compression. If NULL
350
+ * then all nodes are enabled
351
+ */
352
+ void setCompression(std::string mode,
353
+ std::string bucket = "",
354
+ const std::vector<int>* nodes = NULL);
355
+
356
+ const Json::Value getKeyInfo(std::string key, std::string bucket = "");
357
+
332
358
  /**
333
359
  * Create a connection to the mock/real server.
334
360
  *
@@ -46,7 +46,7 @@ TEST_F(ConfmonTest, testBasic)
46
46
  MockEnvironment::getInstance()->createConnection(hw, instance);
47
47
 
48
48
 
49
- Confmon *mon = new Confmon(instance->settings, instance->iotable);
49
+ Confmon *mon = new Confmon(instance->settings, instance->iotable, instance);
50
50
  Provider *http = mon->get_provider(CLCONFIG_HTTP);
51
51
  http->enable();
52
52
  http->configure_nodes(*instance->ht_nodes);
@@ -130,7 +130,7 @@ TEST_F(ConfmonTest, testCycle)
130
130
  instance->settings->bc_http_stream_time = 100000;
131
131
  instance->memd_sockpool->get_options().tmoidle = 100000;
132
132
 
133
- Confmon *mon = new Confmon(instance->settings, instance->iotable);
133
+ Confmon *mon = new Confmon(instance->settings, instance->iotable, instance);
134
134
 
135
135
  struct listener2 lsn;
136
136
  lsn.io = instance->iotable;
@@ -8,6 +8,14 @@ using namespace PacketMaker;
8
8
 
9
9
  class ForwardTests : public MockUnitTest
10
10
  {
11
+ protected:
12
+ virtual void createConnection(HandleWrap& hw, lcb_t& instance) {
13
+ MockEnvironment::getInstance()->createConnection(hw, instance);
14
+ lcb_cntl_string(instance, "enable_tracing", "off");
15
+ ASSERT_EQ(LCB_SUCCESS, lcb_connect(instance));
16
+ lcb_wait(instance);
17
+ ASSERT_EQ(LCB_SUCCESS, lcb_get_bootstrap_status(instance));
18
+ }
11
19
  };
12
20
 
13
21
  struct ForwardCookie {
@@ -537,6 +537,130 @@ TEST_F(MockUnitTest, testSaslMechs)
537
537
  lcb_destroy(instance);
538
538
  }
539
539
 
540
+ TEST_F(MockUnitTest, testSaslSHA)
541
+ {
542
+ // Ensure our SASL mech listing works.
543
+ SKIP_UNLESS_MOCK();
544
+
545
+ const char *argv[] = { "--buckets", "protected:secret:couchbase", NULL };
546
+
547
+ lcb_t instance = NULL;
548
+ lcb_error_t err;
549
+ struct lcb_create_st crParams;
550
+ MockEnvironment mock_o(argv, "protected"), *protectedEnv = &mock_o;
551
+ protectedEnv->makeConnectParams(crParams, NULL);
552
+ protectedEnv->setCCCP(false);
553
+
554
+ crParams.v.v2.user = "protected";
555
+ crParams.v.v2.passwd = "secret";
556
+ crParams.v.v2.bucket = "protected";
557
+ crParams.v.v2.mchosts = NULL;
558
+
559
+ {
560
+ doLcbCreate(&instance, &crParams, protectedEnv);
561
+
562
+ // Make the socket pool disallow idle connections
563
+ instance->memd_sockpool->get_options().maxidle = 0;
564
+
565
+ ASSERT_EQ(LCB_SUCCESS, lcb_connect(instance));
566
+ ASSERT_EQ(LCB_SUCCESS, lcb_wait(instance));
567
+
568
+ err = lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_FORCE_SASL_MECH, (void *)"SCRAM-SHA512");
569
+ ASSERT_EQ(LCB_SUCCESS, err);
570
+
571
+ Item itm("key", "value");
572
+ KVOperation kvo(&itm);
573
+
574
+ kvo.allowableErrors.insert(LCB_SASLMECH_UNAVAILABLE);
575
+ kvo.allowableErrors.insert(LCB_ETIMEDOUT);
576
+ kvo.store(instance);
577
+
578
+ ASSERT_FALSE(kvo.globalErrors.find(LCB_SASLMECH_UNAVAILABLE) == kvo.globalErrors.end());
579
+
580
+ lcb_destroy(instance);
581
+ }
582
+
583
+ std::vector<std::string> mechs;
584
+ mechs.push_back("SCRAM-SHA512");
585
+ protectedEnv->setSaslMechs(mechs);
586
+
587
+ {
588
+ instance = NULL;
589
+ doLcbCreate(&instance, &crParams, protectedEnv);
590
+
591
+ // Make the socket pool disallow idle connections
592
+ instance->memd_sockpool->get_options().maxidle = 0;
593
+
594
+ ASSERT_EQ(LCB_SUCCESS, lcb_connect(instance));
595
+ ASSERT_EQ(LCB_SUCCESS, lcb_wait(instance));
596
+
597
+ Item itm("key", "value");
598
+ KVOperation kvo(&itm);
599
+
600
+ kvo.allowableErrors.insert(LCB_SASLMECH_UNAVAILABLE);
601
+ kvo.allowableErrors.insert(LCB_ETIMEDOUT);
602
+ kvo.store(instance);
603
+
604
+ #ifndef LCB_NO_SSL
605
+ err = lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_FORCE_SASL_MECH, (void *)"SCRAM-SHA512");
606
+ ASSERT_EQ(LCB_SUCCESS, err);
607
+
608
+ kvo.clear();
609
+ kvo.store(instance);
610
+ #endif
611
+
612
+ lcb_destroy(instance);
613
+ }
614
+ }
615
+
616
+
617
+ extern "C" {
618
+ static const char *get_username(void *cookie, const char *host, const char *port, const char *bucket)
619
+ {
620
+ return bucket;
621
+ }
622
+
623
+ static const char *get_password(void *cookie, const char *host, const char *port, const char *bucket)
624
+ {
625
+ std::map< std::string, std::string > *credentials = static_cast< std::map< std::string, std::string > * >(cookie);
626
+ return (*credentials)[bucket].c_str();
627
+ }
628
+ }
629
+
630
+ TEST_F(MockUnitTest, testDynamicAuth)
631
+ {
632
+ SKIP_UNLESS_MOCK();
633
+
634
+ const char *argv[] = {"--buckets", "protected:secret:couchbase", NULL};
635
+
636
+ lcb_t instance;
637
+ lcb_error_t err;
638
+ struct lcb_create_st crParams;
639
+ MockEnvironment mock_o(argv, "protected"), *mock = &mock_o;
640
+ mock->makeConnectParams(crParams, NULL);
641
+ mock->setCCCP(false);
642
+
643
+ crParams.v.v0.bucket = "protected";
644
+ doLcbCreate(&instance, &crParams, mock);
645
+
646
+ std::map< std::string, std::string > credentials;
647
+ credentials["protected"] = "secret";
648
+ lcb_AUTHENTICATOR *auth = lcbauth_new();
649
+ lcbauth_set_callbacks(auth, &credentials, get_username, get_password);
650
+ lcbauth_set_mode(auth, LCBAUTH_MODE_DYNAMIC);
651
+ lcb_set_auth(instance, auth);
652
+
653
+ err = lcb_connect(instance);
654
+ ASSERT_EQ(LCB_SUCCESS, err);
655
+ ASSERT_EQ(LCB_SUCCESS, lcb_wait(instance));
656
+
657
+ Item itm("key", "value");
658
+ KVOperation kvo(&itm);
659
+ kvo.store(instance);
660
+ lcb_destroy(instance);
661
+ lcbauth_unref(auth);
662
+ }
663
+
540
664
  static void
541
665
  doManyItems(lcb_t instance, std::vector<std::string> keys)
542
666
  {
@@ -497,7 +497,7 @@ TEST_F(SmokeTest, testMemcachedBucket)
497
497
  TEST_F(SmokeTest, testCouchbaseBucket)
498
498
  {
499
499
  SKIP_UNLESS_MOCK();
500
- const char *args[] = { "--buckets", "default::couchbase", NULL };
500
+ const char *args[] = { "--buckets", "default::couchbase", "--debug", NULL };
501
501
  mock = new MockEnvironment(args);
502
502
  mock->setCCCP(false);
503
503
  connectCommon();
@@ -0,0 +1,316 @@
1
+ #include "config.h"
2
+ #include "iotests.h"
3
+ #include "internal.h"
4
+
5
+ class SnappyUnitTest : public MockUnitTest
6
+ {
7
+ protected:
8
+ void setCompression(std::string mode)
9
+ {
10
+ MockEnvironment::getInstance()->setCompression(mode);
11
+ }
12
+
13
+ bool isCompressed(std::string &key)
14
+ {
15
+ const Json::Value info = MockEnvironment::getInstance()->getKeyInfo(key);
16
+ for (Json::Value::const_iterator ii = info.begin(); ii != info.end(); ii++) {
17
+ const Json::Value &node = *ii;
18
+ if (node.isNull()) {
19
+ continue;
20
+ }
21
+ if (node["Conf"]["Type"] == "master") {
22
+ return node["Cache"]["Snappy"].asBool();
23
+ }
24
+ }
25
+ return false;
26
+ }
27
+ };
28
+
29
+ struct SnappyCookie {
30
+ lcb_error_t rc;
31
+ bool called;
32
+ std::string value;
33
+
34
+ void reset()
35
+ {
36
+ rc = LCB_SUCCESS;
37
+ called = false;
38
+ }
39
+ SnappyCookie() : rc(LCB_SUCCESS), called(false) {}
40
+
41
+ ~SnappyCookie() {}
42
+ };
43
+
44
+ extern "C" {
45
+ static void storecb(lcb_t, int, const lcb_RESPBASE *rb)
46
+ {
47
+ SnappyCookie *cookie = reinterpret_cast< SnappyCookie * >(rb->cookie);
48
+ cookie->called = true;
49
+ cookie->rc = rb->rc;
50
+ }
51
+ static void getcb(lcb_t, int, const lcb_RESPBASE *rb)
52
+ {
53
+ SnappyCookie *cookie = reinterpret_cast< SnappyCookie * >(rb->cookie);
54
+ cookie->called = true;
55
+ cookie->rc = rb->rc;
56
+ const lcb_RESPGET *resp = reinterpret_cast< const lcb_RESPGET * >(rb);
57
+ cookie->value.assign((char *)resp->value, resp->nvalue);
58
+ }
59
+ }
60
+
61
+ TEST_F(SnappyUnitTest, testSpec)
62
+ {
63
+ SKIP_UNLESS_MOCK();
64
+ HandleWrap hw;
65
+ lcb_t instance;
66
+
67
+ setCompression("passive");
68
+ createConnection(hw, instance);
69
+ lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_INOUT);
70
+ lcb_install_callback3(instance, LCB_CALLBACK_GET, getcb);
71
+ lcb_install_callback3(instance, LCB_CALLBACK_STORE, storecb);
72
+
73
+ std::string key("hello");
74
+ std::string value("A big black bug bit a big black bear, made the big black bear bleed blood");
75
+ std::string compressed("IPA big black bug bit a.\x14");
76
+
77
+ SnappyCookie cookie;
78
+ lcb_CMDSTORE scmd;
79
+ lcb_CMDGET gcmd;
80
+
81
+ scmd = lcb_CMDSTORE();
82
+ scmd.operation = LCB_UPSERT;
83
+ LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
84
+ LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
85
+ cookie = SnappyCookie();
86
+ lcb_store3(instance, &cookie, &scmd);
87
+ lcb_wait(instance);
88
+ ASSERT_TRUE(cookie.called);
89
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
90
+ /* now we have negotiated snappy feature */
91
+ cookie = SnappyCookie();
92
+ lcb_store3(instance, &cookie, &scmd);
93
+ lcb_wait(instance);
94
+ ASSERT_TRUE(cookie.called);
95
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
96
+
97
+ cookie = SnappyCookie();
98
+ gcmd = lcb_CMDGET();
99
+ LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
100
+ lcb_get3(instance, &cookie, &gcmd);
101
+ lcb_wait(instance);
102
+ ASSERT_TRUE(cookie.called);
103
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
104
+ ASSERT_STREQ(value.c_str(), cookie.value.c_str());
105
+ ASSERT_TRUE(isCompressed(key));
106
+
107
+ lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_OUT);
108
+ cookie = SnappyCookie();
109
+ gcmd = lcb_CMDGET();
110
+ LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
111
+ lcb_get3(instance, &cookie, &gcmd);
112
+ lcb_wait(instance);
113
+ ASSERT_TRUE(cookie.called);
114
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
115
+ ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
116
+
117
+ setCompression("off");
118
+ createConnection(hw, instance);
119
+ lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_INOUT);
120
+ lcb_install_callback3(instance, LCB_CALLBACK_GET, getcb);
121
+ lcb_install_callback3(instance, LCB_CALLBACK_STORE, storecb);
122
+
123
+ cookie = SnappyCookie();
124
+ gcmd = lcb_CMDGET();
125
+ LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
126
+ lcb_get3(instance, &cookie, &gcmd);
127
+ lcb_wait(instance);
128
+ ASSERT_TRUE(cookie.called);
129
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
130
+ ASSERT_STREQ(value.c_str(), cookie.value.c_str());
131
+
132
+ cookie = SnappyCookie();
133
+ lcb_store3(instance, &cookie, &scmd);
134
+ lcb_wait(instance);
135
+ ASSERT_TRUE(cookie.called);
136
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
137
+ ASSERT_FALSE(isCompressed(key));
138
+ }
139
+
140
+ TEST_F(SnappyUnitTest, testIOV)
141
+ {
142
+
143
+ SKIP_UNLESS_MOCK();
144
+ HandleWrap hw;
145
+ lcb_t instance;
146
+
147
+ setCompression("passive");
148
+ createConnection(hw, instance);
149
+ lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_INOUT);
150
+ lcb_install_callback3(instance, LCB_CALLBACK_GET, getcb);
151
+ lcb_install_callback3(instance, LCB_CALLBACK_STORE, storecb);
152
+
153
+ std::string key("hello");
154
+ std::string value1("A big black bug bit ");
155
+ std::string value2("a big black bear, ");
156
+ std::string value3("made the big black ");
157
+ std::string value4("bear bleed blood");
158
+ std::string value = value1 + value2 + value3 + value4;
159
+ std::string compressed("IPA big black bug bit a.\x14");
160
+
161
+ SnappyCookie cookie;
162
+ lcb_CMDSTORE scmd;
163
+ lcb_CMDGET gcmd;
164
+
165
+ lcb_IOV iov[4];
166
+ unsigned int niov = 4;
167
+ iov[0].iov_base = (void *)value1.c_str();
168
+ iov[0].iov_len = value1.size();
169
+ iov[1].iov_base = (void *)value2.c_str();
170
+ iov[1].iov_len = value2.size();
171
+ iov[2].iov_base = (void *)value3.c_str();
172
+ iov[2].iov_len = value3.size();
173
+ iov[3].iov_base = (void *)value4.c_str();
174
+ iov[3].iov_len = value4.size();
175
+
176
+ scmd = lcb_CMDSTORE();
177
+ scmd.operation = LCB_UPSERT;
178
+ LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
179
+ LCB_CMD_SET_VALUEIOV(&scmd, iov, niov);
180
+ cookie = SnappyCookie();
181
+ lcb_store3(instance, &cookie, &scmd);
182
+ lcb_wait(instance);
183
+ ASSERT_TRUE(cookie.called);
184
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
185
+ /* now we have negotiated snappy feature */
186
+ cookie = SnappyCookie();
187
+ lcb_store3(instance, &cookie, &scmd);
188
+ lcb_wait(instance);
189
+ ASSERT_TRUE(cookie.called);
190
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
191
+
192
+ cookie = SnappyCookie();
193
+ gcmd = lcb_CMDGET();
194
+ LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
195
+ lcb_get3(instance, &cookie, &gcmd);
196
+ lcb_wait(instance);
197
+ ASSERT_TRUE(cookie.called);
198
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
199
+ ASSERT_STREQ(value.c_str(), cookie.value.c_str());
200
+ ASSERT_TRUE(isCompressed(key));
201
+
202
+ lcb_cntl_setu32(instance, LCB_CNTL_COMPRESSION_OPTS, LCB_COMPRESS_OUT);
203
+ cookie = SnappyCookie();
204
+ gcmd = lcb_CMDGET();
205
+ LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
206
+ lcb_get3(instance, &cookie, &gcmd);
207
+ lcb_wait(instance);
208
+ ASSERT_TRUE(cookie.called);
209
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
210
+ ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
211
+ }
212
+
213
+
214
+ TEST_F(SnappyUnitTest, testSettings)
215
+ {
216
+
217
+ SKIP_UNLESS_MOCK();
218
+ HandleWrap hw;
219
+ lcb_t instance;
220
+
221
+ setCompression("passive");
222
+ createConnection(hw, instance);
223
+ lcb_cntl_string(instance, "compression", "deflate_only");
224
+ lcb_install_callback3(instance, LCB_CALLBACK_GET, getcb);
225
+ lcb_install_callback3(instance, LCB_CALLBACK_STORE, storecb);
226
+
227
+ std::string key("hello");
228
+ std::string value("A big black bug bit a big black bear, made the big black bear bleed blood");
229
+ std::string compressed("IPA big black bug bit a.\x14");
230
+
231
+ SnappyCookie cookie;
232
+ lcb_CMDSTORE scmd;
233
+ lcb_CMDGET gcmd;
234
+
235
+ scmd = lcb_CMDSTORE();
236
+ scmd.operation = LCB_UPSERT;
237
+ LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
238
+ LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
239
+ cookie = SnappyCookie();
240
+ lcb_store3(instance, &cookie, &scmd);
241
+ lcb_wait(instance);
242
+ ASSERT_TRUE(cookie.called);
243
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
244
+ /* now we have negotiated snappy feature */
245
+ cookie = SnappyCookie();
246
+ lcb_store3(instance, &cookie, &scmd);
247
+ lcb_wait(instance);
248
+ ASSERT_TRUE(cookie.called);
249
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
250
+
251
+ value = "A big black bug";
252
+ compressed = "A big black bug";
253
+ scmd = lcb_CMDSTORE();
254
+ scmd.operation = LCB_UPSERT;
255
+ LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
256
+ LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
257
+ cookie = SnappyCookie();
258
+ lcb_store3(instance, &cookie, &scmd);
259
+ lcb_wait(instance);
260
+ ASSERT_TRUE(cookie.called);
261
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
262
+
263
+ cookie = SnappyCookie();
264
+ gcmd = lcb_CMDGET();
265
+ LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
266
+ lcb_get3(instance, &cookie, &gcmd);
267
+ lcb_wait(instance);
268
+ ASSERT_TRUE(cookie.called);
269
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
270
+ ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
271
+
272
+ lcb_cntl_string(instance, "compression_min_size", "1024"); /* greater than size of the value */
273
+ value = "A big black bug bit a big black bear, made the big black bear bleed blood";
274
+ compressed = "A big black bug bit a big black bear, made the big black bear bleed blood";
275
+ scmd = lcb_CMDSTORE();
276
+ scmd.operation = LCB_UPSERT;
277
+ LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
278
+ LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
279
+ cookie = SnappyCookie();
280
+ lcb_store3(instance, &cookie, &scmd);
281
+ lcb_wait(instance);
282
+ ASSERT_TRUE(cookie.called);
283
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
284
+
285
+ cookie = SnappyCookie();
286
+ gcmd = lcb_CMDGET();
287
+ LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
288
+ lcb_get3(instance, &cookie, &gcmd);
289
+ lcb_wait(instance);
290
+ ASSERT_TRUE(cookie.called);
291
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
292
+ ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
293
+
294
+ lcb_cntl_string(instance, "compression_min_size", "40"); /* less than size of the value */
295
+ lcb_cntl_string(instance, "compression_min_ratio", "0.1"); /* expect to reduce size in 10 times */
296
+ value = "A big black bug bit a big black bear, made the big black bear bleed blood";
297
+ compressed = "A big black bug bit a big black bear, made the big black bear bleed blood";
298
+ scmd = lcb_CMDSTORE();
299
+ scmd.operation = LCB_UPSERT;
300
+ LCB_CMD_SET_KEY(&scmd, key.c_str(), key.size());
301
+ LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.size());
302
+ cookie = SnappyCookie();
303
+ lcb_store3(instance, &cookie, &scmd);
304
+ lcb_wait(instance);
305
+ ASSERT_TRUE(cookie.called);
306
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
307
+
308
+ cookie = SnappyCookie();
309
+ gcmd = lcb_CMDGET();
310
+ LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.size());
311
+ lcb_get3(instance, &cookie, &gcmd);
312
+ lcb_wait(instance);
313
+ ASSERT_TRUE(cookie.called);
314
+ ASSERT_EQ(LCB_SUCCESS, cookie.rc);
315
+ ASSERT_STREQ(compressed.c_str(), cookie.value.c_str());
316
+ }