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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/.travis.yml +35 -0
- data/Gemfile +4 -0
- data/LICENSE +24 -0
- data/README.md +389 -0
- data/Rakefile +75 -0
- data/ext/README.md +6 -0
- data/ext/Rakefile +20 -0
- data/ext/libcouchbase/.gitignore +130 -0
- data/ext/libcouchbase/.travis.yml +19 -0
- data/ext/libcouchbase/CMakeLists.txt +429 -0
- data/ext/libcouchbase/CONTRIBUTING.md +124 -0
- data/ext/libcouchbase/LICENSE +202 -0
- data/ext/libcouchbase/README.markdown +163 -0
- data/ext/libcouchbase/RELEASE_NOTES.markdown +2691 -0
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +27 -0
- data/ext/libcouchbase/cmake/Modules/CopyPDB.cmake +42 -0
- data/ext/libcouchbase/cmake/Modules/DistScript.cmake +17 -0
- data/ext/libcouchbase/cmake/Modules/DownloadLcbDep.cmake +20 -0
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseHdrHistogram.cmake +15 -0
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibev.cmake +73 -0
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +52 -0
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +56 -0
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseSnappy.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +29 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +133 -0
- data/ext/libcouchbase/cmake/Modules/GetPlatformCCInfo.cmake +45 -0
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +70 -0
- data/ext/libcouchbase/cmake/config-cmake.h.in +60 -0
- data/ext/libcouchbase/cmake/configure +357 -0
- data/ext/libcouchbase/cmake/defs.mk.in +8 -0
- data/ext/libcouchbase/cmake/dtrace-instr-link.pl +38 -0
- data/ext/libcouchbase/cmake/source_files.cmake +73 -0
- data/ext/libcouchbase/configure.pl +1 -0
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +624 -0
- data/ext/libcouchbase/contrib/cJSON/cJSON.h +158 -0
- data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +9 -0
- data/ext/libcouchbase/contrib/cbsasl/COPYING +202 -0
- data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +217 -0
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +205 -0
- data/ext/libcouchbase/contrib/cbsasl/src/common.c +46 -0
- data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/hmac.c +67 -0
- data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/hmac.h +33 -0
- data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/md5.c +296 -0
- data/ext/libcouchbase/contrib/cbsasl/src/cram-md5/md5.h +45 -0
- data/ext/libcouchbase/contrib/cbsasl/src/hash.c +573 -0
- data/ext/libcouchbase/contrib/cbsasl/src/hash.h +15 -0
- data/ext/libcouchbase/contrib/cbsasl/src/util.h +31 -0
- data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +2 -0
- data/ext/libcouchbase/contrib/cliopts/cliopts.c +747 -0
- data/ext/libcouchbase/contrib/cliopts/cliopts.h +493 -0
- data/ext/libcouchbase/contrib/genhash/genhash.c +372 -0
- data/ext/libcouchbase/contrib/genhash/genhash.h +235 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/CHANGES +157 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/CMakeLists.txt +252 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/CONTRIBUTORS +37 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/LICENSE +28 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/MINIFY.sh +15 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/README +435 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/cmake/internal_utils.cmake +227 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-death-test.h +294 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-message.h +250 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-param-test.h +1421 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-param-test.h.pump +487 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-printers.h +855 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-spi.h +232 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-test-part.h +179 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest-typed-test.h +259 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest.h +2291 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest_pred_impl.h +358 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/gtest_prod.h +58 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h +319 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h +206 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-internal.h +1158 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h +233 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h +5143 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h.pump +301 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h +619 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-port.h +1947 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-string.h +167 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-tuple.h +1012 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-tuple.h.pump +339 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h +3331 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h.pump +297 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-all.cc +48 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-death-test.cc +1344 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-filepath.cc +382 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-internal-inl.h +1218 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-port.cc +805 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-printers.cc +363 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-test-part.cc +110 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest-typed-test.cc +110 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest.cc +5015 -0
- data/ext/libcouchbase/contrib/gtest-1.7.0/src/gtest_main.cc +38 -0
- data/ext/libcouchbase/contrib/http_parser/LICENSE-MIT +23 -0
- data/ext/libcouchbase/contrib/http_parser/README.md +178 -0
- data/ext/libcouchbase/contrib/http_parser/http_parser.c +2060 -0
- data/ext/libcouchbase/contrib/http_parser/http_parser.h +321 -0
- data/ext/libcouchbase/contrib/jsonsl/LICENSE +20 -0
- data/ext/libcouchbase/contrib/jsonsl/jsonsl.c +1452 -0
- data/ext/libcouchbase/contrib/jsonsl/jsonsl.h +971 -0
- data/ext/libcouchbase/contrib/lcb-jsoncpp/CMakeLists.txt +6 -0
- data/ext/libcouchbase/contrib/lcb-jsoncpp/LICENSE +55 -0
- data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp-forwards.h +255 -0
- data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +4892 -0
- data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.h +1961 -0
- data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +8 -0
- data/ext/libcouchbase/contrib/snappy/COPYING +28 -0
- data/ext/libcouchbase/contrib/snappy/snappy-c.cc +90 -0
- data/ext/libcouchbase/contrib/snappy/snappy-c.h +138 -0
- data/ext/libcouchbase/contrib/snappy/snappy-internal.h +150 -0
- data/ext/libcouchbase/contrib/snappy/snappy-lcb-msvc.h +5 -0
- data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +71 -0
- data/ext/libcouchbase/contrib/snappy/snappy-sinksource.h +137 -0
- data/ext/libcouchbase/contrib/snappy/snappy-stubs-internal.cc +42 -0
- data/ext/libcouchbase/contrib/snappy/snappy-stubs-internal.h +491 -0
- data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +98 -0
- data/ext/libcouchbase/contrib/snappy/snappy.cc +1307 -0
- data/ext/libcouchbase/contrib/snappy/snappy.h +184 -0
- data/ext/libcouchbase/contrib/win32-defs/iocpdefs.h +133 -0
- data/ext/libcouchbase/contrib/win32-defs/mingwdefs.h +4396 -0
- data/ext/libcouchbase/contrib/win32-defs/win_stdint.h +258 -0
- data/ext/libcouchbase/example/CMakeLists.txt +37 -0
- data/ext/libcouchbase/example/README.markdown +47 -0
- data/ext/libcouchbase/example/db/db.c +167 -0
- data/ext/libcouchbase/example/db/vb.c +227 -0
- data/ext/libcouchbase/example/instancepool/main.cc +102 -0
- data/ext/libcouchbase/example/instancepool/pool.cc +102 -0
- data/ext/libcouchbase/example/instancepool/pool.h +69 -0
- data/ext/libcouchbase/example/libeventdirect/main.c +148 -0
- data/ext/libcouchbase/example/mcc/mcc.cc +246 -0
- data/ext/libcouchbase/example/minimal/minimal.c +130 -0
- data/ext/libcouchbase/example/observe/observe.c +146 -0
- data/ext/libcouchbase/example/subdoc/subdoc-multi.cc +132 -0
- data/ext/libcouchbase/example/subdoc/subdoc-simple.cc +191 -0
- data/ext/libcouchbase/example/tick/tick.c +119 -0
- data/ext/libcouchbase/example/views/views-example.cc +83 -0
- data/ext/libcouchbase/include/libcouchbase/_cxxwrap.h +150 -0
- data/ext/libcouchbase/include/libcouchbase/api-legacy.h +1689 -0
- data/ext/libcouchbase/include/libcouchbase/api3.h +2 -0
- data/ext/libcouchbase/include/libcouchbase/assert.h +44 -0
- data/ext/libcouchbase/include/libcouchbase/cbft.h +109 -0
- data/ext/libcouchbase/include/libcouchbase/cntl-private.h +356 -0
- data/ext/libcouchbase/include/libcouchbase/cntl.h +937 -0
- data/ext/libcouchbase/include/libcouchbase/configuration.h.in +23 -0
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +3677 -0
- data/ext/libcouchbase/include/libcouchbase/deprecated.h +300 -0
- data/ext/libcouchbase/include/libcouchbase/error.h +595 -0
- data/ext/libcouchbase/include/libcouchbase/http.h +1 -0
- data/ext/libcouchbase/include/libcouchbase/iops.h +1050 -0
- data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +263 -0
- data/ext/libcouchbase/include/libcouchbase/kvbuf.h +132 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +364 -0
- data/ext/libcouchbase/include/libcouchbase/pktfwd.h +270 -0
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +367 -0
- data/ext/libcouchbase/include/libcouchbase/plugins/io/wsaerr-inl.c +76 -0
- data/ext/libcouchbase/include/libcouchbase/plugins/io/wsaerr.h +199 -0
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +312 -0
- data/ext/libcouchbase/include/libcouchbase/sysdefs.h +98 -0
- data/ext/libcouchbase/include/libcouchbase/vbucket.h +643 -0
- data/ext/libcouchbase/include/libcouchbase/views.h +298 -0
- data/ext/libcouchbase/include/libcouchbase/visibility.h +65 -0
- data/ext/libcouchbase/include/memcached/COPYING +30 -0
- data/ext/libcouchbase/include/memcached/README +10 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +1916 -0
- data/ext/libcouchbase/include/memcached/vbucket.h +42 -0
- data/ext/libcouchbase/packaging/README +7 -0
- data/ext/libcouchbase/packaging/abicheck/.gitignore +4 -0
- data/ext/libcouchbase/packaging/abicheck/Makefile +17 -0
- data/ext/libcouchbase/packaging/abicheck/README.md +27 -0
- data/ext/libcouchbase/packaging/abicheck/template.xml +3 -0
- data/ext/libcouchbase/packaging/deb/compat +1 -0
- data/ext/libcouchbase/packaging/deb/control +73 -0
- data/ext/libcouchbase/packaging/deb/copyright +10 -0
- data/ext/libcouchbase/packaging/deb/libcouchbase-dev.docs +3 -0
- data/ext/libcouchbase/packaging/deb/package.mk +31 -0
- data/ext/libcouchbase/packaging/deb/rules +46 -0
- data/ext/libcouchbase/packaging/deb/source/format +1 -0
- data/ext/libcouchbase/packaging/distinfo/README +1 -0
- data/ext/libcouchbase/packaging/distinfo/distinfo.cmake.in +4 -0
- data/ext/libcouchbase/packaging/dllversion.rc.in +39 -0
- data/ext/libcouchbase/packaging/libcouchbase.pc.in +10 -0
- data/ext/libcouchbase/packaging/nuget/libcouchbase.autopkg +76 -0
- data/ext/libcouchbase/packaging/parse-git-describe.pl +166 -0
- data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +108 -0
- data/ext/libcouchbase/packaging/rpm/package.mk +40 -0
- data/ext/libcouchbase/plugins/io/iocp/CMakeLists.txt +9 -0
- data/ext/libcouchbase/plugins/io/iocp/iocp_iops.c +466 -0
- data/ext/libcouchbase/plugins/io/iocp/iocp_iops.h +217 -0
- data/ext/libcouchbase/plugins/io/iocp/iocp_loop.c +295 -0
- data/ext/libcouchbase/plugins/io/iocp/iocp_timer.c +79 -0
- data/ext/libcouchbase/plugins/io/iocp/iocp_util.c +229 -0
- data/ext/libcouchbase/plugins/io/libev/CMakeLists.txt +29 -0
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +65 -0
- data/ext/libcouchbase/plugins/io/libev/plugin-libev.c +289 -0
- data/ext/libcouchbase/plugins/io/libevent/CMakeLists.txt +29 -0
- data/ext/libcouchbase/plugins/io/libevent/libevent_io_opts.h +67 -0
- data/ext/libcouchbase/plugins/io/libevent/plugin-libevent.c +292 -0
- data/ext/libcouchbase/plugins/io/libuv/CMakeLists.txt +42 -0
- data/ext/libcouchbase/plugins/io/libuv/libuv_compat.h +212 -0
- data/ext/libcouchbase/plugins/io/libuv/libuv_io_opts.h +118 -0
- data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +148 -0
- data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +648 -0
- data/ext/libcouchbase/plugins/io/select/CMakeLists.txt +11 -0
- data/ext/libcouchbase/plugins/io/select/plugin-select.c +448 -0
- data/ext/libcouchbase/plugins/io/select/select_io_opts.h +39 -0
- data/ext/libcouchbase/src/README.md +103 -0
- data/ext/libcouchbase/src/aspend.h +106 -0
- data/ext/libcouchbase/src/auth.cc +74 -0
- data/ext/libcouchbase/src/auth.h +54 -0
- data/ext/libcouchbase/src/bootstrap.c +269 -0
- data/ext/libcouchbase/src/bootstrap.h +129 -0
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.c +495 -0
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +347 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +630 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +82 -0
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +681 -0
- data/ext/libcouchbase/src/bucketconfig/confmon.c +474 -0
- data/ext/libcouchbase/src/callbacks.c +378 -0
- data/ext/libcouchbase/src/cbft.cc +210 -0
- data/ext/libcouchbase/src/cntl.cc +847 -0
- data/ext/libcouchbase/src/config_static.h +159 -0
- data/ext/libcouchbase/src/connspec.cc +462 -0
- data/ext/libcouchbase/src/connspec.h +105 -0
- data/ext/libcouchbase/src/ctx-log-inl.h +27 -0
- data/ext/libcouchbase/src/dump.c +98 -0
- data/ext/libcouchbase/src/getconfig.c +100 -0
- data/ext/libcouchbase/src/gethrtime.c +109 -0
- data/ext/libcouchbase/src/handler.c +922 -0
- data/ext/libcouchbase/src/hashset.c +164 -0
- data/ext/libcouchbase/src/hashset.h +86 -0
- data/ext/libcouchbase/src/hashtable.c +75 -0
- data/ext/libcouchbase/src/hdr_timings.c +92 -0
- data/ext/libcouchbase/src/hostlist.cc +301 -0
- data/ext/libcouchbase/src/hostlist.h +171 -0
- data/ext/libcouchbase/src/http/http-priv.h +307 -0
- data/ext/libcouchbase/src/http/http.cc +633 -0
- data/ext/libcouchbase/src/http/http.h +34 -0
- data/ext/libcouchbase/src/http/http_io.cc +307 -0
- data/ext/libcouchbase/src/instance.cc +722 -0
- data/ext/libcouchbase/src/internal.h +244 -0
- data/ext/libcouchbase/src/iofactory.c +575 -0
- data/ext/libcouchbase/src/jsparse/parser.cc +519 -0
- data/ext/libcouchbase/src/jsparse/parser.h +173 -0
- data/ext/libcouchbase/src/lcbht/lcbht.c +282 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +199 -0
- data/ext/libcouchbase/src/lcbio/connect.c +557 -0
- data/ext/libcouchbase/src/lcbio/connect.h +364 -0
- data/ext/libcouchbase/src/lcbio/ctx.c +611 -0
- data/ext/libcouchbase/src/lcbio/ctx.h +405 -0
- data/ext/libcouchbase/src/lcbio/iotable.c +290 -0
- data/ext/libcouchbase/src/lcbio/iotable.h +84 -0
- data/ext/libcouchbase/src/lcbio/ioutils.c +350 -0
- data/ext/libcouchbase/src/lcbio/ioutils.h +203 -0
- data/ext/libcouchbase/src/lcbio/lcbio.h +51 -0
- data/ext/libcouchbase/src/lcbio/manager.c +584 -0
- data/ext/libcouchbase/src/lcbio/manager.h +156 -0
- data/ext/libcouchbase/src/lcbio/protoctx.c +84 -0
- data/ext/libcouchbase/src/lcbio/rw-inl.h +115 -0
- data/ext/libcouchbase/src/lcbio/ssl.h +149 -0
- data/ext/libcouchbase/src/lcbio/timer-ng.h +179 -0
- data/ext/libcouchbase/src/lcbio/timer.c +132 -0
- data/ext/libcouchbase/src/legacy.c +430 -0
- data/ext/libcouchbase/src/list.c +144 -0
- data/ext/libcouchbase/src/list.h +127 -0
- data/ext/libcouchbase/src/logging.c +244 -0
- data/ext/libcouchbase/src/logging.h +86 -0
- data/ext/libcouchbase/src/mc/compress.c +90 -0
- data/ext/libcouchbase/src/mc/compress.h +61 -0
- data/ext/libcouchbase/src/mc/forward.c +186 -0
- data/ext/libcouchbase/src/mc/forward.h +90 -0
- data/ext/libcouchbase/src/mc/iovcursor-inl.h +279 -0
- data/ext/libcouchbase/src/mc/iovcursor.h +66 -0
- data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +111 -0
- data/ext/libcouchbase/src/mc/mcreq.c +954 -0
- data/ext/libcouchbase/src/mc/mcreq.h +977 -0
- data/ext/libcouchbase/src/mcserver/mcserver.c +784 -0
- data/ext/libcouchbase/src/mcserver/mcserver.h +121 -0
- data/ext/libcouchbase/src/mcserver/negotiate.c +656 -0
- data/ext/libcouchbase/src/mcserver/negotiate.h +119 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +860 -0
- data/ext/libcouchbase/src/n1ql/n1ql-internal.h +22 -0
- data/ext/libcouchbase/src/n1ql/n1ql.cc +729 -0
- data/ext/libcouchbase/src/n1ql/params.cc +215 -0
- data/ext/libcouchbase/src/netbuf/netbuf-defs.h +89 -0
- data/ext/libcouchbase/src/netbuf/netbuf-mblock.h +235 -0
- data/ext/libcouchbase/src/netbuf/netbuf.c +929 -0
- data/ext/libcouchbase/src/netbuf/netbuf.h +452 -0
- data/ext/libcouchbase/src/newconfig.c +385 -0
- data/ext/libcouchbase/src/nodeinfo.cc +194 -0
- data/ext/libcouchbase/src/operations/cbflush.c +71 -0
- data/ext/libcouchbase/src/operations/counter.c +116 -0
- data/ext/libcouchbase/src/operations/durability-cas.c +224 -0
- data/ext/libcouchbase/src/operations/durability-seqno.c +157 -0
- data/ext/libcouchbase/src/operations/durability.c +668 -0
- data/ext/libcouchbase/src/operations/durability_internal.h +199 -0
- data/ext/libcouchbase/src/operations/get.c +409 -0
- data/ext/libcouchbase/src/operations/observe-seqno.c +96 -0
- data/ext/libcouchbase/src/operations/observe.c +340 -0
- data/ext/libcouchbase/src/operations/pktfwd.c +86 -0
- data/ext/libcouchbase/src/operations/remove.c +83 -0
- data/ext/libcouchbase/src/operations/stats.c +461 -0
- data/ext/libcouchbase/src/operations/store.c +360 -0
- data/ext/libcouchbase/src/operations/subdoc.cc +510 -0
- data/ext/libcouchbase/src/operations/touch.c +81 -0
- data/ext/libcouchbase/src/packetutils.c +60 -0
- data/ext/libcouchbase/src/packetutils.h +147 -0
- data/ext/libcouchbase/src/probes.d +211 -0
- data/ext/libcouchbase/src/rdb/bigalloc.c +225 -0
- data/ext/libcouchbase/src/rdb/bigalloc.h +73 -0
- data/ext/libcouchbase/src/rdb/chunkalloc.c +174 -0
- data/ext/libcouchbase/src/rdb/libcalloc.c +94 -0
- data/ext/libcouchbase/src/rdb/rope.c +419 -0
- data/ext/libcouchbase/src/rdb/rope.h +488 -0
- data/ext/libcouchbase/src/retrychk.c +113 -0
- data/ext/libcouchbase/src/retryq.c +424 -0
- data/ext/libcouchbase/src/retryq.h +157 -0
- data/ext/libcouchbase/src/ringbuffer.c +442 -0
- data/ext/libcouchbase/src/ringbuffer.h +100 -0
- data/ext/libcouchbase/src/settings.c +95 -0
- data/ext/libcouchbase/src/settings.h +188 -0
- data/ext/libcouchbase/src/simplestring.c +211 -0
- data/ext/libcouchbase/src/simplestring.h +228 -0
- data/ext/libcouchbase/src/sllist-inl.h +197 -0
- data/ext/libcouchbase/src/sllist.h +76 -0
- data/ext/libcouchbase/src/ssl/CMakeLists.txt +23 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +415 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +454 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +408 -0
- data/ext/libcouchbase/src/ssl/ssl_iot_common.h +180 -0
- data/ext/libcouchbase/src/ssobuf.h +82 -0
- data/ext/libcouchbase/src/strcodecs/base64.c +123 -0
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +285 -0
- data/ext/libcouchbase/src/timings.c +208 -0
- data/ext/libcouchbase/src/trace.h +105 -0
- data/ext/libcouchbase/src/utilities.c +171 -0
- data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -0
- data/ext/libcouchbase/src/vbucket/aliases.h +35 -0
- data/ext/libcouchbase/src/vbucket/crc32.h +83 -0
- data/ext/libcouchbase/src/vbucket/hash.h +30 -0
- data/ext/libcouchbase/src/vbucket/json-inl.h +112 -0
- data/ext/libcouchbase/src/vbucket/ketama.c +66 -0
- data/ext/libcouchbase/src/vbucket/rfc1321/global.h +32 -0
- data/ext/libcouchbase/src/vbucket/rfc1321/md5.h +35 -0
- data/ext/libcouchbase/src/vbucket/rfc1321/md5c-inl.h +335 -0
- data/ext/libcouchbase/src/vbucket/vbucket.c +1543 -0
- data/ext/libcouchbase/src/views/docreq.c +194 -0
- data/ext/libcouchbase/src/views/docreq.h +83 -0
- data/ext/libcouchbase/src/views/viewreq.c +358 -0
- data/ext/libcouchbase/src/views/viewreq.h +36 -0
- data/ext/libcouchbase/src/wait.c +161 -0
- data/ext/libcouchbase/tests/CMakeLists.txt +140 -0
- data/ext/libcouchbase/tests/basic/t_base64.cc +81 -0
- data/ext/libcouchbase/tests/basic/t_ccbc103.cc +95 -0
- data/ext/libcouchbase/tests/basic/t_connstr.cc +404 -0
- data/ext/libcouchbase/tests/basic/t_creds.cc +32 -0
- data/ext/libcouchbase/tests/basic/t_ctlcodes.cc +92 -0
- data/ext/libcouchbase/tests/basic/t_hashset.cc +262 -0
- data/ext/libcouchbase/tests/basic/t_host.cc +198 -0
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +137 -0
- data/ext/libcouchbase/tests/basic/t_jsparse.h +589 -0
- data/ext/libcouchbase/tests/basic/t_list.cc +155 -0
- data/ext/libcouchbase/tests/basic/t_logger.cc +65 -0
- data/ext/libcouchbase/tests/basic/t_misc.cc +24 -0
- data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +18 -0
- data/ext/libcouchbase/tests/basic/t_netbuf.cc +446 -0
- data/ext/libcouchbase/tests/basic/t_packet.cc +222 -0
- data/ext/libcouchbase/tests/basic/t_ringbuffer.cc +278 -0
- data/ext/libcouchbase/tests/basic/t_slist.cc +429 -0
- data/ext/libcouchbase/tests/basic/t_strerror.cc +64 -0
- data/ext/libcouchbase/tests/basic/t_string.cc +112 -0
- data/ext/libcouchbase/tests/basic/t_urlencode.cc +132 -0
- data/ext/libcouchbase/tests/check-all.cc +608 -0
- data/ext/libcouchbase/tests/htparse/t_basic.cc +193 -0
- data/ext/libcouchbase/tests/ioserver/connection.cc +166 -0
- data/ext/libcouchbase/tests/ioserver/future.cc +50 -0
- data/ext/libcouchbase/tests/ioserver/ioserver.cc +104 -0
- data/ext/libcouchbase/tests/ioserver/ioserver.h +478 -0
- data/ext/libcouchbase/tests/ioserver/socket.cc +88 -0
- data/ext/libcouchbase/tests/ioserver/ssl_connection.cc +145 -0
- data/ext/libcouchbase/tests/ioserver/threads-pthreads.cc +119 -0
- data/ext/libcouchbase/tests/ioserver/threads-win32.cc +117 -0
- data/ext/libcouchbase/tests/ioserver/threads.h +66 -0
- data/ext/libcouchbase/tests/iotests/iotests.h +15 -0
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +524 -0
- data/ext/libcouchbase/tests/iotests/mock-environment.h +385 -0
- data/ext/libcouchbase/tests/iotests/mock-unit-test.cc +67 -0
- data/ext/libcouchbase/tests/iotests/mock-unit-test.h +61 -0
- data/ext/libcouchbase/tests/iotests/serverparams.h +76 -0
- data/ext/libcouchbase/tests/iotests/t_arithmetic.cc +143 -0
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +226 -0
- data/ext/libcouchbase/tests/iotests/t_configcache.cc +117 -0
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +241 -0
- data/ext/libcouchbase/tests/iotests/t_durability.cc +1059 -0
- data/ext/libcouchbase/tests/iotests/t_forward.cc +110 -0
- data/ext/libcouchbase/tests/iotests/t_get.cc +512 -0
- data/ext/libcouchbase/tests/iotests/t_http.cc +438 -0
- data/ext/libcouchbase/tests/iotests/t_iops.cc +175 -0
- data/ext/libcouchbase/tests/iotests/t_lock.cc +275 -0
- data/ext/libcouchbase/tests/iotests/t_misc.cc +713 -0
- data/ext/libcouchbase/tests/iotests/t_mutate.cc +609 -0
- data/ext/libcouchbase/tests/iotests/t_n1ql.cc +270 -0
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +654 -0
- data/ext/libcouchbase/tests/iotests/t_obseqno.cc +157 -0
- data/ext/libcouchbase/tests/iotests/t_regression.cc +321 -0
- data/ext/libcouchbase/tests/iotests/t_sched.cc +88 -0
- data/ext/libcouchbase/tests/iotests/t_serverops.cc +230 -0
- data/ext/libcouchbase/tests/iotests/t_smoke.cc +528 -0
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +822 -0
- data/ext/libcouchbase/tests/iotests/t_syncmode.cc +64 -0
- data/ext/libcouchbase/tests/iotests/t_views.cc +405 -0
- data/ext/libcouchbase/tests/iotests/testutil.cc +250 -0
- data/ext/libcouchbase/tests/iotests/testutil.h +163 -0
- data/ext/libcouchbase/tests/mc/mctest.h +119 -0
- data/ext/libcouchbase/tests/mc/pktmaker.h +101 -0
- data/ext/libcouchbase/tests/mc/t_alloc.cc +269 -0
- data/ext/libcouchbase/tests/mc/t_context.cc +100 -0
- data/ext/libcouchbase/tests/mc/t_flush.cc +185 -0
- data/ext/libcouchbase/tests/mc/t_forward.cc +239 -0
- data/ext/libcouchbase/tests/mc/t_ioflush.cc +102 -0
- data/ext/libcouchbase/tests/mc/t_iovcursor.cc +173 -0
- data/ext/libcouchbase/tests/mocksupport/procutil.c +305 -0
- data/ext/libcouchbase/tests/mocksupport/procutil.h +89 -0
- data/ext/libcouchbase/tests/mocksupport/server.c +391 -0
- data/ext/libcouchbase/tests/mocksupport/server.h +72 -0
- data/ext/libcouchbase/tests/mocksupport/timeout.c +69 -0
- data/ext/libcouchbase/tests/nonio_tests.cc +23 -0
- data/ext/libcouchbase/tests/rdb/rdbtest.h +133 -0
- data/ext/libcouchbase/tests/rdb/t_basic.cc +128 -0
- data/ext/libcouchbase/tests/rdb/t_bigalloc.cc +93 -0
- data/ext/libcouchbase/tests/rdb/t_refs.cc +112 -0
- data/ext/libcouchbase/tests/socktests/socktest.cc +347 -0
- data/ext/libcouchbase/tests/socktests/socktest.h +448 -0
- data/ext/libcouchbase/tests/socktests/t_basic.cc +143 -0
- data/ext/libcouchbase/tests/socktests/t_ctx.cc +73 -0
- data/ext/libcouchbase/tests/socktests/t_manager.cc +179 -0
- data/ext/libcouchbase/tests/socktests/t_putex.cc +256 -0
- data/ext/libcouchbase/tests/socktests/t_read.cc +187 -0
- data/ext/libcouchbase/tests/socktests/t_reentrant.cc +143 -0
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +80 -0
- data/ext/libcouchbase/tests/socktests/t_write.cc +95 -0
- data/ext/libcouchbase/tests/start_mock.bat +15 -0
- data/ext/libcouchbase/tests/start_mock.sh +42 -0
- data/ext/libcouchbase/tests/unit_tests.cc +43 -0
- data/ext/libcouchbase/tests/vbucket/confdata/bad.json +101 -0
- data/ext/libcouchbase/tests/vbucket/confdata/full_25.json +363 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_25.json +90 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_30.json +1 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_45.json +1 -0
- data/ext/libcouchbase/tests/vbucket/confdata/terse_25.json +291 -0
- data/ext/libcouchbase/tests/vbucket/confdata/terse_30.json +1 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +341 -0
- data/ext/libcouchbase/tools/CMakeLists.txt +51 -0
- data/ext/libcouchbase/tools/cbc-handlers.h +462 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +439 -0
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +822 -0
- data/ext/libcouchbase/tools/cbc.cc +1541 -0
- data/ext/libcouchbase/tools/common/histogram.cc +43 -0
- data/ext/libcouchbase/tools/common/histogram.h +23 -0
- data/ext/libcouchbase/tools/common/my_inttypes.h +22 -0
- data/ext/libcouchbase/tools/common/options.cc +420 -0
- data/ext/libcouchbase/tools/common/options.h +81 -0
- data/ext/libcouchbase/tools/docgen/docgen.h +469 -0
- data/ext/libcouchbase/tools/docgen/loc.h +210 -0
- data/ext/libcouchbase/tools/docgen/placeholders.h +211 -0
- data/ext/libcouchbase/tools/docgen/seqgen.h +94 -0
- data/lib/libcouchbase.rb +36 -0
- data/lib/libcouchbase/bucket.rb +819 -0
- data/lib/libcouchbase/callbacks.rb +72 -0
- data/lib/libcouchbase/connection.rb +790 -0
- data/lib/libcouchbase/design_docs.rb +86 -0
- data/lib/libcouchbase/error.rb +68 -0
- data/lib/libcouchbase/ext/libcouchbase.rb +1135 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdbase.rb +23 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdcounter.rb +36 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdendure.rb +26 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdfts.rb +24 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdget.rb +30 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdgetreplica.rb +49 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdhttp.rb +58 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdn1ql.rb +40 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdobseqno.rb +33 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdobserve.rb +30 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdstore.rb +40 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdstoredur.rb +45 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdsubdoc.rb +49 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdverbosity.rb +29 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdviewquery.rb +61 -0
- data/lib/libcouchbase/ext/libcouchbase/contigbuf.rb +14 -0
- data/lib/libcouchbase/ext/libcouchbase/create_st.rb +15 -0
- data/lib/libcouchbase/ext/libcouchbase/create_st0.rb +23 -0
- data/lib/libcouchbase/ext/libcouchbase/create_st1.rb +26 -0
- data/lib/libcouchbase/ext/libcouchbase/create_st2.rb +32 -0
- data/lib/libcouchbase/ext/libcouchbase/create_st3.rb +26 -0
- data/lib/libcouchbase/ext/libcouchbase/crst_u.rb +20 -0
- data/lib/libcouchbase/ext/libcouchbase/durability_opts_st_v.rb +11 -0
- data/lib/libcouchbase/ext/libcouchbase/durability_opts_t.rb +14 -0
- data/lib/libcouchbase/ext/libcouchbase/durabilityopt_sv0.rb +63 -0
- data/lib/libcouchbase/ext/libcouchbase/enums.rb +991 -0
- data/lib/libcouchbase/ext/libcouchbase/fragbuf.rb +18 -0
- data/lib/libcouchbase/ext/libcouchbase/ftshandle.rb +7 -0
- data/lib/libcouchbase/ext/libcouchbase/histogram.rb +34 -0
- data/lib/libcouchbase/ext/libcouchbase/http_request_t.rb +7 -0
- data/lib/libcouchbase/ext/libcouchbase/keybuf.rb +20 -0
- data/lib/libcouchbase/ext/libcouchbase/multicmd_ctx.rb +30 -0
- data/lib/libcouchbase/ext/libcouchbase/mutation_token.rb +17 -0
- data/lib/libcouchbase/ext/libcouchbase/n1qlhandle.rb +7 -0
- data/lib/libcouchbase/ext/libcouchbase/n1qlparams.rb +7 -0
- data/lib/libcouchbase/ext/libcouchbase/respbase.rb +29 -0
- data/lib/libcouchbase/ext/libcouchbase/respcounter.rb +32 -0
- data/lib/libcouchbase/ext/libcouchbase/respendure.rb +49 -0
- data/lib/libcouchbase/ext/libcouchbase/respfts.rb +40 -0
- data/lib/libcouchbase/ext/libcouchbase/respget.rb +44 -0
- data/lib/libcouchbase/ext/libcouchbase/resphttp.rb +48 -0
- data/lib/libcouchbase/ext/libcouchbase/respmcversion.rb +38 -0
- data/lib/libcouchbase/ext/libcouchbase/respn1ql.rb +41 -0
- data/lib/libcouchbase/ext/libcouchbase/respobseqno.rb +52 -0
- data/lib/libcouchbase/ext/libcouchbase/respobserve.rb +41 -0
- data/lib/libcouchbase/ext/libcouchbase/respserverbase.rb +32 -0
- data/lib/libcouchbase/ext/libcouchbase/respstats.rb +38 -0
- data/lib/libcouchbase/ext/libcouchbase/respstore.rb +32 -0
- data/lib/libcouchbase/ext/libcouchbase/respstoredur.rb +38 -0
- data/lib/libcouchbase/ext/libcouchbase/respsubdoc.rb +35 -0
- data/lib/libcouchbase/ext/libcouchbase/respviewquery.rb +67 -0
- data/lib/libcouchbase/ext/libcouchbase/sdentry.rb +22 -0
- data/lib/libcouchbase/ext/libcouchbase/sdspec.rb +26 -0
- data/lib/libcouchbase/ext/libcouchbase/t.rb +7 -0
- data/lib/libcouchbase/ext/libcouchbase/valbuf.rb +22 -0
- data/lib/libcouchbase/ext/libcouchbase/valbuf_u_buf.rb +14 -0
- data/lib/libcouchbase/ext/libcouchbase/viewhandle.rb +7 -0
- data/lib/libcouchbase/ext/libcouchbase_iocp.rb +26 -0
- data/lib/libcouchbase/ext/libcouchbase_libuv.rb +18 -0
- data/lib/libcouchbase/ext/tasks.rb +87 -0
- data/lib/libcouchbase/n1ql.rb +73 -0
- data/lib/libcouchbase/query_full_text.rb +147 -0
- data/lib/libcouchbase/query_n1ql.rb +121 -0
- data/lib/libcouchbase/query_view.rb +129 -0
- data/lib/libcouchbase/results_fiber.rb +262 -0
- data/lib/libcouchbase/results_native.rb +211 -0
- data/lib/libcouchbase/version.rb +5 -0
- data/libcouchbase.gemspec +61 -0
- data/spec/bucket_spec.rb +270 -0
- data/spec/connection_spec.rb +277 -0
- data/spec/design_docs_spec.rb +23 -0
- data/spec/error_spec.rb +26 -0
- data/spec/fts_spec.rb +129 -0
- data/spec/n1ql_spec.rb +201 -0
- data/spec/results_libuv_spec.rb +229 -0
- data/spec/results_native_spec.rb +259 -0
- data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/design.json +1 -0
- data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/data-0000.cbb +0 -0
- data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/failover.json +1 -0
- data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/meta.json +1 -0
- data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/seqno.json +1 -0
- data/spec/seed/2016-10-25T043505Z/2016-10-25T043505Z-full/bucket-default/node-127.0.0.1%3A8091/snapshot_markers.json +1 -0
- data/spec/view_spec.rb +195 -0
- 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
|
+
}
|