libcouchbase 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (561) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +35 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +24 -0
  8. data/README.md +389 -0
  9. data/Rakefile +75 -0
  10. data/ext/README.md +6 -0
  11. data/ext/Rakefile +20 -0
  12. data/ext/libcouchbase/.gitignore +130 -0
  13. data/ext/libcouchbase/.travis.yml +19 -0
  14. data/ext/libcouchbase/CMakeLists.txt +429 -0
  15. data/ext/libcouchbase/CONTRIBUTING.md +124 -0
  16. data/ext/libcouchbase/LICENSE +202 -0
  17. data/ext/libcouchbase/README.markdown +163 -0
  18. data/ext/libcouchbase/RELEASE_NOTES.markdown +2691 -0
  19. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +27 -0
  20. data/ext/libcouchbase/cmake/Modules/CopyPDB.cmake +42 -0
  21. data/ext/libcouchbase/cmake/Modules/DistScript.cmake +17 -0
  22. data/ext/libcouchbase/cmake/Modules/DownloadLcbDep.cmake +20 -0
  23. data/ext/libcouchbase/cmake/Modules/FindCouchbaseHdrHistogram.cmake +15 -0
  24. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibev.cmake +73 -0
  25. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +52 -0
  26. data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +56 -0
  27. data/ext/libcouchbase/cmake/Modules/FindCouchbaseSnappy.cmake +11 -0
  28. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +29 -0
  29. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +133 -0
  30. data/ext/libcouchbase/cmake/Modules/GetPlatformCCInfo.cmake +45 -0
  31. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +70 -0
  32. data/ext/libcouchbase/cmake/config-cmake.h.in +60 -0
  33. data/ext/libcouchbase/cmake/configure +357 -0
  34. data/ext/libcouchbase/cmake/defs.mk.in +8 -0
  35. data/ext/libcouchbase/cmake/dtrace-instr-link.pl +38 -0
  36. data/ext/libcouchbase/cmake/source_files.cmake +73 -0
  37. data/ext/libcouchbase/configure.pl +1 -0
  38. data/ext/libcouchbase/contrib/cJSON/cJSON.c +624 -0
  39. data/ext/libcouchbase/contrib/cJSON/cJSON.h +158 -0
  40. data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +9 -0
  41. data/ext/libcouchbase/contrib/cbsasl/COPYING +202 -0
  42. data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +217 -0
  43. data/ext/libcouchbase/contrib/cbsasl/src/client.c +205 -0
  44. data/ext/libcouchbase/contrib/cbsasl/src/common.c +46 -0
  45. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/hmac.c +67 -0
  46. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/hmac.h +33 -0
  47. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/md5.c +296 -0
  48. data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/md5.h +45 -0
  49. data/ext/libcouchbase/contrib/cbsasl/src/hash.c +573 -0
  50. data/ext/libcouchbase/contrib/cbsasl/src/hash.h +15 -0
  51. data/ext/libcouchbase/contrib/cbsasl/src/util.h +31 -0
  52. data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +2 -0
  53. data/ext/libcouchbase/contrib/cliopts/cliopts.c +747 -0
  54. data/ext/libcouchbase/contrib/cliopts/cliopts.h +493 -0
  55. data/ext/libcouchbase/contrib/genhash/genhash.c +372 -0
  56. data/ext/libcouchbase/contrib/genhash/genhash.h +235 -0
  57. data/ext/libcouchbase/contrib/gtest-1.7.0/CHANGES +157 -0
  58. data/ext/libcouchbase/contrib/gtest-1.7.0/CMakeLists.txt +252 -0
  59. data/ext/libcouchbase/contrib/gtest-1.7.0/CONTRIBUTORS +37 -0
  60. data/ext/libcouchbase/contrib/gtest-1.7.0/LICENSE +28 -0
  61. data/ext/libcouchbase/contrib/gtest-1.7.0/MINIFY.sh +15 -0
  62. data/ext/libcouchbase/contrib/gtest-1.7.0/README +435 -0
  63. data/ext/libcouchbase/contrib/gtest-1.7.0/cmake/internal_utils.cmake +227 -0
  64. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-death-test.h +294 -0
  65. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-message.h +250 -0
  66. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-param-test.h +1421 -0
  67. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-param-test.h.pump +487 -0
  68. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-printers.h +855 -0
  69. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-spi.h +232 -0
  70. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-test-part.h +179 -0
  71. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-typed-test.h +259 -0
  72. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest.h +2291 -0
  73. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest_pred_impl.h +358 -0
  74. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest_prod.h +58 -0
  75. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h +319 -0
  76. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h +206 -0
  77. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-internal.h +1158 -0
  78. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h +233 -0
  79. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h +5143 -0
  80. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h.pump +301 -0
  81. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h +619 -0
  82. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-port.h +1947 -0
  83. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-string.h +167 -0
  84. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-tuple.h +1012 -0
  85. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-tuple.h.pump +339 -0
  86. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h +3331 -0
  87. data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h.pump +297 -0
  88. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-all.cc +48 -0
  89. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-death-test.cc +1344 -0
  90. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-filepath.cc +382 -0
  91. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-internal-inl.h +1218 -0
  92. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-port.cc +805 -0
  93. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-printers.cc +363 -0
  94. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-test-part.cc +110 -0
  95. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-typed-test.cc +110 -0
  96. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest.cc +5015 -0
  97. data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest_main.cc +38 -0
  98. data/ext/libcouchbase/contrib/http_parser/LICENSE-MIT +23 -0
  99. data/ext/libcouchbase/contrib/http_parser/README.md +178 -0
  100. data/ext/libcouchbase/contrib/http_parser/http_parser.c +2060 -0
  101. data/ext/libcouchbase/contrib/http_parser/http_parser.h +321 -0
  102. data/ext/libcouchbase/contrib/jsonsl/LICENSE +20 -0
  103. data/ext/libcouchbase/contrib/jsonsl/jsonsl.c +1452 -0
  104. data/ext/libcouchbase/contrib/jsonsl/jsonsl.h +971 -0
  105. data/ext/libcouchbase/contrib/lcb-jsoncpp/CMakeLists.txt +6 -0
  106. data/ext/libcouchbase/contrib/lcb-jsoncpp/LICENSE +55 -0
  107. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp-forwards.h +255 -0
  108. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +4892 -0
  109. data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.h +1961 -0
  110. data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +8 -0
  111. data/ext/libcouchbase/contrib/snappy/COPYING +28 -0
  112. data/ext/libcouchbase/contrib/snappy/snappy-c.cc +90 -0
  113. data/ext/libcouchbase/contrib/snappy/snappy-c.h +138 -0
  114. data/ext/libcouchbase/contrib/snappy/snappy-internal.h +150 -0
  115. data/ext/libcouchbase/contrib/snappy/snappy-lcb-msvc.h +5 -0
  116. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +71 -0
  117. data/ext/libcouchbase/contrib/snappy/snappy-sinksource.h +137 -0
  118. data/ext/libcouchbase/contrib/snappy/snappy-stubs-internal.cc +42 -0
  119. data/ext/libcouchbase/contrib/snappy/snappy-stubs-internal.h +491 -0
  120. data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +98 -0
  121. data/ext/libcouchbase/contrib/snappy/snappy.cc +1307 -0
  122. data/ext/libcouchbase/contrib/snappy/snappy.h +184 -0
  123. data/ext/libcouchbase/contrib/win32-defs/iocpdefs.h +133 -0
  124. data/ext/libcouchbase/contrib/win32-defs/mingwdefs.h +4396 -0
  125. data/ext/libcouchbase/contrib/win32-defs/win_stdint.h +258 -0
  126. data/ext/libcouchbase/example/CMakeLists.txt +37 -0
  127. data/ext/libcouchbase/example/README.markdown +47 -0
  128. data/ext/libcouchbase/example/db/db.c +167 -0
  129. data/ext/libcouchbase/example/db/vb.c +227 -0
  130. data/ext/libcouchbase/example/instancepool/main.cc +102 -0
  131. data/ext/libcouchbase/example/instancepool/pool.cc +102 -0
  132. data/ext/libcouchbase/example/instancepool/pool.h +69 -0
  133. data/ext/libcouchbase/example/libeventdirect/main.c +148 -0
  134. data/ext/libcouchbase/example/mcc/mcc.cc +246 -0
  135. data/ext/libcouchbase/example/minimal/minimal.c +130 -0
  136. data/ext/libcouchbase/example/observe/observe.c +146 -0
  137. data/ext/libcouchbase/example/subdoc/subdoc-multi.cc +132 -0
  138. data/ext/libcouchbase/example/subdoc/subdoc-simple.cc +191 -0
  139. data/ext/libcouchbase/example/tick/tick.c +119 -0
  140. data/ext/libcouchbase/example/views/views-example.cc +83 -0
  141. data/ext/libcouchbase/include/libcouchbase/_cxxwrap.h +150 -0
  142. data/ext/libcouchbase/include/libcouchbase/api-legacy.h +1689 -0
  143. data/ext/libcouchbase/include/libcouchbase/api3.h +2 -0
  144. data/ext/libcouchbase/include/libcouchbase/assert.h +44 -0
  145. data/ext/libcouchbase/include/libcouchbase/cbft.h +109 -0
  146. data/ext/libcouchbase/include/libcouchbase/cntl-private.h +356 -0
  147. data/ext/libcouchbase/include/libcouchbase/cntl.h +937 -0
  148. data/ext/libcouchbase/include/libcouchbase/configuration.h.in +23 -0
  149. data/ext/libcouchbase/include/libcouchbase/couchbase.h +3677 -0
  150. data/ext/libcouchbase/include/libcouchbase/deprecated.h +300 -0
  151. data/ext/libcouchbase/include/libcouchbase/error.h +595 -0
  152. data/ext/libcouchbase/include/libcouchbase/http.h +1 -0
  153. data/ext/libcouchbase/include/libcouchbase/iops.h +1050 -0
  154. data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +263 -0
  155. data/ext/libcouchbase/include/libcouchbase/kvbuf.h +132 -0
  156. data/ext/libcouchbase/include/libcouchbase/n1ql.h +364 -0
  157. data/ext/libcouchbase/include/libcouchbase/pktfwd.h +270 -0
  158. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +367 -0
  159. data/ext/libcouchbase/include/libcouchbase/plugins/io/wsaerr-inl.c +76 -0
  160. data/ext/libcouchbase/include/libcouchbase/plugins/io/wsaerr.h +199 -0
  161. data/ext/libcouchbase/include/libcouchbase/subdoc.h +312 -0
  162. data/ext/libcouchbase/include/libcouchbase/sysdefs.h +98 -0
  163. data/ext/libcouchbase/include/libcouchbase/vbucket.h +643 -0
  164. data/ext/libcouchbase/include/libcouchbase/views.h +298 -0
  165. data/ext/libcouchbase/include/libcouchbase/visibility.h +65 -0
  166. data/ext/libcouchbase/include/memcached/COPYING +30 -0
  167. data/ext/libcouchbase/include/memcached/README +10 -0
  168. data/ext/libcouchbase/include/memcached/protocol_binary.h +1916 -0
  169. data/ext/libcouchbase/include/memcached/vbucket.h +42 -0
  170. data/ext/libcouchbase/packaging/README +7 -0
  171. data/ext/libcouchbase/packaging/abicheck/.gitignore +4 -0
  172. data/ext/libcouchbase/packaging/abicheck/Makefile +17 -0
  173. data/ext/libcouchbase/packaging/abicheck/README.md +27 -0
  174. data/ext/libcouchbase/packaging/abicheck/template.xml +3 -0
  175. data/ext/libcouchbase/packaging/deb/compat +1 -0
  176. data/ext/libcouchbase/packaging/deb/control +73 -0
  177. data/ext/libcouchbase/packaging/deb/copyright +10 -0
  178. data/ext/libcouchbase/packaging/deb/libcouchbase-dev.docs +3 -0
  179. data/ext/libcouchbase/packaging/deb/package.mk +31 -0
  180. data/ext/libcouchbase/packaging/deb/rules +46 -0
  181. data/ext/libcouchbase/packaging/deb/source/format +1 -0
  182. data/ext/libcouchbase/packaging/distinfo/README +1 -0
  183. data/ext/libcouchbase/packaging/distinfo/distinfo.cmake.in +4 -0
  184. data/ext/libcouchbase/packaging/dllversion.rc.in +39 -0
  185. data/ext/libcouchbase/packaging/libcouchbase.pc.in +10 -0
  186. data/ext/libcouchbase/packaging/nuget/libcouchbase.autopkg +76 -0
  187. data/ext/libcouchbase/packaging/parse-git-describe.pl +166 -0
  188. data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +108 -0
  189. data/ext/libcouchbase/packaging/rpm/package.mk +40 -0
  190. data/ext/libcouchbase/plugins/io/iocp/CMakeLists.txt +9 -0
  191. data/ext/libcouchbase/plugins/io/iocp/iocp_iops.c +466 -0
  192. data/ext/libcouchbase/plugins/io/iocp/iocp_iops.h +217 -0
  193. data/ext/libcouchbase/plugins/io/iocp/iocp_loop.c +295 -0
  194. data/ext/libcouchbase/plugins/io/iocp/iocp_timer.c +79 -0
  195. data/ext/libcouchbase/plugins/io/iocp/iocp_util.c +229 -0
  196. data/ext/libcouchbase/plugins/io/libev/CMakeLists.txt +29 -0
  197. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +65 -0
  198. data/ext/libcouchbase/plugins/io/libev/plugin-libev.c +289 -0
  199. data/ext/libcouchbase/plugins/io/libevent/CMakeLists.txt +29 -0
  200. data/ext/libcouchbase/plugins/io/libevent/libevent_io_opts.h +67 -0
  201. data/ext/libcouchbase/plugins/io/libevent/plugin-libevent.c +292 -0
  202. data/ext/libcouchbase/plugins/io/libuv/CMakeLists.txt +42 -0
  203. data/ext/libcouchbase/plugins/io/libuv/libuv_compat.h +212 -0
  204. data/ext/libcouchbase/plugins/io/libuv/libuv_io_opts.h +118 -0
  205. data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +148 -0
  206. data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +648 -0
  207. data/ext/libcouchbase/plugins/io/select/CMakeLists.txt +11 -0
  208. data/ext/libcouchbase/plugins/io/select/plugin-select.c +448 -0
  209. data/ext/libcouchbase/plugins/io/select/select_io_opts.h +39 -0
  210. data/ext/libcouchbase/src/README.md +103 -0
  211. data/ext/libcouchbase/src/aspend.h +106 -0
  212. data/ext/libcouchbase/src/auth.cc +74 -0
  213. data/ext/libcouchbase/src/auth.h +54 -0
  214. data/ext/libcouchbase/src/bootstrap.c +269 -0
  215. data/ext/libcouchbase/src/bootstrap.h +129 -0
  216. data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +495 -0
  217. data/ext/libcouchbase/src/bucketconfig/bc_file.c +347 -0
  218. data/ext/libcouchbase/src/bucketconfig/bc_http.c +630 -0
  219. data/ext/libcouchbase/src/bucketconfig/bc_http.h +82 -0
  220. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +150 -0
  221. data/ext/libcouchbase/src/bucketconfig/clconfig.h +681 -0
  222. data/ext/libcouchbase/src/bucketconfig/confmon.c +474 -0
  223. data/ext/libcouchbase/src/callbacks.c +378 -0
  224. data/ext/libcouchbase/src/cbft.cc +210 -0
  225. data/ext/libcouchbase/src/cntl.cc +847 -0
  226. data/ext/libcouchbase/src/config_static.h +159 -0
  227. data/ext/libcouchbase/src/connspec.cc +462 -0
  228. data/ext/libcouchbase/src/connspec.h +105 -0
  229. data/ext/libcouchbase/src/ctx-log-inl.h +27 -0
  230. data/ext/libcouchbase/src/dump.c +98 -0
  231. data/ext/libcouchbase/src/getconfig.c +100 -0
  232. data/ext/libcouchbase/src/gethrtime.c +109 -0
  233. data/ext/libcouchbase/src/handler.c +922 -0
  234. data/ext/libcouchbase/src/hashset.c +164 -0
  235. data/ext/libcouchbase/src/hashset.h +86 -0
  236. data/ext/libcouchbase/src/hashtable.c +75 -0
  237. data/ext/libcouchbase/src/hdr_timings.c +92 -0
  238. data/ext/libcouchbase/src/hostlist.cc +301 -0
  239. data/ext/libcouchbase/src/hostlist.h +171 -0
  240. data/ext/libcouchbase/src/http/http-priv.h +307 -0
  241. data/ext/libcouchbase/src/http/http.cc +633 -0
  242. data/ext/libcouchbase/src/http/http.h +34 -0
  243. data/ext/libcouchbase/src/http/http_io.cc +307 -0
  244. data/ext/libcouchbase/src/instance.cc +722 -0
  245. data/ext/libcouchbase/src/internal.h +244 -0
  246. data/ext/libcouchbase/src/iofactory.c +575 -0
  247. data/ext/libcouchbase/src/jsparse/parser.cc +519 -0
  248. data/ext/libcouchbase/src/jsparse/parser.h +173 -0
  249. data/ext/libcouchbase/src/lcbht/lcbht.c +282 -0
  250. data/ext/libcouchbase/src/lcbht/lcbht.h +199 -0
  251. data/ext/libcouchbase/src/lcbio/connect.c +557 -0
  252. data/ext/libcouchbase/src/lcbio/connect.h +364 -0
  253. data/ext/libcouchbase/src/lcbio/ctx.c +611 -0
  254. data/ext/libcouchbase/src/lcbio/ctx.h +405 -0
  255. data/ext/libcouchbase/src/lcbio/iotable.c +290 -0
  256. data/ext/libcouchbase/src/lcbio/iotable.h +84 -0
  257. data/ext/libcouchbase/src/lcbio/ioutils.c +350 -0
  258. data/ext/libcouchbase/src/lcbio/ioutils.h +203 -0
  259. data/ext/libcouchbase/src/lcbio/lcbio.h +51 -0
  260. data/ext/libcouchbase/src/lcbio/manager.c +584 -0
  261. data/ext/libcouchbase/src/lcbio/manager.h +156 -0
  262. data/ext/libcouchbase/src/lcbio/protoctx.c +84 -0
  263. data/ext/libcouchbase/src/lcbio/rw-inl.h +115 -0
  264. data/ext/libcouchbase/src/lcbio/ssl.h +149 -0
  265. data/ext/libcouchbase/src/lcbio/timer-ng.h +179 -0
  266. data/ext/libcouchbase/src/lcbio/timer.c +132 -0
  267. data/ext/libcouchbase/src/legacy.c +430 -0
  268. data/ext/libcouchbase/src/list.c +144 -0
  269. data/ext/libcouchbase/src/list.h +127 -0
  270. data/ext/libcouchbase/src/logging.c +244 -0
  271. data/ext/libcouchbase/src/logging.h +86 -0
  272. data/ext/libcouchbase/src/mc/compress.c +90 -0
  273. data/ext/libcouchbase/src/mc/compress.h +61 -0
  274. data/ext/libcouchbase/src/mc/forward.c +186 -0
  275. data/ext/libcouchbase/src/mc/forward.h +90 -0
  276. data/ext/libcouchbase/src/mc/iovcursor-inl.h +279 -0
  277. data/ext/libcouchbase/src/mc/iovcursor.h +66 -0
  278. data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +111 -0
  279. data/ext/libcouchbase/src/mc/mcreq.c +954 -0
  280. data/ext/libcouchbase/src/mc/mcreq.h +977 -0
  281. data/ext/libcouchbase/src/mcserver/mcserver.c +784 -0
  282. data/ext/libcouchbase/src/mcserver/mcserver.h +121 -0
  283. data/ext/libcouchbase/src/mcserver/negotiate.c +656 -0
  284. data/ext/libcouchbase/src/mcserver/negotiate.h +119 -0
  285. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +860 -0
  286. data/ext/libcouchbase/src/n1ql/n1ql-internal.h +22 -0
  287. data/ext/libcouchbase/src/n1ql/n1ql.cc +729 -0
  288. data/ext/libcouchbase/src/n1ql/params.cc +215 -0
  289. data/ext/libcouchbase/src/netbuf/netbuf-defs.h +89 -0
  290. data/ext/libcouchbase/src/netbuf/netbuf-mblock.h +235 -0
  291. data/ext/libcouchbase/src/netbuf/netbuf.c +929 -0
  292. data/ext/libcouchbase/src/netbuf/netbuf.h +452 -0
  293. data/ext/libcouchbase/src/newconfig.c +385 -0
  294. data/ext/libcouchbase/src/nodeinfo.cc +194 -0
  295. data/ext/libcouchbase/src/operations/cbflush.c +71 -0
  296. data/ext/libcouchbase/src/operations/counter.c +116 -0
  297. data/ext/libcouchbase/src/operations/durability-cas.c +224 -0
  298. data/ext/libcouchbase/src/operations/durability-seqno.c +157 -0
  299. data/ext/libcouchbase/src/operations/durability.c +668 -0
  300. data/ext/libcouchbase/src/operations/durability_internal.h +199 -0
  301. data/ext/libcouchbase/src/operations/get.c +409 -0
  302. data/ext/libcouchbase/src/operations/observe-seqno.c +96 -0
  303. data/ext/libcouchbase/src/operations/observe.c +340 -0
  304. data/ext/libcouchbase/src/operations/pktfwd.c +86 -0
  305. data/ext/libcouchbase/src/operations/remove.c +83 -0
  306. data/ext/libcouchbase/src/operations/stats.c +461 -0
  307. data/ext/libcouchbase/src/operations/store.c +360 -0
  308. data/ext/libcouchbase/src/operations/subdoc.cc +510 -0
  309. data/ext/libcouchbase/src/operations/touch.c +81 -0
  310. data/ext/libcouchbase/src/packetutils.c +60 -0
  311. data/ext/libcouchbase/src/packetutils.h +147 -0
  312. data/ext/libcouchbase/src/probes.d +211 -0
  313. data/ext/libcouchbase/src/rdb/bigalloc.c +225 -0
  314. data/ext/libcouchbase/src/rdb/bigalloc.h +73 -0
  315. data/ext/libcouchbase/src/rdb/chunkalloc.c +174 -0
  316. data/ext/libcouchbase/src/rdb/libcalloc.c +94 -0
  317. data/ext/libcouchbase/src/rdb/rope.c +419 -0
  318. data/ext/libcouchbase/src/rdb/rope.h +488 -0
  319. data/ext/libcouchbase/src/retrychk.c +113 -0
  320. data/ext/libcouchbase/src/retryq.c +424 -0
  321. data/ext/libcouchbase/src/retryq.h +157 -0
  322. data/ext/libcouchbase/src/ringbuffer.c +442 -0
  323. data/ext/libcouchbase/src/ringbuffer.h +100 -0
  324. data/ext/libcouchbase/src/settings.c +95 -0
  325. data/ext/libcouchbase/src/settings.h +188 -0
  326. data/ext/libcouchbase/src/simplestring.c +211 -0
  327. data/ext/libcouchbase/src/simplestring.h +228 -0
  328. data/ext/libcouchbase/src/sllist-inl.h +197 -0
  329. data/ext/libcouchbase/src/sllist.h +76 -0
  330. data/ext/libcouchbase/src/ssl/CMakeLists.txt +23 -0
  331. data/ext/libcouchbase/src/ssl/ssl_c.c +415 -0
  332. data/ext/libcouchbase/src/ssl/ssl_common.c +454 -0
  333. data/ext/libcouchbase/src/ssl/ssl_e.c +408 -0
  334. data/ext/libcouchbase/src/ssl/ssl_iot_common.h +180 -0
  335. data/ext/libcouchbase/src/ssobuf.h +82 -0
  336. data/ext/libcouchbase/src/strcodecs/base64.c +123 -0
  337. data/ext/libcouchbase/src/strcodecs/strcodecs.h +285 -0
  338. data/ext/libcouchbase/src/timings.c +208 -0
  339. data/ext/libcouchbase/src/trace.h +105 -0
  340. data/ext/libcouchbase/src/utilities.c +171 -0
  341. data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -0
  342. data/ext/libcouchbase/src/vbucket/aliases.h +35 -0
  343. data/ext/libcouchbase/src/vbucket/crc32.h +83 -0
  344. data/ext/libcouchbase/src/vbucket/hash.h +30 -0
  345. data/ext/libcouchbase/src/vbucket/json-inl.h +112 -0
  346. data/ext/libcouchbase/src/vbucket/ketama.c +66 -0
  347. data/ext/libcouchbase/src/vbucket/rfc1321/global.h +32 -0
  348. data/ext/libcouchbase/src/vbucket/rfc1321/md5.h +35 -0
  349. data/ext/libcouchbase/src/vbucket/rfc1321/md5c-inl.h +335 -0
  350. data/ext/libcouchbase/src/vbucket/vbucket.c +1543 -0
  351. data/ext/libcouchbase/src/views/docreq.c +194 -0
  352. data/ext/libcouchbase/src/views/docreq.h +83 -0
  353. data/ext/libcouchbase/src/views/viewreq.c +358 -0
  354. data/ext/libcouchbase/src/views/viewreq.h +36 -0
  355. data/ext/libcouchbase/src/wait.c +161 -0
  356. data/ext/libcouchbase/tests/CMakeLists.txt +140 -0
  357. data/ext/libcouchbase/tests/basic/t_base64.cc +81 -0
  358. data/ext/libcouchbase/tests/basic/t_ccbc103.cc +95 -0
  359. data/ext/libcouchbase/tests/basic/t_connstr.cc +404 -0
  360. data/ext/libcouchbase/tests/basic/t_creds.cc +32 -0
  361. data/ext/libcouchbase/tests/basic/t_ctlcodes.cc +92 -0
  362. data/ext/libcouchbase/tests/basic/t_hashset.cc +262 -0
  363. data/ext/libcouchbase/tests/basic/t_host.cc +198 -0
  364. data/ext/libcouchbase/tests/basic/t_jsparse.cc +137 -0
  365. data/ext/libcouchbase/tests/basic/t_jsparse.h +589 -0
  366. data/ext/libcouchbase/tests/basic/t_list.cc +155 -0
  367. data/ext/libcouchbase/tests/basic/t_logger.cc +65 -0
  368. data/ext/libcouchbase/tests/basic/t_misc.cc +24 -0
  369. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +18 -0
  370. data/ext/libcouchbase/tests/basic/t_netbuf.cc +446 -0
  371. data/ext/libcouchbase/tests/basic/t_packet.cc +222 -0
  372. data/ext/libcouchbase/tests/basic/t_ringbuffer.cc +278 -0
  373. data/ext/libcouchbase/tests/basic/t_slist.cc +429 -0
  374. data/ext/libcouchbase/tests/basic/t_strerror.cc +64 -0
  375. data/ext/libcouchbase/tests/basic/t_string.cc +112 -0
  376. data/ext/libcouchbase/tests/basic/t_urlencode.cc +132 -0
  377. data/ext/libcouchbase/tests/check-all.cc +608 -0
  378. data/ext/libcouchbase/tests/htparse/t_basic.cc +193 -0
  379. data/ext/libcouchbase/tests/ioserver/connection.cc +166 -0
  380. data/ext/libcouchbase/tests/ioserver/future.cc +50 -0
  381. data/ext/libcouchbase/tests/ioserver/ioserver.cc +104 -0
  382. data/ext/libcouchbase/tests/ioserver/ioserver.h +478 -0
  383. data/ext/libcouchbase/tests/ioserver/socket.cc +88 -0
  384. data/ext/libcouchbase/tests/ioserver/ssl_connection.cc +145 -0
  385. data/ext/libcouchbase/tests/ioserver/threads-pthreads.cc +119 -0
  386. data/ext/libcouchbase/tests/ioserver/threads-win32.cc +117 -0
  387. data/ext/libcouchbase/tests/ioserver/threads.h +66 -0
  388. data/ext/libcouchbase/tests/iotests/iotests.h +15 -0
  389. data/ext/libcouchbase/tests/iotests/mock-environment.cc +524 -0
  390. data/ext/libcouchbase/tests/iotests/mock-environment.h +385 -0
  391. data/ext/libcouchbase/tests/iotests/mock-unit-test.cc +67 -0
  392. data/ext/libcouchbase/tests/iotests/mock-unit-test.h +61 -0
  393. data/ext/libcouchbase/tests/iotests/serverparams.h +76 -0
  394. data/ext/libcouchbase/tests/iotests/t_arithmetic.cc +143 -0
  395. data/ext/libcouchbase/tests/iotests/t_behavior.cc +226 -0
  396. data/ext/libcouchbase/tests/iotests/t_configcache.cc +117 -0
  397. data/ext/libcouchbase/tests/iotests/t_confmon.cc +241 -0
  398. data/ext/libcouchbase/tests/iotests/t_durability.cc +1059 -0
  399. data/ext/libcouchbase/tests/iotests/t_forward.cc +110 -0
  400. data/ext/libcouchbase/tests/iotests/t_get.cc +512 -0
  401. data/ext/libcouchbase/tests/iotests/t_http.cc +438 -0
  402. data/ext/libcouchbase/tests/iotests/t_iops.cc +175 -0
  403. data/ext/libcouchbase/tests/iotests/t_lock.cc +275 -0
  404. data/ext/libcouchbase/tests/iotests/t_misc.cc +713 -0
  405. data/ext/libcouchbase/tests/iotests/t_mutate.cc +609 -0
  406. data/ext/libcouchbase/tests/iotests/t_n1ql.cc +270 -0
  407. data/ext/libcouchbase/tests/iotests/t_netfail.cc +654 -0
  408. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +157 -0
  409. data/ext/libcouchbase/tests/iotests/t_regression.cc +321 -0
  410. data/ext/libcouchbase/tests/iotests/t_sched.cc +88 -0
  411. data/ext/libcouchbase/tests/iotests/t_serverops.cc +230 -0
  412. data/ext/libcouchbase/tests/iotests/t_smoke.cc +528 -0
  413. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +822 -0
  414. data/ext/libcouchbase/tests/iotests/t_syncmode.cc +64 -0
  415. data/ext/libcouchbase/tests/iotests/t_views.cc +405 -0
  416. data/ext/libcouchbase/tests/iotests/testutil.cc +250 -0
  417. data/ext/libcouchbase/tests/iotests/testutil.h +163 -0
  418. data/ext/libcouchbase/tests/mc/mctest.h +119 -0
  419. data/ext/libcouchbase/tests/mc/pktmaker.h +101 -0
  420. data/ext/libcouchbase/tests/mc/t_alloc.cc +269 -0
  421. data/ext/libcouchbase/tests/mc/t_context.cc +100 -0
  422. data/ext/libcouchbase/tests/mc/t_flush.cc +185 -0
  423. data/ext/libcouchbase/tests/mc/t_forward.cc +239 -0
  424. data/ext/libcouchbase/tests/mc/t_ioflush.cc +102 -0
  425. data/ext/libcouchbase/tests/mc/t_iovcursor.cc +173 -0
  426. data/ext/libcouchbase/tests/mocksupport/procutil.c +305 -0
  427. data/ext/libcouchbase/tests/mocksupport/procutil.h +89 -0
  428. data/ext/libcouchbase/tests/mocksupport/server.c +391 -0
  429. data/ext/libcouchbase/tests/mocksupport/server.h +72 -0
  430. data/ext/libcouchbase/tests/mocksupport/timeout.c +69 -0
  431. data/ext/libcouchbase/tests/nonio_tests.cc +23 -0
  432. data/ext/libcouchbase/tests/rdb/rdbtest.h +133 -0
  433. data/ext/libcouchbase/tests/rdb/t_basic.cc +128 -0
  434. data/ext/libcouchbase/tests/rdb/t_bigalloc.cc +93 -0
  435. data/ext/libcouchbase/tests/rdb/t_refs.cc +112 -0
  436. data/ext/libcouchbase/tests/socktests/socktest.cc +347 -0
  437. data/ext/libcouchbase/tests/socktests/socktest.h +448 -0
  438. data/ext/libcouchbase/tests/socktests/t_basic.cc +143 -0
  439. data/ext/libcouchbase/tests/socktests/t_ctx.cc +73 -0
  440. data/ext/libcouchbase/tests/socktests/t_manager.cc +179 -0
  441. data/ext/libcouchbase/tests/socktests/t_putex.cc +256 -0
  442. data/ext/libcouchbase/tests/socktests/t_read.cc +187 -0
  443. data/ext/libcouchbase/tests/socktests/t_reentrant.cc +143 -0
  444. data/ext/libcouchbase/tests/socktests/t_ssl.cc +80 -0
  445. data/ext/libcouchbase/tests/socktests/t_write.cc +95 -0
  446. data/ext/libcouchbase/tests/start_mock.bat +15 -0
  447. data/ext/libcouchbase/tests/start_mock.sh +42 -0
  448. data/ext/libcouchbase/tests/unit_tests.cc +43 -0
  449. data/ext/libcouchbase/tests/vbucket/confdata/bad.json +101 -0
  450. data/ext/libcouchbase/tests/vbucket/confdata/full_25.json +363 -0
  451. data/ext/libcouchbase/tests/vbucket/confdata/memd_25.json +90 -0
  452. data/ext/libcouchbase/tests/vbucket/confdata/memd_30.json +1 -0
  453. data/ext/libcouchbase/tests/vbucket/confdata/memd_45.json +1 -0
  454. data/ext/libcouchbase/tests/vbucket/confdata/terse_25.json +291 -0
  455. data/ext/libcouchbase/tests/vbucket/confdata/terse_30.json +1 -0
  456. data/ext/libcouchbase/tests/vbucket/t_config.cc +341 -0
  457. data/ext/libcouchbase/tools/CMakeLists.txt +51 -0
  458. data/ext/libcouchbase/tools/cbc-handlers.h +462 -0
  459. data/ext/libcouchbase/tools/cbc-n1qlback.cc +439 -0
  460. data/ext/libcouchbase/tools/cbc-pillowfight.cc +822 -0
  461. data/ext/libcouchbase/tools/cbc.cc +1541 -0
  462. data/ext/libcouchbase/tools/common/histogram.cc +43 -0
  463. data/ext/libcouchbase/tools/common/histogram.h +23 -0
  464. data/ext/libcouchbase/tools/common/my_inttypes.h +22 -0
  465. data/ext/libcouchbase/tools/common/options.cc +420 -0
  466. data/ext/libcouchbase/tools/common/options.h +81 -0
  467. data/ext/libcouchbase/tools/docgen/docgen.h +469 -0
  468. data/ext/libcouchbase/tools/docgen/loc.h +210 -0
  469. data/ext/libcouchbase/tools/docgen/placeholders.h +211 -0
  470. data/ext/libcouchbase/tools/docgen/seqgen.h +94 -0
  471. data/lib/libcouchbase.rb +36 -0
  472. data/lib/libcouchbase/bucket.rb +819 -0
  473. data/lib/libcouchbase/callbacks.rb +72 -0
  474. data/lib/libcouchbase/connection.rb +790 -0
  475. data/lib/libcouchbase/design_docs.rb +86 -0
  476. data/lib/libcouchbase/error.rb +68 -0
  477. data/lib/libcouchbase/ext/libcouchbase.rb +1135 -0
  478. data/lib/libcouchbase/ext/libcouchbase/cmdbase.rb +23 -0
  479. data/lib/libcouchbase/ext/libcouchbase/cmdcounter.rb +36 -0
  480. data/lib/libcouchbase/ext/libcouchbase/cmdendure.rb +26 -0
  481. data/lib/libcouchbase/ext/libcouchbase/cmdfts.rb +24 -0
  482. data/lib/libcouchbase/ext/libcouchbase/cmdget.rb +30 -0
  483. data/lib/libcouchbase/ext/libcouchbase/cmdgetreplica.rb +49 -0
  484. data/lib/libcouchbase/ext/libcouchbase/cmdhttp.rb +58 -0
  485. data/lib/libcouchbase/ext/libcouchbase/cmdn1ql.rb +40 -0
  486. data/lib/libcouchbase/ext/libcouchbase/cmdobseqno.rb +33 -0
  487. data/lib/libcouchbase/ext/libcouchbase/cmdobserve.rb +30 -0
  488. data/lib/libcouchbase/ext/libcouchbase/cmdstore.rb +40 -0
  489. data/lib/libcouchbase/ext/libcouchbase/cmdstoredur.rb +45 -0
  490. data/lib/libcouchbase/ext/libcouchbase/cmdsubdoc.rb +49 -0
  491. data/lib/libcouchbase/ext/libcouchbase/cmdverbosity.rb +29 -0
  492. data/lib/libcouchbase/ext/libcouchbase/cmdviewquery.rb +61 -0
  493. data/lib/libcouchbase/ext/libcouchbase/contigbuf.rb +14 -0
  494. data/lib/libcouchbase/ext/libcouchbase/create_st.rb +15 -0
  495. data/lib/libcouchbase/ext/libcouchbase/create_st0.rb +23 -0
  496. data/lib/libcouchbase/ext/libcouchbase/create_st1.rb +26 -0
  497. data/lib/libcouchbase/ext/libcouchbase/create_st2.rb +32 -0
  498. data/lib/libcouchbase/ext/libcouchbase/create_st3.rb +26 -0
  499. data/lib/libcouchbase/ext/libcouchbase/crst_u.rb +20 -0
  500. data/lib/libcouchbase/ext/libcouchbase/durability_opts_st_v.rb +11 -0
  501. data/lib/libcouchbase/ext/libcouchbase/durability_opts_t.rb +14 -0
  502. data/lib/libcouchbase/ext/libcouchbase/durabilityopt_sv0.rb +63 -0
  503. data/lib/libcouchbase/ext/libcouchbase/enums.rb +991 -0
  504. data/lib/libcouchbase/ext/libcouchbase/fragbuf.rb +18 -0
  505. data/lib/libcouchbase/ext/libcouchbase/ftshandle.rb +7 -0
  506. data/lib/libcouchbase/ext/libcouchbase/histogram.rb +34 -0
  507. data/lib/libcouchbase/ext/libcouchbase/http_request_t.rb +7 -0
  508. data/lib/libcouchbase/ext/libcouchbase/keybuf.rb +20 -0
  509. data/lib/libcouchbase/ext/libcouchbase/multicmd_ctx.rb +30 -0
  510. data/lib/libcouchbase/ext/libcouchbase/mutation_token.rb +17 -0
  511. data/lib/libcouchbase/ext/libcouchbase/n1qlhandle.rb +7 -0
  512. data/lib/libcouchbase/ext/libcouchbase/n1qlparams.rb +7 -0
  513. data/lib/libcouchbase/ext/libcouchbase/respbase.rb +29 -0
  514. data/lib/libcouchbase/ext/libcouchbase/respcounter.rb +32 -0
  515. data/lib/libcouchbase/ext/libcouchbase/respendure.rb +49 -0
  516. data/lib/libcouchbase/ext/libcouchbase/respfts.rb +40 -0
  517. data/lib/libcouchbase/ext/libcouchbase/respget.rb +44 -0
  518. data/lib/libcouchbase/ext/libcouchbase/resphttp.rb +48 -0
  519. data/lib/libcouchbase/ext/libcouchbase/respmcversion.rb +38 -0
  520. data/lib/libcouchbase/ext/libcouchbase/respn1ql.rb +41 -0
  521. data/lib/libcouchbase/ext/libcouchbase/respobseqno.rb +52 -0
  522. data/lib/libcouchbase/ext/libcouchbase/respobserve.rb +41 -0
  523. data/lib/libcouchbase/ext/libcouchbase/respserverbase.rb +32 -0
  524. data/lib/libcouchbase/ext/libcouchbase/respstats.rb +38 -0
  525. data/lib/libcouchbase/ext/libcouchbase/respstore.rb +32 -0
  526. data/lib/libcouchbase/ext/libcouchbase/respstoredur.rb +38 -0
  527. data/lib/libcouchbase/ext/libcouchbase/respsubdoc.rb +35 -0
  528. data/lib/libcouchbase/ext/libcouchbase/respviewquery.rb +67 -0
  529. data/lib/libcouchbase/ext/libcouchbase/sdentry.rb +22 -0
  530. data/lib/libcouchbase/ext/libcouchbase/sdspec.rb +26 -0
  531. data/lib/libcouchbase/ext/libcouchbase/t.rb +7 -0
  532. data/lib/libcouchbase/ext/libcouchbase/valbuf.rb +22 -0
  533. data/lib/libcouchbase/ext/libcouchbase/valbuf_u_buf.rb +14 -0
  534. data/lib/libcouchbase/ext/libcouchbase/viewhandle.rb +7 -0
  535. data/lib/libcouchbase/ext/libcouchbase_iocp.rb +26 -0
  536. data/lib/libcouchbase/ext/libcouchbase_libuv.rb +18 -0
  537. data/lib/libcouchbase/ext/tasks.rb +87 -0
  538. data/lib/libcouchbase/n1ql.rb +73 -0
  539. data/lib/libcouchbase/query_full_text.rb +147 -0
  540. data/lib/libcouchbase/query_n1ql.rb +121 -0
  541. data/lib/libcouchbase/query_view.rb +129 -0
  542. data/lib/libcouchbase/results_fiber.rb +262 -0
  543. data/lib/libcouchbase/results_native.rb +211 -0
  544. data/lib/libcouchbase/version.rb +5 -0
  545. data/libcouchbase.gemspec +61 -0
  546. data/spec/bucket_spec.rb +270 -0
  547. data/spec/connection_spec.rb +277 -0
  548. data/spec/design_docs_spec.rb +23 -0
  549. data/spec/error_spec.rb +26 -0
  550. data/spec/fts_spec.rb +129 -0
  551. data/spec/n1ql_spec.rb +201 -0
  552. data/spec/results_libuv_spec.rb +229 -0
  553. data/spec/results_native_spec.rb +259 -0
  554. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/design.json +1 -0
  555. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/data-0000.cbb +0 -0
  556. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/failover.json +1 -0
  557. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/meta.json +1 -0
  558. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/seqno.json +1 -0
  559. data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/snapshot_markers.json +1 -0
  560. data/spec/view_spec.rb +195 -0
  561. metadata +775 -0
@@ -0,0 +1,117 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2012 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include "config.h"
19
+ #include "iotests.h"
20
+
21
+ #include <cstdio>
22
+
23
+ class ConfigCacheUnitTest : public MockUnitTest
24
+ {
25
+ };
26
+
27
+ extern "C" {
28
+ static void bootstrap_callback(lcb_t instance, lcb_error_t err)
29
+ {
30
+ EXPECT_EQ(LCB_SUCCESS, err);
31
+ int *pp = (int *)lcb_get_cookie(instance);
32
+ *pp += 1;
33
+ }
34
+ }
35
+
36
+ TEST_F(ConfigCacheUnitTest, testConfigCache)
37
+ {
38
+ lcb_t instance;
39
+ lcb_error_t err;
40
+ lcb_create_st cropts;
41
+
42
+ // Get the filename:
43
+ char filename[L_tmpnam + 0];
44
+ ASSERT_TRUE(NULL != tmpnam(filename));
45
+ memset(&cropts, 0, sizeof(cropts));
46
+
47
+ MockEnvironment::getInstance()->makeConnectParams(cropts, NULL);
48
+ doLcbCreate(&instance, &cropts, MockEnvironment::getInstance());
49
+ err = lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_CONFIGCACHE, (void *)filename);
50
+ ASSERT_EQ(LCB_SUCCESS, err);
51
+
52
+ int is_loaded;
53
+ err = lcb_cntl(instance, LCB_CNTL_GET,
54
+ LCB_CNTL_CONFIG_CACHE_LOADED, &is_loaded);
55
+
56
+ ASSERT_EQ(err, LCB_SUCCESS);
57
+ ASSERT_EQ(is_loaded, 0);
58
+
59
+ err = lcb_connect(instance);
60
+ ASSERT_EQ(err, LCB_SUCCESS);
61
+
62
+ err = lcb_wait(instance);
63
+ ASSERT_EQ(err, LCB_SUCCESS);
64
+
65
+ // now try another one
66
+ lcb_destroy(instance);
67
+ doLcbCreate(&instance, &cropts, MockEnvironment::getInstance());
68
+ ASSERT_EQ(LCB_SUCCESS, err);
69
+ err = lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_CONFIGCACHE, (void *)filename);
70
+ ASSERT_EQ(LCB_SUCCESS, err);
71
+ lcb_set_bootstrap_callback(instance, bootstrap_callback);
72
+ int bsCalled = 0;
73
+ lcb_set_cookie(instance, &bsCalled);
74
+
75
+ err = lcb_connect(instance);
76
+ ASSERT_EQ(LCB_SUCCESS, err);
77
+
78
+ err = lcb_wait(instance);
79
+ ASSERT_EQ(LCB_SUCCESS, err);
80
+
81
+ err = lcb_cntl(instance, LCB_CNTL_GET,
82
+ LCB_CNTL_CONFIG_CACHE_LOADED, &is_loaded);
83
+ ASSERT_NE(0, is_loaded);
84
+ ASSERT_EQ(1, bsCalled);
85
+
86
+ /* Just make sure we can schedule a command */
87
+ storeKey(instance, "a_key", "a_value");
88
+
89
+ lcb_destroy(instance);
90
+
91
+ doLcbCreate(&instance, &cropts, MockEnvironment::getInstance());
92
+ ASSERT_EQ(LCB_SUCCESS, err);
93
+ err = lcb_cntl_string(instance, "config_cache", filename);
94
+ ASSERT_EQ(LCB_SUCCESS, err);
95
+ err = lcb_connect(instance);
96
+ ASSERT_EQ(LCB_SUCCESS, err);
97
+ lcb_wait(instance);
98
+ err = lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_CONFIG_CACHE_LOADED, &is_loaded);
99
+ ASSERT_EQ(LCB_SUCCESS, err);
100
+ ASSERT_NE(0, is_loaded);
101
+ lcb_destroy(instance);
102
+
103
+ doLcbCreate(&instance, &cropts, MockEnvironment::getInstance());
104
+ ASSERT_EQ(LCB_SUCCESS, err);
105
+ err = lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_CONFIGCACHE_RO, (void *)filename);
106
+ ASSERT_EQ(LCB_SUCCESS, err);
107
+ lcb_destroy(instance);
108
+
109
+ remove(filename);
110
+
111
+ // Try one more time, with a file that does not exist..
112
+ doLcbCreate(&instance, &cropts, MockEnvironment::getInstance());
113
+ ASSERT_EQ(LCB_SUCCESS, err);
114
+ err = lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_CONFIGCACHE_RO, (void *)filename);
115
+ ASSERT_NE(LCB_SUCCESS, err);
116
+ lcb_destroy(instance);
117
+ }
@@ -0,0 +1,241 @@
1
+ #define LCB_BOOTSTRAP_DEFINE_STRUCT
2
+
3
+ #include "iotests.h"
4
+ #include "config.h"
5
+ #include "internal.h"
6
+ #include "bucketconfig/clconfig.h"
7
+ #include <lcbio/iotable.h>
8
+ #include <set>
9
+
10
+ class Confmon : public ::testing::Test
11
+ {
12
+ void SetUp() {
13
+ MockEnvironment::Reset();
14
+ }
15
+ };
16
+
17
+ struct evstop_listener {
18
+ clconfig_listener base;
19
+ lcbio_pTABLE io;
20
+ int called;
21
+ };
22
+
23
+ extern "C" {
24
+ static void listen_callback1(clconfig_listener *lsn, clconfig_event_t event,
25
+ clconfig_info *info)
26
+ {
27
+ if (event != CLCONFIG_EVENT_GOT_NEW_CONFIG) {
28
+ return;
29
+ }
30
+
31
+ evstop_listener *me = reinterpret_cast<evstop_listener*>(lsn);
32
+ me->called = 1;
33
+ IOT_STOP(me->io);
34
+ }
35
+ }
36
+
37
+ TEST_F(Confmon, testBasic)
38
+ {
39
+ HandleWrap hw;
40
+ lcb_t instance;
41
+ MockEnvironment::getInstance()->createConnection(hw, instance);
42
+
43
+
44
+ lcb_confmon *mon = lcb_confmon_create(instance->settings, instance->iotable);
45
+ clconfig_provider *http = lcb_confmon_get_provider(mon, LCB_CLCONFIG_HTTP);
46
+ lcb_clconfig_http_enable(http);
47
+ lcb_clconfig_http_set_nodes(http, instance->ht_nodes);
48
+
49
+ lcb_confmon_prepare(mon);
50
+
51
+ EXPECT_EQ(NULL, lcb_confmon_get_config(mon));
52
+ EXPECT_EQ(LCB_SUCCESS, lcb_confmon_start(mon));
53
+ EXPECT_EQ(LCB_SUCCESS, lcb_confmon_start(mon));
54
+ EXPECT_EQ(LCB_SUCCESS, lcb_confmon_stop(mon));
55
+ EXPECT_EQ(LCB_SUCCESS, lcb_confmon_stop(mon));
56
+
57
+ // Try to find a provider..
58
+ clconfig_provider *provider = lcb_confmon_get_provider(mon, LCB_CLCONFIG_HTTP);
59
+ ASSERT_NE(0, provider->enabled);
60
+
61
+ struct evstop_listener listener;
62
+ memset(&listener, 0, sizeof(listener));
63
+
64
+ listener.base.callback = listen_callback1;
65
+ listener.base.parent = mon;
66
+ listener.io = instance->iotable;
67
+
68
+ lcb_confmon_add_listener(mon, &listener.base);
69
+ lcb_confmon_start(mon);
70
+ IOT_START(instance->iotable);
71
+ ASSERT_NE(0, listener.called);
72
+
73
+ lcb_confmon_destroy(mon);
74
+ }
75
+
76
+
77
+ struct listener2 {
78
+ clconfig_listener base;
79
+ int call_count;
80
+ lcbio_pTABLE io;
81
+ clconfig_method_t last_source;
82
+ std::set<clconfig_event_t> expected_events;
83
+
84
+ void reset() {
85
+ call_count = 0;
86
+ last_source = LCB_CLCONFIG_PHONY;
87
+ expected_events.clear();
88
+ }
89
+
90
+ listener2() {
91
+ memset(&base, 0, sizeof(base));
92
+ io = NULL;
93
+ reset();
94
+ }
95
+ };
96
+
97
+ static struct listener2* getListener2(const void *p)
98
+ {
99
+ return reinterpret_cast<struct listener2*>(const_cast<void*>(p));
100
+ }
101
+
102
+ extern "C" {
103
+ static void listen_callback2(clconfig_listener *prov,
104
+ clconfig_event_t event,
105
+ clconfig_info *info)
106
+ {
107
+ // Increase the number of times we've received a callback..
108
+ struct listener2* lsn = getListener2(prov);
109
+
110
+ if (event == CLCONFIG_EVENT_MONITOR_STOPPED) {
111
+ IOT_START(lsn->io);
112
+ return;
113
+ }
114
+
115
+ if (!lsn->expected_events.empty()) {
116
+ if (lsn->expected_events.end() ==
117
+ lsn->expected_events.find(event)) {
118
+ return;
119
+ }
120
+ }
121
+
122
+ lsn->call_count++;
123
+ lsn->last_source = info->origin;
124
+ IOT_STOP(lsn->io);
125
+ }
126
+ }
127
+
128
+ static void runConfmon(lcbio_pTABLE io, lcb_confmon *mon)
129
+ {
130
+ IOT_START(io);
131
+ }
132
+
133
+ TEST_F(Confmon, testCycle)
134
+ {
135
+ HandleWrap hw;
136
+ lcb_t instance;
137
+ lcb_create_st cropts;
138
+ MockEnvironment *mock = MockEnvironment::getInstance();
139
+
140
+ if (mock->isRealCluster()) {
141
+ return;
142
+ }
143
+
144
+ mock->createConnection(hw, instance);
145
+ instance->settings->bc_http_stream_time = 100000;
146
+ instance->memd_sockpool->tmoidle = 100000;
147
+
148
+ lcb_confmon *mon = lcb_confmon_create(instance->settings, instance->iotable);
149
+
150
+ struct listener2 lsn;
151
+ lsn.base.callback = listen_callback2;
152
+ lsn.io = instance->iotable;
153
+ lsn.reset();
154
+
155
+ lcb_confmon_add_listener(mon, &lsn.base);
156
+
157
+ mock->makeConnectParams(cropts, NULL);
158
+ clconfig_provider *cccp = lcb_confmon_get_provider(mon, LCB_CLCONFIG_CCCP);
159
+ clconfig_provider *http = lcb_confmon_get_provider(mon, LCB_CLCONFIG_HTTP);
160
+
161
+ hostlist_t hl = hostlist_create();
162
+ hostlist_add_stringz(hl, cropts.v.v2.mchosts, 11210);
163
+ lcb_clconfig_cccp_enable(cccp, instance);
164
+ lcb_clconfig_cccp_set_nodes(cccp, hl);
165
+
166
+ lcb_clconfig_http_enable(http);
167
+ lcb_clconfig_http_set_nodes(http, instance->ht_nodes);
168
+ hostlist_destroy(hl);
169
+
170
+ lcb_confmon_prepare(mon);
171
+ lcb_confmon_start(mon);
172
+ lsn.expected_events.insert(CLCONFIG_EVENT_GOT_NEW_CONFIG);
173
+ runConfmon(lsn.io, mon);
174
+
175
+ // Ensure CCCP is functioning properly and we're called only once.
176
+ ASSERT_EQ(1, lsn.call_count);
177
+ ASSERT_EQ(LCB_CLCONFIG_CCCP, lsn.last_source);
178
+
179
+ lcb_confmon_start(mon);
180
+ lsn.reset();
181
+ lsn.expected_events.insert(CLCONFIG_EVENT_GOT_ANY_CONFIG);
182
+ runConfmon(lsn.io, mon);
183
+ ASSERT_EQ(1, lsn.call_count);
184
+ ASSERT_EQ(LCB_CLCONFIG_CCCP, lsn.last_source);
185
+
186
+ mock->setCCCP(false);
187
+ mock->failoverNode(5);
188
+ lsn.reset();
189
+ lcb_confmon_start(mon);
190
+ lsn.expected_events.insert(CLCONFIG_EVENT_GOT_ANY_CONFIG);
191
+ lsn.expected_events.insert(CLCONFIG_EVENT_GOT_NEW_CONFIG);
192
+ runConfmon(lsn.io, mon);
193
+ ASSERT_EQ(LCB_CLCONFIG_HTTP, lsn.last_source);
194
+ ASSERT_EQ(1, lsn.call_count);
195
+ lcb_confmon_destroy(mon);
196
+ }
197
+
198
+ TEST_F(Confmon, testBootstrapMethods)
199
+ {
200
+ lcb_t instance;
201
+ HandleWrap hw;
202
+ MockEnvironment::getInstance()->createConnection(hw, instance);
203
+ lcb_error_t err = lcb_connect(instance);
204
+ ASSERT_EQ(LCB_SUCCESS, err);
205
+
206
+ // Try the various bootstrap times
207
+ struct lcb_BOOTSTRAP *bs = instance->bootstrap;
208
+ hrtime_t last = bs->last_refresh, cur = 0;
209
+
210
+ // Reset it for the time being
211
+ bs->last_refresh = 0;
212
+ lcb_confmon_stop(instance->confmon);
213
+
214
+ // Refreshing now should work
215
+ lcb_bootstrap_common(instance, LCB_BS_REFRESH_THROTTLE);
216
+ ASSERT_NE(0, lcb_confmon_is_refreshing(instance->confmon));
217
+
218
+ cur = bs->last_refresh;
219
+ ASSERT_GT(cur, 0);
220
+ ASSERT_EQ(0, bs->errcounter);
221
+ last = cur;
222
+
223
+ // Stop it, so the state is reset
224
+ lcb_confmon_stop(instance->confmon);
225
+ ASSERT_EQ(0, lcb_confmon_is_refreshing(instance->confmon));
226
+
227
+ lcb_bootstrap_common(instance, LCB_BS_REFRESH_THROTTLE|LCB_BS_REFRESH_INCRERR);
228
+ ASSERT_EQ(last, bs->last_refresh);
229
+ ASSERT_EQ(1, bs->errcounter);
230
+
231
+ // Ensure that a throttled-without-incr doesn't actually incr
232
+ lcb_bootstrap_common(instance, LCB_BS_REFRESH_THROTTLE);
233
+ ASSERT_EQ(1, bs->errcounter);
234
+
235
+ // No refresh yet
236
+ ASSERT_EQ(0, lcb_confmon_is_refreshing(instance->confmon));
237
+
238
+ lcb_bootstrap_common(instance, LCB_BS_REFRESH_ALWAYS);
239
+ ASSERT_NE(0, lcb_confmon_is_refreshing(instance->confmon));
240
+ lcb_confmon_stop(instance->confmon);
241
+ }
@@ -0,0 +1,1059 @@
1
+ #include "config.h"
2
+ #include "iotests.h"
3
+ #include "internal.h"
4
+ #include <map>
5
+
6
+ using namespace std;
7
+
8
+ #define LOGARGS(instance, lvl) \
9
+ instance->settings, "tests-dur", LCB_LOG_##lvl, __FILE__, __LINE__
10
+ #define SECS_USECS(f) ((f) * 1000000)
11
+
12
+ static bool supportsMutationTokens(lcb_t instance)
13
+ {
14
+ // Ensure we have at least one connection
15
+ storeKey(instance, "dummy_stok_test", "dummy");
16
+
17
+ int val = 0;
18
+ lcb_error_t rc;
19
+ rc = lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_MUTATION_TOKENS_SUPPORTED, &val);
20
+
21
+
22
+ EXPECT_EQ(LCB_SUCCESS, rc);
23
+ if (val == 0) {
24
+ printf("Current cluster does not support synctokens!\n");
25
+ return false;
26
+ } else {
27
+ return true;
28
+ }
29
+ }
30
+
31
+ class DurabilityUnitTest : public MockUnitTest
32
+ {
33
+ protected:
34
+ static void defaultOptions(lcb_t instance, lcb_durability_opts_st &opts) {
35
+ lcb_size_t nservers = lcb_get_num_nodes(instance);
36
+ lcb_size_t nreplicas = lcb_get_num_replicas(instance);
37
+
38
+ opts.v.v0.persist_to = (lcb_uint16_t) min(nreplicas + 1, nservers);
39
+ opts.v.v0.replicate_to = (lcb_uint16_t) min(nreplicas, nservers - 1);
40
+ }
41
+ };
42
+
43
+ extern "C" {
44
+ static void defaultDurabilityCallback(lcb_t, int, const lcb_RESPENDURE*);
45
+ static void multiDurabilityCallback(lcb_t, int, const lcb_RESPENDURE*);
46
+ }
47
+
48
+ class DurabilityOperation
49
+ {
50
+ public:
51
+ DurabilityOperation() {
52
+ }
53
+
54
+ string key;
55
+ lcb_RESPENDURE resp;
56
+ lcb_CMDENDURE req;
57
+
58
+ void assign(const lcb_RESPENDURE *resp) {
59
+ this->resp = *resp;
60
+ key.assign((const char *)resp->key, resp->nkey);
61
+ this->resp.key = NULL;
62
+ }
63
+
64
+ void wait(lcb_t instance) {
65
+ lcb_install_callback3(instance, LCB_CALLBACK_ENDURE,
66
+ (lcb_RESPCALLBACK)defaultDurabilityCallback);
67
+ EXPECT_EQ(LCB_SUCCESS, lcb_wait(instance));
68
+ }
69
+
70
+ void wait(lcb_t instance,
71
+ const lcb_durability_opts_t *opts, const lcb_CMDENDURE *cmd) {
72
+
73
+ lcb_error_t rc;
74
+ lcb_MULTICMD_CTX *mctx = lcb_endure3_ctxnew(instance, opts, &rc);
75
+ EXPECT_FALSE(mctx == NULL);
76
+ rc = mctx->addcmd(mctx, (lcb_CMDBASE*)cmd);
77
+ EXPECT_EQ(LCB_SUCCESS, rc);
78
+ rc = mctx->done(mctx, this);
79
+ EXPECT_EQ(LCB_SUCCESS, rc);
80
+ wait(instance);
81
+ }
82
+
83
+ void run(lcb_t instance, const lcb_durability_opts_t *opts, const Item &itm) {
84
+ lcb_CMDENDURE cmd = { 0 };
85
+ ASSERT_FALSE(itm.key.empty());
86
+ LCB_CMD_SET_KEY(&cmd, itm.key.data(), itm.key.length());
87
+ cmd.cas = itm.cas;
88
+ wait(instance, opts, &cmd);
89
+ }
90
+
91
+ // Really wait(), but named as 'run()' here to make usage more consistent.
92
+ void run(lcb_t instance, const lcb_durability_opts_t *opts,
93
+ const lcb_CMDENDURE& cmd) {
94
+ wait(instance, opts, &cmd);
95
+ }
96
+
97
+ void assertCriteriaMatch(const lcb_durability_opts_st &opts) {
98
+ ASSERT_EQ(LCB_SUCCESS, resp.rc);
99
+ ASSERT_TRUE(resp.persisted_master != 0);
100
+ ASSERT_TRUE(opts.v.v0.persist_to <= resp.npersisted);
101
+ ASSERT_TRUE(opts.v.v0.replicate_to <= resp.nreplicated);
102
+ }
103
+
104
+ void dump(std::string &str) {
105
+ if (key.empty()) {
106
+ str = "<No Key>\n";
107
+ return;
108
+ }
109
+ std::stringstream ss;
110
+ ss << "Key: " << key << std::endl
111
+ << "Error: " << resp.rc << std::endl
112
+ << "Persisted (master?): " << resp.npersisted
113
+ << " (" << resp.persisted_master << ")" << std::endl
114
+ << "Replicated: " << resp.nreplicated << std::endl
115
+ << "CAS: 0x" << std::hex << resp.cas << std::endl;
116
+ str += ss.str();
117
+ }
118
+
119
+ void dump() {
120
+ string s;
121
+ dump(s);
122
+ cout << s;
123
+ }
124
+ };
125
+
126
+ class DurabilityMultiOperation
127
+ {
128
+ public:
129
+
130
+ DurabilityMultiOperation() : counter(0) {
131
+ }
132
+
133
+ template <typename T>
134
+ void run(lcb_t instance, const lcb_durability_opts_t *opts, const T &items) {
135
+ counter = 0;
136
+ unsigned ii = 0;
137
+ typename T::const_iterator iter = items.begin();
138
+ lcb_error_t rc;
139
+ lcb_MULTICMD_CTX *mctx = lcb_endure3_ctxnew(instance, opts, &rc);
140
+ ASSERT_FALSE(mctx == NULL);
141
+
142
+ for (; iter != items.end(); iter++, ii++) {
143
+ lcb_CMDENDURE cmd = { 0 };
144
+ const Item &itm = *iter;
145
+
146
+ cmd.cas = itm.cas;
147
+ LCB_CMD_SET_KEY(&cmd, itm.key.c_str(), itm.key.length());
148
+ rc = mctx->addcmd(mctx, (lcb_CMDBASE*)&cmd);
149
+ ASSERT_EQ(LCB_SUCCESS, rc);
150
+ kmap[itm.key] = DurabilityOperation();
151
+ }
152
+
153
+ lcb_install_callback3(instance, LCB_CALLBACK_ENDURE,
154
+ (lcb_RESPCALLBACK)multiDurabilityCallback);
155
+
156
+ rc = mctx->done(mctx, this);
157
+ ASSERT_EQ(LCB_SUCCESS, rc);
158
+ lcb_wait(instance);
159
+ ASSERT_EQ(items.size(), counter);
160
+ }
161
+
162
+ void assign(const lcb_RESPENDURE *resp) {
163
+ ASSERT_GT(resp->nkey, 0U);
164
+ counter++;
165
+
166
+ string key;
167
+ key.assign((const char *)resp->key, resp->nkey);
168
+ ASSERT_TRUE(kmap.find(key) != kmap.end());
169
+ kmap[key].assign(resp);
170
+ }
171
+
172
+ template <typename T>
173
+ bool _findItem(const string &s, const T &items, Item &itm) {
174
+ for (typename T::const_iterator iter = items.begin();
175
+ iter != items.end(); iter++) {
176
+ if (iter->key.compare(s) == 0) {
177
+ itm = *iter;
178
+ return true;
179
+ }
180
+ }
181
+ return false;
182
+ }
183
+
184
+ template <typename T>
185
+ void assertAllMatch(const lcb_durability_opts_t &opts,
186
+ const T &items_ok,
187
+ const T &items_missing,
188
+ lcb_error_t missing_err = LCB_KEY_ENOENT) {
189
+
190
+ for (map<string, DurabilityOperation>::iterator iter = kmap.begin();
191
+ iter != kmap.end();
192
+ iter++) {
193
+
194
+ Item itm_tmp;
195
+ // make sure we were expecting it
196
+ if (_findItem(iter->second.key, items_ok, itm_tmp)) {
197
+ iter->second.assertCriteriaMatch(opts);
198
+
199
+ } else if (_findItem(iter->second.key, items_missing, itm_tmp)) {
200
+ ASSERT_EQ(missing_err, iter->second.resp.rc);
201
+
202
+ } else {
203
+ ASSERT_STREQ("",
204
+ "Key not in missing or OK list");
205
+ }
206
+ }
207
+
208
+ // Finally, make sure they're all there
209
+
210
+ for (typename T::const_iterator iter = items_ok.begin();
211
+ iter != items_ok.end();
212
+ iter++) {
213
+ ASSERT_TRUE(kmap.find(iter->key) != kmap.end());
214
+ }
215
+
216
+ for (typename T::const_iterator iter = items_missing.begin();
217
+ iter != items_missing.end(); iter++) {
218
+ ASSERT_TRUE(kmap.find(iter->key) != kmap.end());
219
+ }
220
+ }
221
+
222
+ unsigned counter;
223
+ map<string, DurabilityOperation> kmap;
224
+ };
225
+
226
+ extern "C" {
227
+ static void defaultDurabilityCallback(lcb_t, int, const lcb_RESPENDURE *res)
228
+ {
229
+ ((DurabilityOperation*)res->cookie)->assign(res);
230
+ }
231
+ static void multiDurabilityCallback(lcb_t, int, const lcb_RESPENDURE *res)
232
+ {
233
+ ((DurabilityMultiOperation*)res->cookie)->assign(res);
234
+ }
235
+
236
+ }
237
+
238
+ TEST_F(DurabilityUnitTest, testInvalidCriteria)
239
+ {
240
+ /**
241
+ * We don't schedule stuff to the network here
242
+ */
243
+ HandleWrap hwrap;
244
+ createConnection(hwrap);
245
+
246
+ lcb_t instance = hwrap.getLcb();
247
+
248
+ lcb_durability_opts_t opts = { 0 };
249
+ lcb_durability_cmd_t cmd = { 0 }, *cmd_p = &cmd;
250
+ lcb_error_t err;
251
+
252
+ defaultOptions(instance, opts);
253
+
254
+ err = lcb_durability_poll(instance, NULL, &opts, 0, &cmd_p);
255
+ ASSERT_EQ(LCB_EINVAL, err);
256
+
257
+ opts.v.v0.persist_to = 10;
258
+ opts.v.v0.replicate_to = 100;
259
+ opts.v.v0.cap_max = 0;
260
+
261
+ err = lcb_durability_poll(instance, NULL, &opts, 1, &cmd_p);
262
+ ASSERT_EQ(err, LCB_DURABILITY_ETOOMANY);
263
+ }
264
+
265
+ /**
266
+ * Test various criteria for durability
267
+ */
268
+ TEST_F(DurabilityUnitTest, testDurabilityCriteria)
269
+ {
270
+ HandleWrap hwrap;
271
+ lcb_t instance;
272
+
273
+ createConnection(hwrap);
274
+ instance = hwrap.getLcb();
275
+
276
+ lcb_durability_opts_st opts = { 0 };
277
+ lcb_durability_cmd_st cmd = { 0 };
278
+ lcb_durability_cmd_st *cmd_p = &cmd;
279
+
280
+ /** test with no persist/replicate */
281
+ defaultOptions(instance, opts);
282
+
283
+ opts.v.v0.replicate_to = 0;
284
+ opts.v.v0.persist_to = 0;
285
+ }
286
+
287
+ /**
288
+ * @test Test several 'basic' durability functions
289
+ *
290
+ * @pre Store a key. Perform a durability check with master-only persistence
291
+ * (i.e. persist_to = 1, replicate_to = 0)
292
+ * @post Operation succeeds
293
+ *
294
+ * @pre Check the key against 'maximum possible' durability by estimating the
295
+ * maximum replica/server count
296
+ *
297
+ * @post Operation succeeds
298
+ *
299
+ * @pre Set the durability options to a very large criteria, but set the
300
+ * @c cap_max flag so the API will reduce it to a sane default. Then use it
301
+ * for a durability check
302
+ *
303
+ * @post the response is successful
304
+ */
305
+ TEST_F(DurabilityUnitTest, testSimpleDurability)
306
+ {
307
+ /** need real cluster for durability tests */
308
+ LCB_TEST_REQUIRE_FEATURE("observe");
309
+ SKIP_UNLESS_MOCK();
310
+
311
+ HandleWrap hwrap;
312
+ lcb_t instance;
313
+
314
+ Item kv = Item("a_key", "a_value", 0);
315
+ createConnection(hwrap);
316
+ instance = hwrap.getLcb();
317
+
318
+ removeKey(instance, kv.key);
319
+
320
+ KVOperation kvo = KVOperation(&kv);
321
+ kvo.store(instance);
322
+
323
+ // Now wait for it to persist
324
+ lcb_durability_opts_t opts;
325
+ memset(&opts, 0, sizeof(opts));
326
+ opts.v.v0.persist_to = 1;
327
+ opts.v.v0.replicate_to = 0;
328
+
329
+ kvo = KVOperation(&kv);
330
+ kvo.get(instance);
331
+
332
+ DurabilityOperation dop;
333
+ dop.run(instance, &opts, kvo.result);
334
+
335
+ dop.assertCriteriaMatch(opts);
336
+ ASSERT_STREQ(kv.key.c_str(), dop.key.c_str());
337
+
338
+
339
+ // Try with more expanded criteria
340
+ defaultOptions(instance, opts);
341
+ dop = DurabilityOperation();
342
+ dop.run(instance, &opts, kvo.result);
343
+ dop.assertCriteriaMatch(opts);
344
+
345
+ // Make the options to some absurd number. Ensure it's capped!
346
+ opts.v.v0.persist_to = 100;
347
+ opts.v.v0.replicate_to = 100;
348
+ opts.v.v0.cap_max = 1;
349
+
350
+ dop = DurabilityOperation();
351
+ dop.run(instance, &opts, kvo.result);
352
+ defaultOptions(instance, opts);
353
+ dop.assertCriteriaMatch(opts);
354
+ }
355
+
356
+ /**
357
+ * @test Durability checks against non-existent keys
358
+ * @pre Remove a key, and perform a durability check against it
359
+ * @post Operation fails with @c LCB_KEY_ENOENT
360
+ */
361
+ TEST_F(DurabilityUnitTest, testNonExist)
362
+ {
363
+ LCB_TEST_REQUIRE_FEATURE("observe");
364
+ SKIP_UNLESS_MOCK();
365
+
366
+ lcb_t instance;
367
+ HandleWrap hwrap;
368
+
369
+ string key = "non-exist-key";
370
+
371
+ createConnection(hwrap);
372
+ instance = hwrap.getLcb();
373
+
374
+ removeKey(instance, key);
375
+
376
+ Item itm = Item(key, "", 0);
377
+
378
+ DurabilityOperation dop;
379
+ lcb_durability_opts_t opts = { 0 };
380
+ opts.v.v0.timeout = SECS_USECS(2);
381
+
382
+ defaultOptions(instance, opts);
383
+
384
+ // Ensure this only uses the CAS method
385
+ opts.version = 1;
386
+ opts.v.v0.pollopts = LCB_DURABILITY_MODE_CAS;
387
+
388
+ dop.run(instance, &opts, itm);
389
+ ASSERT_EQ(LCB_KEY_ENOENT, dop.resp.rc);
390
+ }
391
+
392
+ /**
393
+ * @test Test negative durability (Delete)
394
+ *
395
+ * @pre Store a key, Remove it, perform a durability check against the key,
396
+ * using the @c check_delete flag
397
+ *
398
+ * @post A positive reply is received indicating the item has been deleted
399
+ *
400
+ * @pre Store the key, but don't remove it. Perform a durability check against
401
+ * the key using the delete flag
402
+ *
403
+ * @post Operation is returned with @c LCB_ETIMEDOUT
404
+ */
405
+ TEST_F(DurabilityUnitTest, testDelete)
406
+ {
407
+ LCB_TEST_REQUIRE_FEATURE("observe");
408
+ SKIP_UNLESS_MOCK();
409
+
410
+ HandleWrap hwrap;
411
+ lcb_t instance;
412
+ lcb_durability_opts_t opts = { 0 };
413
+ string key = "deleted-key";
414
+ createConnection(hwrap);
415
+ instance = hwrap.getLcb();
416
+
417
+ storeKey(instance, key, "value");
418
+
419
+ Item itm = Item(key, "value", 0);
420
+
421
+ KVOperation kvo = KVOperation(&itm);
422
+ DurabilityOperation dop;
423
+
424
+ kvo.remove(instance);
425
+
426
+ // Ensure the key is actually purged!
427
+ MockMutationCommand mcmd(MockCommand::PURGE, key);
428
+ mcmd.onMaster = true;
429
+ mcmd.replicaCount = lcb_get_num_replicas(instance);
430
+ doMockTxn(mcmd);
431
+
432
+ defaultOptions(instance, opts);
433
+ opts.v.v0.check_delete = 1;
434
+ dop.run(instance, &opts, itm);
435
+ dop.assertCriteriaMatch(opts);
436
+
437
+ kvo.clear();
438
+ kvo.request = &itm;
439
+ kvo.store(instance);
440
+
441
+ opts.v.v0.timeout = SECS_USECS(1);
442
+
443
+ // With CAS
444
+ opts.version = 1;
445
+ opts.v.v0.pollopts = LCB_DURABILITY_MODE_CAS;
446
+ dop = DurabilityOperation();
447
+ dop.run(instance, &opts, itm);
448
+ ASSERT_EQ(LCB_ETIMEDOUT, dop.resp.rc);
449
+
450
+ // With seqno
451
+ if (supportsMutationTokens(instance)) {
452
+ opts.v.v0.pollopts = LCB_DURABILITY_MODE_SEQNO;
453
+ dop = DurabilityOperation();
454
+ dop.run(instance, &opts, itm);
455
+ ASSERT_EQ(LCB_SUCCESS, dop.resp.rc);
456
+ }
457
+ }
458
+
459
+ /**
460
+ * @test Test behavior when a key is modified (exists with a different CAS)
461
+ *
462
+ * @pre Store a key. Store it again. Keep the CAS from the first store as the
463
+ * stale CAS. Keep the current CAS as well.
464
+ *
465
+ * @pre Perform a durability check against the stale CAS
466
+ * @post Operation fails with @c LCB_KEY_EEXISTS
467
+ *
468
+ * @pre Perform a durability check against the new CAS
469
+ * @post Operation succeeds
470
+ */
471
+ TEST_F(DurabilityUnitTest, testModified)
472
+ {
473
+ LCB_TEST_REQUIRE_FEATURE("observe");
474
+
475
+ HandleWrap hwrap;
476
+ lcb_t instance;
477
+ lcb_durability_opts_t opts = { 0 };
478
+ string key = "mutated-key";
479
+ Item itm = Item(key, key);
480
+ KVOperation kvo_cur(&itm), kvo_stale(&itm);
481
+
482
+ createConnection(hwrap);
483
+ instance = hwrap.getLcb();
484
+
485
+ kvo_stale.store(instance);
486
+ kvo_cur.store(instance);
487
+
488
+ kvo_stale.result.val = kvo_cur.result.val = key;
489
+
490
+ defaultOptions(instance, opts);
491
+ DurabilityOperation dop;
492
+
493
+ opts.version = 1;
494
+ opts.v.v0.pollopts = LCB_DURABILITY_MODE_CAS;
495
+ dop.run(instance, &opts, kvo_stale.result);
496
+ ASSERT_EQ(LCB_KEY_EEXISTS, dop.resp.rc);
497
+
498
+ if (supportsMutationTokens(instance)) {
499
+ opts.v.v0.pollopts = LCB_DURABILITY_MODE_SEQNO;
500
+ dop = DurabilityOperation();
501
+ dop.run(instance, &opts, kvo_stale.result);
502
+ ASSERT_EQ(LCB_SUCCESS, dop.resp.rc);
503
+ }
504
+ }
505
+
506
+ /**
507
+ * @test Test with very quick timeouts
508
+ * @pre Schedule an operation with an interval of 2 usec and a timeout of
509
+ * 5 usec
510
+ *
511
+ * @post Operation returns with LCB_ETIMEDOUT
512
+ */
513
+ TEST_F(DurabilityUnitTest, testQuickTimeout)
514
+ {
515
+ LCB_TEST_REQUIRE_FEATURE("observe");
516
+ lcb_t instance;
517
+ HandleWrap hwrap;
518
+ lcb_durability_opts_t opts = { 0 };
519
+ string key = "a_key";
520
+
521
+ createConnection(hwrap);
522
+ instance = hwrap.getLcb();
523
+
524
+ Item itm = Item(key, key);
525
+ KVOperation(&itm).store(instance);
526
+
527
+ defaultOptions(instance, opts);
528
+
529
+ /* absurd */
530
+ opts.v.v0.timeout = 5;
531
+ opts.v.v0.interval = 2;
532
+
533
+ for (unsigned ii = 0; ii < 10; ii++) {
534
+ DurabilityOperation dop;
535
+ dop.run(instance, &opts, itm);
536
+ ASSERT_EQ(LCB_ETIMEDOUT, dop.resp.rc);
537
+ }
538
+ }
539
+
540
+ /**
541
+ * @test Test a durability request for multiple keys
542
+ *
543
+ * @pre Store ten keys, and check that they exist all at once
544
+ * @post all ten keys are received in the response, and they're ok
545
+ *
546
+ * @pre Check that ten missing keys exist all at once
547
+ * @post all ten keys are received in the response, and they have an error
548
+ *
549
+ * @pre Check the ten stored and ten missing keys in a single operation
550
+ * @post The ten missing keys are present and have a negative status, the ten
551
+ * stored keys are present and are OK
552
+ */
553
+ TEST_F(DurabilityUnitTest, testMulti)
554
+ {
555
+ LCB_TEST_REQUIRE_FEATURE("observe");
556
+ unsigned ii;
557
+ const unsigned limit = 10;
558
+
559
+ vector<Item> items_stored;
560
+ vector<Item> items_missing;
561
+
562
+ lcb_durability_opts_t opts = { 0 };
563
+ HandleWrap hwrap;
564
+ lcb_t instance;
565
+
566
+ createConnection(hwrap);
567
+ instance = hwrap.getLcb();
568
+ // Set the timeout to something high. For some reason this gives problem
569
+ // on a real cluster
570
+ lcb_cntl_setu32(instance, LCB_CNTL_DURABILITY_TIMEOUT, LCB_MS2US(10000));
571
+
572
+ for (ii = 0; ii < limit; ii++) {
573
+ char buf[64];
574
+ sprintf(buf, "key-stored-%u", ii);
575
+ string key_stored = buf;
576
+ sprintf(buf, "key-missing-%u", ii);
577
+ string key_missing = buf;
578
+
579
+ removeKey(instance, key_stored);
580
+ removeKey(instance, key_missing);
581
+
582
+ Item itm_e = Item(key_stored, key_stored, 0);
583
+ Item itm_m = Item(key_missing, key_missing, 0);
584
+
585
+ KVOperation kvo(&itm_e);
586
+ kvo.store(instance);
587
+ items_stored.push_back(kvo.result);
588
+ items_missing.push_back(itm_m);
589
+ }
590
+
591
+ defaultOptions(instance, opts);
592
+ opts.version = 1;
593
+ opts.v.v0.pollopts = LCB_DURABILITY_MODE_CAS;
594
+
595
+ /**
596
+ * Create the command..
597
+ */
598
+ DurabilityMultiOperation dmop = DurabilityMultiOperation();
599
+ dmop.run(instance, &opts, items_stored);
600
+ dmop.assertAllMatch(opts, items_stored, vector<Item>());
601
+
602
+ // Store all the missing ones
603
+ opts.v.v0.timeout = (lcb_uint32_t)SECS_USECS(1.5);
604
+ dmop = DurabilityMultiOperation();
605
+ dmop.run(instance, &opts, items_missing);
606
+ dmop.assertAllMatch(opts, vector<Item>(), items_missing, LCB_KEY_ENOENT);
607
+
608
+ // Store them all together
609
+ opts.v.v0.timeout = 0;
610
+ vector<Item> combined;
611
+ combined.insert(combined.end(), items_stored.begin(), items_stored.end());
612
+ combined.insert(combined.end(), items_missing.begin(), items_missing.end());
613
+ dmop.run(instance, &opts, combined);
614
+ dmop.assertAllMatch(opts, items_stored, items_missing);
615
+ }
616
+
617
+ struct cb_cookie {
618
+ int is_observe;
619
+ int count;
620
+ };
621
+
622
+ extern "C" {
623
+ static void dummyObserveCallback(lcb_t, const void *cookie,
624
+ lcb_error_t,
625
+ const lcb_observe_resp_t *)
626
+ {
627
+ struct cb_cookie *c = (struct cb_cookie *)cookie;
628
+ ASSERT_EQ(1, c->is_observe);
629
+ c->count++;
630
+ }
631
+
632
+ static void dummyDurabilityCallback(lcb_t, const void *cookie,
633
+ lcb_error_t,
634
+ const lcb_durability_resp_t *)
635
+ {
636
+ struct cb_cookie *c = (struct cb_cookie *)cookie;
637
+ ASSERT_EQ(0, c->is_observe);
638
+ c->count++;
639
+ }
640
+ }
641
+
642
+ /**
643
+ * @test Ensure basic observe functions as normal
644
+ *
645
+ * @pre pair up two batched commands, one a durability command, and one a
646
+ * primitive observe. Set up distinct callbacks for the two (both of which
647
+ * touch a counter, one incrementing and one decrementing an int*).
648
+ * Wait for the operations to complete via @c lcb_wait
649
+ *
650
+ * @post The durability counter is decremented, observe counter incremented
651
+ */
652
+ TEST_F(DurabilityUnitTest, testObserveSanity)
653
+ {
654
+ LCB_TEST_REQUIRE_FEATURE("observe");
655
+ HandleWrap handle;
656
+ lcb_t instance;
657
+ createConnection(handle);
658
+ instance = handle.getLcb();
659
+ lcb_error_t err;
660
+
661
+
662
+ lcb_set_durability_callback(instance, dummyDurabilityCallback);
663
+ lcb_set_observe_callback(instance, dummyObserveCallback);
664
+
665
+ lcb_durability_opts_t opts = { 0 };
666
+
667
+ lcb_observe_cmd_t ocmd, *ocmds[] = { &ocmd };
668
+ lcb_durability_cmd_t dcmd, *dcmds[] = { &dcmd };
669
+
670
+ memset(&ocmd, 0, sizeof(ocmd));
671
+ memset(&dcmd, 0, sizeof(dcmd));
672
+
673
+ ocmd.v.v0.key = "key";
674
+ ocmd.v.v0.nkey = 3;
675
+
676
+ dcmd.v.v0.key = "key";
677
+ dcmd.v.v0.nkey = 3;
678
+
679
+ storeKey(instance, "key", "value");
680
+
681
+ defaultOptions(instance, opts);
682
+
683
+ struct cb_cookie o_cookie = { 1, 0 };
684
+ struct cb_cookie d_cookie = { 0, 0 };
685
+
686
+ err = lcb_observe(instance, &o_cookie, 1, ocmds);
687
+ ASSERT_EQ(LCB_SUCCESS, err);
688
+
689
+ err = lcb_durability_poll(instance, &d_cookie, &opts, 1, dcmds);
690
+ ASSERT_EQ(LCB_SUCCESS, err);
691
+
692
+ ASSERT_EQ(LCB_SUCCESS, lcb_wait(instance));
693
+
694
+ ASSERT_GT(o_cookie.count, 0);
695
+ ASSERT_GT(d_cookie.count, 0);
696
+ }
697
+
698
+ TEST_F(DurabilityUnitTest, testMasterObserve)
699
+ {
700
+ LCB_TEST_REQUIRE_FEATURE("observe");
701
+ SKIP_UNLESS_MOCK();
702
+
703
+ HandleWrap handle;
704
+ createConnection(handle);
705
+ lcb_t instance = handle.getLcb();
706
+
707
+ lcb_set_observe_callback(instance, dummyObserveCallback);
708
+ lcb_observe_cmd_t ocmd, *ocmds[] = { &ocmd };
709
+ memset(&ocmd, 0, sizeof(ocmd));
710
+ ocmd.version = 1;
711
+ ocmd.v.v1.key = "key";
712
+ ocmd.v.v1.options = LCB_OBSERVE_MASTER_ONLY;
713
+ ocmd.v.v1.nkey = 3;
714
+ storeKey(instance, "key", "value");
715
+ struct cb_cookie o_cookie = { 1, 0 };
716
+ lcb_error_t err = lcb_observe(instance, &o_cookie, 1, ocmds);
717
+ ASSERT_EQ(LCB_SUCCESS, err);
718
+ lcb_wait(instance);
719
+
720
+ // 2 == one for the callback, one for the NULL
721
+ ASSERT_EQ(2, o_cookie.count);
722
+ }
723
+
724
+ extern "C" {
725
+ static void fo_callback(void *cookie)
726
+ {
727
+ lcb_t instance = (lcb_t )cookie;
728
+ MockEnvironment *mock = MockEnvironment::getInstance();
729
+ for (int ii = 1; ii < mock->getNumNodes(); ii++) {
730
+ mock->failoverNode(ii);
731
+ }
732
+ lcb_loop_unref(instance);
733
+ }
734
+ }
735
+
736
+ /**
737
+ * Test the functionality of durability operations during things like
738
+ * node failovers.
739
+ *
740
+ * The idea behind here is to ensure that we can trigger a case where a series
741
+ * of OBSERVE packets are caught in the middle of a cluster update and end up
742
+ * being relocated to the same server. Previously (and currently) this would
743
+ * confuse the lookup_server_with_command functionality which would then invoke
744
+ * the 'NULL' callback multiple times (because it assumes it's not located
745
+ * anywhere else)
746
+ */
747
+ TEST_F(DurabilityUnitTest, testDurabilityRelocation)
748
+ {
749
+ SKIP_UNLESS_MOCK();
750
+
751
+ // Disable CCCP so that we get streaming updates
752
+ MockEnvironment *mock = MockEnvironment::getInstance();
753
+ mock->setCCCP(false);
754
+
755
+ HandleWrap handle;
756
+ lcb_t instance;
757
+ createConnection(handle);
758
+ instance = handle.getLcb();
759
+
760
+ lcb_set_durability_callback(instance, dummyDurabilityCallback);
761
+ std::string key = "key";
762
+
763
+ lcb_durability_cmd_t dcmd, *dcmds[] = { &dcmd };
764
+ lcb_durability_opts_t opts = { 0 };
765
+
766
+ opts.v.v0.persist_to = 100;
767
+ opts.v.v0.replicate_to = 100;
768
+ opts.v.v0.cap_max = 1;
769
+ storeKey(instance, key, "value");
770
+
771
+ // Ensure we have to resend commands multiple times
772
+ MockMutationCommand mcmd(MockCommand::UNPERSIST, key);
773
+ mcmd.onMaster = true;
774
+ mcmd.replicaCount = lcb_get_num_replicas(instance);
775
+ doMockTxn(mcmd);
776
+
777
+ memset(&dcmd, 0, sizeof(dcmd));
778
+
779
+ dcmd.v.v0.key = key.c_str();
780
+ dcmd.v.v0.nkey = 3;
781
+
782
+ /**
783
+ * Failover all but one node
784
+ */
785
+ for (int ii = 1; ii < mock->getNumNodes(); ii++) {
786
+ mock->hiccupNodes(1000, 0);
787
+ }
788
+ lcbio_pTIMER tm = lcbio_timer_new(handle.getLcb()->iotable,
789
+ instance, fo_callback);
790
+ lcbio_timer_rearm(tm, 500000);
791
+ lcb_loop_ref(instance);
792
+
793
+ struct cb_cookie cookie = { 0, 0 };
794
+ lcb_error_t err = lcb_durability_poll(instance, &cookie, &opts, 1, dcmds);
795
+ ASSERT_EQ(LCB_SUCCESS, err);
796
+
797
+ lcb_wait(instance);
798
+ lcbio_timer_destroy(tm);
799
+ ASSERT_EQ(1, cookie.count);
800
+ }
801
+
802
+
803
+ TEST_F(DurabilityUnitTest, testDuplicateCommands)
804
+ {
805
+ HandleWrap hw;
806
+ lcb_t instance;
807
+ createConnection(hw, instance);
808
+ std::string key("key");
809
+ std::vector<lcb_durability_cmd_t> cmds;
810
+ std::vector<lcb_durability_cmd_t *> cmdlist;
811
+ lcb_durability_opts_t options = { 0 };
812
+ options.v.v0.replicate_to = 100;
813
+ options.v.v0.persist_to = 100;
814
+ options.v.v0.cap_max = 1;
815
+
816
+ for (int ii = 0; ii < 2; ii++) {
817
+ lcb_durability_cmd_t cmd = { 0 };
818
+ cmd.v.v0.key = key.c_str();
819
+ cmd.v.v0.nkey = key.size();
820
+ cmds.push_back(cmd);
821
+ }
822
+ for (size_t ii = 0; ii < cmds.size(); ii++) {
823
+ cmdlist.push_back(&cmds[ii]);
824
+ }
825
+ lcb_error_t err;
826
+ err = lcb_durability_poll(instance, NULL, &options, 2, &cmdlist[0]);
827
+ ASSERT_EQ(LCB_DUPLICATE_COMMANDS, err);
828
+ }
829
+
830
+ TEST_F(DurabilityUnitTest, testMissingSynctoken)
831
+ {
832
+ HandleWrap hw;
833
+ lcb_t instance;
834
+ createConnection(hw, instance);
835
+
836
+ if (!supportsMutationTokens(instance)) {
837
+ return;
838
+ }
839
+
840
+ std::string("nonexist-key");
841
+ lcb_error_t rc;
842
+ lcb_MULTICMD_CTX *mctx;
843
+ lcb_durability_opts_t options = { 0 };
844
+ defaultOptions(instance, options);
845
+ options.version = 1;
846
+ options.v.v0.pollopts = LCB_DURABILITY_MODE_SEQNO;
847
+
848
+ mctx = lcb_endure3_ctxnew(instance, &options, &rc);
849
+ ASSERT_FALSE(mctx == NULL);
850
+ lcb_CMDENDURE cmd = { 0 };
851
+ LCB_CMD_SET_KEY(&cmd, "foo", 3);
852
+
853
+ rc = mctx->addcmd(mctx, (lcb_CMDBASE*)&cmd);
854
+ ASSERT_EQ(LCB_DURABILITY_NO_MUTATION_TOKENS, rc);
855
+
856
+ mctx->fail(mctx);
857
+ }
858
+
859
+ TEST_F(DurabilityUnitTest, testExternalSynctoken)
860
+ {
861
+ HandleWrap hw1, hw2;
862
+ lcb_t instance1, instance2;
863
+ createConnection(hw1, instance1);
864
+ createConnection(hw2, instance2);
865
+
866
+ if (!supportsMutationTokens(instance1)) {
867
+ return;
868
+ }
869
+
870
+ std::string key("hello");
871
+ std::string value("world");
872
+ storeKey(instance1, key, value);
873
+
874
+ const lcb_MUTATION_TOKEN *ss;
875
+ lcb_KEYBUF kb;
876
+ lcb_error_t rc;
877
+ LCB_KREQ_SIMPLE(&kb, key.c_str(), key.size());
878
+ ss = lcb_get_mutation_token(instance1, &kb, &rc);
879
+ ASSERT_FALSE(ss == NULL);
880
+ ASSERT_TRUE(LCB_MUTATION_TOKEN_ISVALID(ss));
881
+ ASSERT_EQ(LCB_SUCCESS, rc);
882
+
883
+ lcb_durability_opts_t options = { 0 };
884
+ lcb_CMDENDURE cmd = { 0 };
885
+ defaultOptions(instance2, options);
886
+ options.version = 1;
887
+ options.v.v0.pollopts = LCB_DURABILITY_MODE_SEQNO;
888
+
889
+ // Initialize the command
890
+ LCB_CMD_SET_KEY(&cmd, key.c_str(), key.size());
891
+ cmd.mutation_token = ss;
892
+ cmd.cmdflags |= LCB_CMDENDURE_F_MUTATION_TOKEN;
893
+
894
+ DurabilityOperation dop;
895
+ dop.run(instance2, &options, cmd);
896
+ // TODO: How to actually run this?
897
+ ASSERT_EQ(LCB_SUCCESS, dop.resp.rc);
898
+ }
899
+
900
+ TEST_F(DurabilityUnitTest, testOptionValidation)
901
+ {
902
+ HandleWrap hw;
903
+ lcb_t instance;
904
+ lcb_U16 persist = 0, replicate = 0;
905
+ int options;
906
+ lcb_error_t rc;
907
+
908
+ createConnection(hw, instance);
909
+
910
+ // Validate simple mode
911
+ persist = -1;
912
+ replicate = -1;
913
+ rc = lcb_durability_validate(instance, &persist, &replicate,
914
+ LCB_DURABILITY_VALIDATE_CAPMAX);
915
+
916
+ ASSERT_EQ(LCB_SUCCESS, rc);
917
+ ASSERT_TRUE(persist > replicate);
918
+
919
+ lcbvb_CONFIG *vbc;
920
+ rc = lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_VBCONFIG, &vbc);
921
+ ASSERT_EQ(LCB_SUCCESS, rc);
922
+
923
+ int replica_max = min(LCBVB_NREPLICAS(vbc), LCBVB_NDATASERVERS(vbc)-1);
924
+ int persist_max = replica_max + 1;
925
+
926
+ ASSERT_EQ(replica_max, replicate);
927
+ ASSERT_EQ(persist_max, persist);
928
+
929
+ persist = 0;
930
+ replicate = 0;
931
+ rc = lcb_durability_validate(instance, &persist, &replicate, 0);
932
+ ASSERT_EQ(LCB_EINVAL, rc);
933
+
934
+ persist = -1;
935
+ replicate = -1;
936
+ rc = lcb_durability_validate(instance, &persist, &replicate, 0);
937
+ ASSERT_EQ(LCB_DURABILITY_ETOOMANY, rc);
938
+
939
+ persist = persist_max;
940
+ replicate = replica_max;
941
+ rc = lcb_durability_validate(instance, &persist, &replicate, 0);
942
+ ASSERT_EQ(LCB_SUCCESS, rc);
943
+ ASSERT_EQ(persist_max, persist);
944
+ ASSERT_EQ(replica_max, replicate);
945
+
946
+ rc = lcb_durability_validate(instance, &persist, &replicate,
947
+ LCB_DURABILITY_VALIDATE_CAPMAX);
948
+ ASSERT_EQ(LCB_SUCCESS, rc);
949
+ ASSERT_EQ(persist_max, persist);
950
+ ASSERT_EQ(replica_max, replicate);
951
+ }
952
+
953
+ extern "C" {
954
+ static void durstoreCallback(lcb_t, int, const lcb_RESPBASE *rb)
955
+ {
956
+ const lcb_RESPSTOREDUR *resp = reinterpret_cast<const lcb_RESPSTOREDUR*>(rb);
957
+ lcb_RESPSTOREDUR *rout = reinterpret_cast<lcb_RESPSTOREDUR*>(rb->cookie);
958
+ lcb_RESPENDURE *dur_resp = const_cast<lcb_RESPENDURE*>(rout->dur_resp);
959
+
960
+ ASSERT_FALSE(resp->dur_resp == NULL);
961
+
962
+ *rout = *resp;
963
+ *dur_resp = *resp->dur_resp;
964
+ rout->dur_resp = dur_resp;
965
+ }
966
+ }
967
+
968
+ TEST_F(DurabilityUnitTest, testDurStore)
969
+ {
970
+ HandleWrap hw;
971
+ lcb_t instance;
972
+ lcb_durability_opts_t options = { 0 };
973
+ createConnection(hw, instance);
974
+ lcb_install_callback3(instance, LCB_CALLBACK_STOREDUR, durstoreCallback);
975
+
976
+ std::string key("durStore");
977
+ std::string value("value");
978
+
979
+ lcb_error_t rc;
980
+ lcb_RESPSTOREDUR resp = { 0 };
981
+ lcb_RESPENDURE dur_resp = { 0 };
982
+
983
+ resp.dur_resp = &dur_resp;
984
+
985
+ lcb_CMDSTOREDUR cmd = { 0 };
986
+ LCB_CMD_SET_KEY(&cmd, key.c_str(), key.size());
987
+ LCB_CMD_SET_VALUE(&cmd, value.c_str(), value.size());
988
+ defaultOptions(instance, options);
989
+ cmd.operation = LCB_SET;
990
+ cmd.persist_to = options.v.v0.persist_to;
991
+ cmd.replicate_to = options.v.v0.replicate_to;
992
+
993
+ lcb_sched_enter(instance);
994
+ resp.rc = LCB_ERROR;
995
+ rc = lcb_storedur3(instance, &resp, &cmd);
996
+ ASSERT_EQ(LCB_SUCCESS, rc);
997
+ lcb_sched_leave(instance);
998
+ lcb_wait(instance);
999
+
1000
+ ASSERT_EQ(LCB_SUCCESS, resp.rc);
1001
+ ASSERT_NE(0, resp.store_ok);
1002
+ ASSERT_TRUE(options.v.v0.persist_to <= resp.dur_resp->npersisted);
1003
+ ASSERT_TRUE(options.v.v0.replicate_to <= resp.dur_resp->nreplicated);
1004
+
1005
+ lcb_sched_enter(instance);
1006
+ // Try with bad criteria..
1007
+ cmd.persist_to = 100;
1008
+ cmd.replicate_to = 100;
1009
+ rc = lcb_storedur3(instance, &resp, &cmd);
1010
+ ASSERT_EQ(LCB_DURABILITY_ETOOMANY, rc);
1011
+
1012
+ // Try with no persist/replicate options
1013
+ cmd.persist_to = 0;
1014
+ cmd.replicate_to = 0;
1015
+ rc = lcb_storedur3(instance, &resp, &cmd);
1016
+ ASSERT_EQ(LCB_EINVAL, rc);
1017
+ lcb_sched_fail(instance);
1018
+
1019
+ // CAP_MAX should be applied here
1020
+ cmd.persist_to = -1;
1021
+ cmd.replicate_to = -1;
1022
+ lcb_sched_enter(instance);
1023
+ rc = lcb_storedur3(instance, &resp, &cmd);
1024
+ ASSERT_EQ(LCB_SUCCESS, rc);
1025
+ lcb_sched_leave(instance);
1026
+ lcb_wait(instance);
1027
+ ASSERT_EQ(LCB_SUCCESS, resp.rc);
1028
+ ASSERT_TRUE(options.v.v0.persist_to <= resp.dur_resp->npersisted);
1029
+ ASSERT_TRUE(options.v.v0.replicate_to <= resp.dur_resp->nreplicated);
1030
+
1031
+ // Use bad CAS. we should have a clear indicator that storage failed
1032
+ cmd.cas = -1;
1033
+ lcb_sched_enter(instance);
1034
+ rc = lcb_storedur3(instance, &resp, &cmd);
1035
+ ASSERT_EQ(LCB_SUCCESS, rc);
1036
+ lcb_sched_leave(instance);
1037
+ lcb_wait(instance);
1038
+ ASSERT_EQ(LCB_KEY_EEXISTS, resp.rc);
1039
+ ASSERT_EQ(0, resp.store_ok);
1040
+
1041
+ // Make storage succeed, but let durability fail.
1042
+ // TODO: Add Mock-specific command to disable persistence/replication
1043
+ lcb_U32 ustmo = 1; // 1 microsecond
1044
+ rc = lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_DURABILITY_TIMEOUT, &ustmo);
1045
+ ASSERT_EQ(LCB_SUCCESS, rc);
1046
+
1047
+ // Reset CAS from previous command
1048
+ cmd.cas = 0;
1049
+ lcb_sched_enter(instance);
1050
+ rc = lcb_storedur3(instance, &resp, &cmd);
1051
+ ASSERT_EQ(LCB_SUCCESS, rc);
1052
+ lcb_sched_leave(instance);
1053
+ lcb_wait(instance);
1054
+ if (resp.rc == LCB_ETIMEDOUT) {
1055
+ ASSERT_NE(0, resp.store_ok);
1056
+ } else {
1057
+ lcb_log(LOGARGS(instance, WARN), "Test skipped because mock is too fast(!)");
1058
+ }
1059
+ }