libcouchbase 0.0.1

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 (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
+ }