couchbase 4.2.3 → 4.2.5-dev.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 (205) hide show
  1. package/CMakeLists.txt +136 -11
  2. package/deps/couchbase-cxx-client/CMakeLists.txt +54 -4
  3. package/deps/couchbase-cxx-client/README.md +1 -0
  4. package/deps/couchbase-cxx-client/bin/create-search-index +164 -0
  5. package/deps/couchbase-cxx-client/bin/init-cluster +55 -10
  6. package/deps/couchbase-cxx-client/bin/run-unit-tests +62 -6
  7. package/deps/couchbase-cxx-client/bin/travel-sample-index-v6.json +184 -0
  8. package/deps/couchbase-cxx-client/bin/travel-sample-index.json +188 -0
  9. package/deps/couchbase-cxx-client/cmake/Documentation.cmake +0 -1
  10. package/deps/couchbase-cxx-client/cmake/OpenSSL.cmake +98 -3
  11. package/deps/couchbase-cxx-client/cmake/Testing.cmake +8 -0
  12. package/deps/couchbase-cxx-client/cmake/build_config.hxx.in +3 -0
  13. package/deps/couchbase-cxx-client/core/bucket.cxx +183 -152
  14. package/deps/couchbase-cxx-client/core/bucket.hxx +17 -4
  15. package/deps/couchbase-cxx-client/core/cluster.hxx +18 -1
  16. package/deps/couchbase-cxx-client/core/cluster_options.hxx +1 -0
  17. package/deps/couchbase-cxx-client/core/error_context/key_value.cxx +2 -1
  18. package/deps/couchbase-cxx-client/core/error_context/key_value.hxx +10 -12
  19. package/deps/couchbase-cxx-client/core/error_context/search.hxx +1 -1
  20. package/deps/couchbase-cxx-client/core/impl/analytics.cxx +1 -0
  21. package/deps/couchbase-cxx-client/core/impl/boolean_field_query.cxx +40 -0
  22. package/deps/couchbase-cxx-client/core/impl/boolean_query.cxx +62 -0
  23. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +1 -0
  24. package/deps/couchbase-cxx-client/core/impl/conjunction_query.cxx +51 -0
  25. package/deps/couchbase-cxx-client/core/impl/date_range.cxx +89 -0
  26. package/deps/couchbase-cxx-client/core/impl/date_range_facet.cxx +54 -0
  27. package/deps/couchbase-cxx-client/core/impl/date_range_facet_result.cxx +64 -0
  28. package/deps/couchbase-cxx-client/core/impl/date_range_query.cxx +125 -0
  29. package/deps/couchbase-cxx-client/core/impl/disjunction_query.cxx +51 -0
  30. package/deps/couchbase-cxx-client/core/impl/encoded_search_facet.hxx +29 -0
  31. package/deps/couchbase-cxx-client/core/impl/encoded_search_query.hxx +29 -0
  32. package/deps/couchbase-cxx-client/core/impl/encoded_search_sort.hxx +29 -0
  33. package/deps/couchbase-cxx-client/core/impl/geo_bounding_box_query.cxx +46 -0
  34. package/deps/couchbase-cxx-client/core/impl/geo_distance_query.cxx +43 -0
  35. package/deps/couchbase-cxx-client/core/impl/geo_polygon_query.cxx +46 -0
  36. package/deps/couchbase-cxx-client/core/impl/internal_date_range_facet_result.cxx +80 -0
  37. package/deps/couchbase-cxx-client/core/impl/internal_date_range_facet_result.hxx +48 -0
  38. package/deps/couchbase-cxx-client/core/impl/internal_numeric_range_facet_result.cxx +80 -0
  39. package/deps/couchbase-cxx-client/core/impl/internal_numeric_range_facet_result.hxx +48 -0
  40. package/deps/couchbase-cxx-client/core/impl/internal_search_error_context.cxx +141 -0
  41. package/deps/couchbase-cxx-client/core/impl/internal_search_error_context.hxx +61 -0
  42. package/deps/couchbase-cxx-client/core/impl/internal_search_meta_data.cxx +60 -0
  43. package/deps/couchbase-cxx-client/core/impl/internal_search_meta_data.hxx +41 -0
  44. package/deps/couchbase-cxx-client/core/impl/internal_search_result.cxx +84 -0
  45. package/deps/couchbase-cxx-client/core/impl/internal_search_result.hxx +43 -0
  46. package/deps/couchbase-cxx-client/core/impl/internal_search_row.cxx +82 -0
  47. package/deps/couchbase-cxx-client/core/impl/internal_search_row.hxx +56 -0
  48. package/deps/couchbase-cxx-client/core/impl/internal_search_row_location.hxx +32 -0
  49. package/deps/couchbase-cxx-client/core/impl/internal_search_row_locations.cxx +137 -0
  50. package/deps/couchbase-cxx-client/core/impl/internal_search_row_locations.hxx +45 -0
  51. package/deps/couchbase-cxx-client/core/impl/internal_term_facet_result.cxx +80 -0
  52. package/deps/couchbase-cxx-client/core/impl/internal_term_facet_result.hxx +48 -0
  53. package/deps/couchbase-cxx-client/core/impl/key_value_error_context.cxx +98 -0
  54. package/deps/couchbase-cxx-client/core/impl/match_all_query.cxx +35 -0
  55. package/deps/couchbase-cxx-client/core/impl/match_none_query.cxx +35 -0
  56. package/deps/couchbase-cxx-client/core/impl/match_phrase_query.cxx +43 -0
  57. package/deps/couchbase-cxx-client/core/impl/match_query.cxx +59 -0
  58. package/deps/couchbase-cxx-client/core/impl/numeric_range.cxx +49 -0
  59. package/deps/couchbase-cxx-client/core/impl/numeric_range_facet.cxx +54 -0
  60. package/deps/couchbase-cxx-client/core/impl/numeric_range_facet_result.cxx +64 -0
  61. package/deps/couchbase-cxx-client/core/impl/numeric_range_query.cxx +56 -0
  62. package/deps/couchbase-cxx-client/core/impl/phrase_query.cxx +42 -0
  63. package/deps/couchbase-cxx-client/core/impl/prefix_query.cxx +40 -0
  64. package/deps/couchbase-cxx-client/core/impl/query_error_context.cxx +75 -0
  65. package/deps/couchbase-cxx-client/core/impl/query_string_query.cxx +37 -0
  66. package/deps/couchbase-cxx-client/core/impl/regexp_query.cxx +40 -0
  67. package/deps/couchbase-cxx-client/core/impl/search.cxx +191 -0
  68. package/deps/couchbase-cxx-client/core/impl/search_error_context.cxx +147 -0
  69. package/deps/couchbase-cxx-client/core/impl/search_meta_data.cxx +46 -0
  70. package/deps/couchbase-cxx-client/core/impl/search_result.cxx +66 -0
  71. package/deps/couchbase-cxx-client/core/impl/search_row.cxx +74 -0
  72. package/deps/couchbase-cxx-client/core/impl/search_row_location.cxx +64 -0
  73. package/deps/couchbase-cxx-client/core/impl/search_row_locations.cxx +66 -0
  74. package/deps/couchbase-cxx-client/core/impl/search_sort_field.cxx +104 -0
  75. package/deps/couchbase-cxx-client/core/impl/search_sort_id.cxx +43 -0
  76. package/deps/couchbase-cxx-client/core/impl/search_sort_score.cxx +43 -0
  77. package/deps/couchbase-cxx-client/core/impl/term_facet.cxx +36 -0
  78. package/deps/couchbase-cxx-client/core/impl/term_facet_result.cxx +64 -0
  79. package/deps/couchbase-cxx-client/core/impl/term_query.cxx +56 -0
  80. package/deps/couchbase-cxx-client/core/impl/term_range_query.cxx +57 -0
  81. package/deps/couchbase-cxx-client/core/impl/wildcard_query.cxx +40 -0
  82. package/deps/couchbase-cxx-client/core/io/mcbp_command.hxx +9 -2
  83. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +54 -37
  84. package/deps/couchbase-cxx-client/core/io/mcbp_session.hxx +4 -3
  85. package/deps/couchbase-cxx-client/core/json_string.hxx +5 -0
  86. package/deps/couchbase-cxx-client/core/meta/version.cxx +18 -4
  87. package/deps/couchbase-cxx-client/core/mozilla_ca_bundle.hxx +39 -0
  88. package/deps/couchbase-cxx-client/core/operations/document_search.cxx +3 -1
  89. package/deps/couchbase-cxx-client/core/operations/document_search.hxx +1 -1
  90. package/deps/couchbase-cxx-client/core/protocol/client_request.hxx +11 -2
  91. package/deps/couchbase-cxx-client/core/protocol/client_response.hxx +1 -0
  92. package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +59 -46
  93. package/deps/couchbase-cxx-client/core/utils/connection_string.hxx +1 -0
  94. package/deps/couchbase-cxx-client/couchbase/analytics_error_context.hxx +1 -1
  95. package/deps/couchbase-cxx-client/couchbase/boolean_field_query.hxx +77 -0
  96. package/deps/couchbase-cxx-client/couchbase/boolean_query.hxx +223 -0
  97. package/deps/couchbase-cxx-client/couchbase/cluster.hxx +39 -0
  98. package/deps/couchbase-cxx-client/couchbase/conjunction_query.hxx +88 -0
  99. package/deps/couchbase-cxx-client/couchbase/date_range.hxx +69 -0
  100. package/deps/couchbase-cxx-client/couchbase/date_range_facet.hxx +56 -0
  101. package/deps/couchbase-cxx-client/couchbase/date_range_facet_result.hxx +55 -0
  102. package/deps/couchbase-cxx-client/couchbase/date_range_query.hxx +265 -0
  103. package/deps/couchbase-cxx-client/couchbase/disjunction_query.hxx +109 -0
  104. package/deps/couchbase-cxx-client/couchbase/doc_id_query.hxx +111 -0
  105. package/deps/couchbase-cxx-client/couchbase/error_context.hxx +17 -8
  106. package/deps/couchbase-cxx-client/couchbase/fmt/analytics_scan_consistency.hxx +52 -0
  107. package/deps/couchbase-cxx-client/{core/topology/error_map_fmt.hxx → couchbase/fmt/key_value_error_map_attribute.hxx} +21 -21
  108. package/deps/couchbase-cxx-client/couchbase/fmt/search_scan_consistency.hxx +49 -0
  109. package/deps/couchbase-cxx-client/couchbase/geo_bounding_box_query.hxx +107 -0
  110. package/deps/couchbase-cxx-client/couchbase/geo_distance_query.hxx +109 -0
  111. package/deps/couchbase-cxx-client/couchbase/geo_point.hxx +32 -0
  112. package/deps/couchbase-cxx-client/couchbase/geo_polygon_query.hxx +85 -0
  113. package/deps/couchbase-cxx-client/couchbase/highlight_style.hxx +45 -0
  114. package/deps/couchbase-cxx-client/couchbase/key_value_error_context.hxx +7 -2
  115. package/deps/couchbase-cxx-client/couchbase/manager_error_context.hxx +1 -1
  116. package/deps/couchbase-cxx-client/couchbase/match_all_query.hxx +43 -0
  117. package/deps/couchbase-cxx-client/couchbase/match_none_query.hxx +43 -0
  118. package/deps/couchbase-cxx-client/couchbase/match_operator.hxx +45 -0
  119. package/deps/couchbase-cxx-client/couchbase/match_phrase_query.hxx +108 -0
  120. package/deps/couchbase-cxx-client/couchbase/match_query.hxx +163 -0
  121. package/deps/couchbase-cxx-client/couchbase/numeric_range.hxx +58 -0
  122. package/deps/couchbase-cxx-client/couchbase/numeric_range_facet.hxx +56 -0
  123. package/deps/couchbase-cxx-client/couchbase/numeric_range_facet_result.hxx +55 -0
  124. package/deps/couchbase-cxx-client/couchbase/numeric_range_query.hxx +143 -0
  125. package/deps/couchbase-cxx-client/couchbase/phrase_query.hxx +93 -0
  126. package/deps/couchbase-cxx-client/couchbase/prefix_query.hxx +82 -0
  127. package/deps/couchbase-cxx-client/couchbase/query_error_context.hxx +3 -1
  128. package/deps/couchbase-cxx-client/couchbase/query_string_query.hxx +72 -0
  129. package/deps/couchbase-cxx-client/couchbase/regexp_query.hxx +82 -0
  130. package/deps/couchbase-cxx-client/couchbase/scope.hxx +39 -0
  131. package/deps/couchbase-cxx-client/couchbase/search_date_range.hxx +68 -0
  132. package/deps/couchbase-cxx-client/couchbase/search_error_context.hxx +138 -0
  133. package/deps/couchbase-cxx-client/couchbase/search_facet.hxx +60 -0
  134. package/deps/couchbase-cxx-client/couchbase/search_facet_result.hxx +50 -0
  135. package/deps/couchbase-cxx-client/couchbase/search_meta_data.hxx +85 -0
  136. package/deps/couchbase-cxx-client/couchbase/search_metrics.hxx +127 -0
  137. package/deps/couchbase-cxx-client/couchbase/search_numeric_range.hxx +69 -0
  138. package/deps/couchbase-cxx-client/couchbase/search_options.hxx +509 -0
  139. package/deps/couchbase-cxx-client/couchbase/search_query.hxx +69 -0
  140. package/deps/couchbase-cxx-client/couchbase/search_result.hxx +77 -0
  141. package/deps/couchbase-cxx-client/couchbase/search_row.hxx +104 -0
  142. package/deps/couchbase-cxx-client/couchbase/search_row_location.hxx +55 -0
  143. package/deps/couchbase-cxx-client/couchbase/search_row_locations.hxx +86 -0
  144. package/deps/couchbase-cxx-client/couchbase/search_scan_consistency.hxx +34 -0
  145. package/deps/couchbase-cxx-client/couchbase/search_sort.hxx +58 -0
  146. package/deps/couchbase-cxx-client/couchbase/search_sort_field.hxx +117 -0
  147. package/deps/couchbase-cxx-client/couchbase/search_sort_field_missing.hxx +26 -0
  148. package/deps/couchbase-cxx-client/couchbase/search_sort_field_mode.hxx +27 -0
  149. package/deps/couchbase-cxx-client/couchbase/search_sort_field_type.hxx +28 -0
  150. package/deps/couchbase-cxx-client/couchbase/search_sort_id.hxx +60 -0
  151. package/deps/couchbase-cxx-client/couchbase/search_sort_score.hxx +60 -0
  152. package/deps/couchbase-cxx-client/couchbase/search_term_range.hxx +51 -0
  153. package/deps/couchbase-cxx-client/couchbase/security_options.hxx +3 -0
  154. package/deps/couchbase-cxx-client/couchbase/subdocument_error_context.hxx +4 -2
  155. package/deps/couchbase-cxx-client/couchbase/term_facet.hxx +48 -0
  156. package/deps/couchbase-cxx-client/couchbase/term_facet_result.hxx +55 -0
  157. package/deps/couchbase-cxx-client/couchbase/term_query.hxx +151 -0
  158. package/deps/couchbase-cxx-client/couchbase/term_range_query.hxx +142 -0
  159. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_options.hxx +1 -1
  160. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_query_options.hxx +2 -1
  161. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_result.hxx +1 -1
  162. package/deps/couchbase-cxx-client/couchbase/transactions.hxx +3 -3
  163. package/deps/couchbase-cxx-client/couchbase/wildcard_query.hxx +83 -0
  164. package/deps/couchbase-cxx-client/docs/Doxyfile.in +1 -1
  165. package/deps/couchbase-cxx-client/docs/cbc-analytics.md +2 -2
  166. package/deps/couchbase-cxx-client/docs/cbc-get.md +3 -2
  167. package/deps/couchbase-cxx-client/docs/cbc-pillowfight.md +7 -2
  168. package/deps/couchbase-cxx-client/docs/cbc-query.md +2 -2
  169. package/deps/couchbase-cxx-client/docs/cbc.md +3 -3
  170. package/deps/couchbase-cxx-client/docs/cli.hxx +5 -5
  171. package/deps/couchbase-cxx-client/docs/mainpage.hxx +42 -5
  172. package/deps/couchbase-cxx-client/test/CMakeLists.txt +1 -0
  173. package/deps/couchbase-cxx-client/test/test_integration_analytics.cxx +28 -6
  174. package/deps/couchbase-cxx-client/test/test_integration_collections.cxx +7 -3
  175. package/deps/couchbase-cxx-client/test/test_integration_connect.cxx +7 -3
  176. package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +13 -3
  177. package/deps/couchbase-cxx-client/test/test_integration_diagnostics.cxx +8 -2
  178. package/deps/couchbase-cxx-client/test/test_integration_durability.cxx +12 -7
  179. package/deps/couchbase-cxx-client/test/test_integration_examples.cxx +283 -11
  180. package/deps/couchbase-cxx-client/test/test_integration_management.cxx +140 -88
  181. package/deps/couchbase-cxx-client/test/test_integration_query.cxx +67 -9
  182. package/deps/couchbase-cxx-client/test/test_integration_range_scan.cxx +12 -12
  183. package/deps/couchbase-cxx-client/test/test_integration_read_replica.cxx +48 -11
  184. package/deps/couchbase-cxx-client/test/test_integration_search.cxx +19 -1
  185. package/deps/couchbase-cxx-client/test/test_integration_subdoc.cxx +60 -9
  186. package/deps/couchbase-cxx-client/test/test_integration_tracer.cxx +3 -0
  187. package/deps/couchbase-cxx-client/test/test_integration_transcoders.cxx +4 -0
  188. package/deps/couchbase-cxx-client/test/test_transaction_examples.cxx +100 -85
  189. package/deps/couchbase-cxx-client/test/test_unit_connection_string.cxx +29 -0
  190. package/deps/couchbase-cxx-client/test/test_unit_search.cxx +427 -0
  191. package/deps/couchbase-cxx-client/test/utils/integration_test_guard.cxx +2 -1
  192. package/deps/couchbase-cxx-client/test/utils/logger.cxx +3 -1
  193. package/deps/couchbase-cxx-client/test/utils/server_version.hxx +31 -15
  194. package/deps/couchbase-cxx-client/test/utils/test_context.cxx +8 -0
  195. package/deps/couchbase-cxx-client/tools/get.cxx +9 -8
  196. package/deps/couchbase-cxx-client/tools/pillowfight.cxx +175 -75
  197. package/deps/couchbase-cxx-client/tools/version.cxx +4 -2
  198. package/dist/binding.d.ts +1 -1
  199. package/dist/binding.js +3 -2
  200. package/package.json +96 -1
  201. package/scripts/createPlatformPackages.js +108 -0
  202. package/scripts/install.js +45 -0
  203. package/scripts/prebuilds.js +249 -0
  204. package/scripts/prune.js +124 -0
  205. package/src/jstocbpp_autogen.hpp +3 -2
@@ -63,8 +63,13 @@ TEST_CASE("integration: get any replica", "[integration]")
63
63
  {
64
64
  test::utils::integration_test_guard integration;
65
65
 
66
- if (integration.number_of_replicas() == 0 && integration.number_of_nodes() <= integration.number_of_replicas()) {
67
- return;
66
+ if (integration.number_of_replicas() == 0) {
67
+ SKIP("bucket has zero replicas");
68
+ }
69
+ if (integration.number_of_nodes() <= integration.number_of_replicas()) {
70
+ SKIP(fmt::format("number of nodes ({}) is less or equal to number of replicas ({})",
71
+ integration.number_of_nodes(),
72
+ integration.number_of_replicas()));
68
73
  }
69
74
 
70
75
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
@@ -95,8 +100,12 @@ TEST_CASE("integration: get all replicas", "[integration]")
95
100
  test::utils::integration_test_guard integration;
96
101
 
97
102
  auto number_of_replicas = integration.number_of_replicas();
98
- if (number_of_replicas == 0 && integration.number_of_nodes() <= number_of_replicas) {
99
- return;
103
+ if (number_of_replicas == 0) {
104
+ SKIP("bucket has zero replicas");
105
+ }
106
+ if (integration.number_of_nodes() <= number_of_replicas) {
107
+ SKIP(fmt::format(
108
+ "number of nodes ({}) is less or equal to number of replicas ({})", integration.number_of_nodes(), number_of_replicas));
100
109
  }
101
110
 
102
111
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
@@ -109,10 +118,16 @@ TEST_CASE("integration: get all replicas", "[integration]")
109
118
  couchbase::core::document_id id{ integration.ctx.bucket, scope_name, collection_name, key };
110
119
 
111
120
  couchbase::core::operations::insert_request req{ id, basic_doc_json };
121
+ req.durability_level = couchbase::durability_level::majority_and_persist_to_active;
112
122
  auto resp = test::utils::execute(integration.cluster, req);
113
123
  REQUIRE_SUCCESS(resp.ctx.ec());
114
124
  }
115
125
 
126
+ if (integration.cluster_version().is_mock()) {
127
+ // GOCAVES does not implement syncDurability. See https://github.com/couchbaselabs/gocaves/issues/109
128
+ std::this_thread::sleep_for(std::chrono::seconds{ 1 });
129
+ }
130
+
116
131
  {
117
132
  auto collection =
118
133
  couchbase::cluster(integration.cluster).bucket(integration.ctx.bucket).scope(scope_name).collection(collection_name);
@@ -128,8 +143,13 @@ TEST_CASE("integration: get all replicas with missing key", "[integration]")
128
143
  {
129
144
  test::utils::integration_test_guard integration;
130
145
 
131
- if (integration.number_of_replicas() == 0 && integration.number_of_nodes() <= integration.number_of_replicas()) {
132
- return;
146
+ if (integration.number_of_replicas() == 0) {
147
+ SKIP("bucket has zero replicas");
148
+ }
149
+ if (integration.number_of_nodes() <= integration.number_of_replicas()) {
150
+ SKIP(fmt::format("number of nodes ({}) is less or equal to number of replicas ({})",
151
+ integration.number_of_nodes(),
152
+ integration.number_of_replicas()));
133
153
  }
134
154
 
135
155
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
@@ -152,7 +172,9 @@ TEST_CASE("integration: get any replica with missing key", "[integration]")
152
172
  test::utils::integration_test_guard integration;
153
173
 
154
174
  if (integration.number_of_nodes() <= integration.number_of_replicas()) {
155
- return;
175
+ SKIP(fmt::format("number of nodes ({}) is less or equal to number of replicas ({})",
176
+ integration.number_of_nodes(),
177
+ integration.number_of_replicas()));
156
178
  }
157
179
 
158
180
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
@@ -173,8 +195,13 @@ TEST_CASE("integration: get any replica low-level version", "[integration]")
173
195
  {
174
196
  test::utils::integration_test_guard integration;
175
197
 
176
- if (integration.number_of_replicas() == 0 && integration.number_of_nodes() <= integration.number_of_replicas()) {
177
- return;
198
+ if (integration.number_of_replicas() == 0) {
199
+ SKIP("bucket has zero replicas");
200
+ }
201
+ if (integration.number_of_nodes() <= integration.number_of_replicas()) {
202
+ SKIP(fmt::format("number of nodes ({}) is less or equal to number of replicas ({})",
203
+ integration.number_of_nodes(),
204
+ integration.number_of_replicas()));
178
205
  }
179
206
 
180
207
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
@@ -204,8 +231,12 @@ TEST_CASE("integration: get all replicas low-level version", "[integration]")
204
231
  test::utils::integration_test_guard integration;
205
232
 
206
233
  auto number_of_replicas = integration.number_of_replicas();
207
- if (number_of_replicas == 0 && integration.number_of_nodes() <= integration.number_of_replicas()) {
208
- return;
234
+ if (number_of_replicas == 0) {
235
+ SKIP("bucket has zero replicas");
236
+ }
237
+ if (integration.number_of_nodes() <= number_of_replicas) {
238
+ SKIP(fmt::format(
239
+ "number of nodes ({}) is less or equal to number of replicas ({})", integration.number_of_nodes(), number_of_replicas));
209
240
  }
210
241
 
211
242
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
@@ -217,10 +248,16 @@ TEST_CASE("integration: get all replicas low-level version", "[integration]")
217
248
  { "b", 2.0 },
218
249
  };
219
250
  couchbase::core::operations::upsert_request req{ id, couchbase::core::utils::json::generate_binary(value) };
251
+ req.durability_level = couchbase::durability_level::majority_and_persist_to_active;
220
252
  auto resp = test::utils::execute(integration.cluster, req);
221
253
  REQUIRE_SUCCESS(resp.ctx.ec());
222
254
  }
223
255
 
256
+ if (integration.cluster_version().is_mock()) {
257
+ // GOCAVES does not implement syncDurability. See https://github.com/couchbaselabs/gocaves/issues/109
258
+ std::this_thread::sleep_for(std::chrono::seconds{ 1 });
259
+ }
260
+
224
261
  {
225
262
  couchbase::core::operations::get_all_replicas_request req{ id };
226
263
  auto resp = test::utils::execute(integration.cluster, req);
@@ -23,12 +23,18 @@
23
23
  #include "core/operations/management/search_index_drop.hxx"
24
24
  #include "core/operations/management/search_index_upsert.hxx"
25
25
 
26
+ #include <couchbase/query_string_query.hxx>
27
+
26
28
  using Catch::Matchers::StartsWith;
27
29
 
28
30
  TEST_CASE("integration: search query")
29
31
  {
30
32
  test::utils::integration_test_guard integration;
31
33
 
34
+ if (!integration.cluster_version().supports_search()) {
35
+ SKIP("cluster does not support search");
36
+ }
37
+
32
38
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
33
39
 
34
40
  {
@@ -350,6 +356,14 @@ TEST_CASE("integration: search query consistency", "[integration]")
350
356
  {
351
357
  test::utils::integration_test_guard integration;
352
358
 
359
+ if (integration.ctx.deployment == test::utils::deployment_type::elixir) {
360
+ SKIP("elixir deployment is incompatible with parts of this test");
361
+ }
362
+
363
+ if (!integration.cluster_version().supports_search()) {
364
+ SKIP("cluster does not support search");
365
+ }
366
+
353
367
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
354
368
 
355
369
  const std::string params =
@@ -476,8 +490,12 @@ TEST_CASE("integration: search query collections")
476
490
  {
477
491
  test::utils::integration_test_guard integration;
478
492
 
493
+ if (!integration.cluster_version().supports_search()) {
494
+ SKIP("cluster does not support search");
495
+ }
496
+
479
497
  if (!integration.cluster_version().supports_collections()) {
480
- return;
498
+ SKIP("cluster does not support collections");
481
499
  }
482
500
 
483
501
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
@@ -197,6 +197,10 @@ TEST_CASE("integration: subdoc get & exists", "[integration]")
197
197
 
198
198
  SECTION("non json get")
199
199
  {
200
+ if (integration.cluster_version().is_mock()) {
201
+ SKIP("GOCAVES does not handle subdocument operations for non-JSON documents. See "
202
+ "https://github.com/couchbaselabs/gocaves/issues/103");
203
+ }
200
204
  assert_single_lookup_error(integration,
201
205
  non_json_id,
202
206
  couchbase::lookup_in_specs::get("non-exist"),
@@ -206,6 +210,10 @@ TEST_CASE("integration: subdoc get & exists", "[integration]")
206
210
 
207
211
  SECTION("non json exists")
208
212
  {
213
+ if (integration.cluster_version().is_mock()) {
214
+ SKIP("GOCAVES does not handle subdocument operations for non-JSON documents. See "
215
+ "https://github.com/couchbaselabs/gocaves/issues/103");
216
+ }
209
217
  assert_single_lookup_error(integration,
210
218
  non_json_id,
211
219
  couchbase::lookup_in_specs::exists("non-exist"),
@@ -218,11 +226,19 @@ TEST_CASE("integration: subdoc get & exists", "[integration]")
218
226
  {
219
227
  std::vector<std::string> invalid_paths = { "invalid..path", "invalid[-2]" };
220
228
  for (const auto& path : invalid_paths) {
221
- assert_single_lookup_error(integration,
222
- id,
223
- couchbase::lookup_in_specs::get(path),
224
- couchbase::key_value_status_code::subdoc_path_invalid,
225
- couchbase::errc::key_value::path_invalid);
229
+ if (integration.cluster_version().is_mock()) {
230
+ assert_single_lookup_error(integration,
231
+ id,
232
+ couchbase::lookup_in_specs::get(path),
233
+ couchbase::key_value_status_code::subdoc_path_not_found,
234
+ couchbase::errc::key_value::path_not_found);
235
+ } else {
236
+ assert_single_lookup_error(integration,
237
+ id,
238
+ couchbase::lookup_in_specs::get(path),
239
+ couchbase::key_value_status_code::subdoc_path_invalid,
240
+ couchbase::errc::key_value::path_invalid);
241
+ }
226
242
  }
227
243
  }
228
244
 
@@ -317,6 +333,10 @@ TEST_CASE("integration: subdoc store", "[integration]")
317
333
 
318
334
  SECTION("non json")
319
335
  {
336
+ if (integration.cluster_version().is_mock()) {
337
+ SKIP("GOCAVES does not handle subdocument operations for non-JSON documents. See "
338
+ "https://github.com/couchbaselabs/gocaves/issues/103");
339
+ }
320
340
  std::string path{ "dict" };
321
341
  auto value = couchbase::core::utils::to_binary("non-json");
322
342
  couchbase::core::operations::mutate_in_request req{ id };
@@ -411,6 +431,11 @@ TEST_CASE("integration: subdoc mutate in store semantics", "[integration]")
411
431
  TEST_CASE("integration: subdoc unique", "[integration]")
412
432
  {
413
433
  test::utils::integration_test_guard integration;
434
+
435
+ if (integration.cluster_version().is_mock()) {
436
+ SKIP("GOCAVES does not support subdocument create_path feature. See https://github.com/couchbaselabs/gocaves/issues/17");
437
+ }
438
+
414
439
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
415
440
  couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("subdoc") };
416
441
 
@@ -453,7 +478,6 @@ TEST_CASE("integration: subdoc unique", "[integration]")
453
478
  couchbase::mutate_in_specs{ couchbase::mutate_in_specs::array_append("a", tao::json::empty_object).create_path() }.specs();
454
479
  auto resp = test::utils::execute(integration.cluster, req);
455
480
  assert_single_mutate_success(resp, "a");
456
- assert_single_lookup_success(integration, id, couchbase::lookup_in_specs::get("a[-1]"), "{}");
457
481
  }
458
482
 
459
483
  {
@@ -472,7 +496,10 @@ TEST_CASE("integration: subdoc counter", "[integration]")
472
496
  couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("subdoc") };
473
497
 
474
498
  {
475
- auto value_json = couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]]})");
499
+ auto value_json =
500
+ integration.cluster_version().is_mock() // kv_engine creates counters automatically
501
+ ? couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]],"counter":0})")
502
+ : couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]]})");
476
503
  couchbase::core::operations::insert_request req{ id, value_json };
477
504
  auto resp = test::utils::execute(integration.cluster, req);
478
505
  REQUIRE_SUCCESS(resp.ctx.ec());
@@ -497,6 +524,9 @@ TEST_CASE("integration: subdoc counter", "[integration]")
497
524
 
498
525
  SECTION("max value")
499
526
  {
527
+ if (integration.cluster_version().is_mock()) {
528
+ SKIP("GOCAVES incorrectly handles limits for subdoc counters. See https://github.com/couchbaselabs/gocaves/issues/104");
529
+ }
500
530
  {
501
531
  int64_t max_value = std::numeric_limits<int64_t>::max();
502
532
  couchbase::core::operations::mutate_in_request req{ id };
@@ -516,6 +546,9 @@ TEST_CASE("integration: subdoc counter", "[integration]")
516
546
 
517
547
  SECTION("invalid delta")
518
548
  {
549
+ if (integration.cluster_version().is_mock()) {
550
+ SKIP("GOCAVES incorrectly handles zero delta for subdoc counters. See https://github.com/couchbaselabs/gocaves/issues/105");
551
+ }
519
552
  couchbase::core::operations::mutate_in_request req{ id };
520
553
  req.specs = couchbase::mutate_in_specs{ couchbase::mutate_in_specs::increment("counter", 0) }.specs();
521
554
  auto resp = test::utils::execute(integration.cluster, req);
@@ -525,6 +558,9 @@ TEST_CASE("integration: subdoc counter", "[integration]")
525
558
 
526
559
  SECTION("increase number already too big")
527
560
  {
561
+ if (integration.cluster_version().is_mock()) {
562
+ SKIP("GOCAVES incorrectly handles big values for subdoc counters. See https://github.com/couchbaselabs/gocaves/issues/106");
563
+ }
528
564
  {
529
565
  auto big_value = R"({"counter":)" + std::to_string(std::numeric_limits<int64_t>::max()) + "999999999999999999999999999999}";
530
566
  auto value_json = couchbase::core::utils::to_binary(big_value);
@@ -621,7 +657,11 @@ TEST_CASE("integration: subdoc multi lookup", "[integration]")
621
657
  }
622
658
  .specs();
623
659
  auto resp = test::utils::execute(integration.cluster, req);
624
- REQUIRE(resp.ctx.ec() == couchbase::errc::common::invalid_argument);
660
+ if (integration.cluster_version().is_mock()) {
661
+ REQUIRE(resp.ctx.ec() == couchbase::errc::common::unsupported_operation);
662
+ } else {
663
+ REQUIRE(resp.ctx.ec() == couchbase::errc::common::invalid_argument);
664
+ }
625
665
  }
626
666
 
627
667
  SECTION("missing key")
@@ -647,7 +687,10 @@ TEST_CASE("integration: subdoc multi mutation", "[integration]")
647
687
  couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("subdoc") };
648
688
 
649
689
  {
650
- auto value_json = couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]]})");
690
+ auto value_json =
691
+ integration.cluster_version().is_mock() // kv_engine creates counters automatically
692
+ ? couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]],"counter":0})")
693
+ : couchbase::core::utils::to_binary(R"({"dictkey":"dictval","array":[1,2,3,4,[10,20,30,[100,200,300]]]})");
651
694
  couchbase::core::operations::insert_request req{ id, value_json };
652
695
  auto resp = test::utils::execute(integration.cluster, req);
653
696
  REQUIRE_SUCCESS(resp.ctx.ec());
@@ -676,6 +719,9 @@ TEST_CASE("integration: subdoc multi mutation", "[integration]")
676
719
 
677
720
  SECTION("replace with errors")
678
721
  {
722
+ if (integration.cluster_version().is_mock()) {
723
+ SKIP("GOCAVES incorrectly uses error indexes for subdoc mutations. See https://github.com/couchbaselabs/gocaves/issues/107");
724
+ }
679
725
  couchbase::core::operations::mutate_in_request req{ id };
680
726
  req.specs =
681
727
  couchbase::mutate_in_specs{
@@ -695,6 +741,11 @@ TEST_CASE("integration: subdoc multi mutation", "[integration]")
695
741
  TEST_CASE("integration: subdoc expiry")
696
742
  {
697
743
  test::utils::integration_test_guard integration;
744
+
745
+ if (integration.cluster_version().is_mock()) {
746
+ SKIP("GOCAVES does not support subdoc mutations with expiry. See https://github.com/couchbaselabs/gocaves/issues/85");
747
+ }
748
+
698
749
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
699
750
  couchbase::core::document_id id{ integration.ctx.bucket, "_default", "_default", test::utils::uniq_id("subdoc") };
700
751
 
@@ -249,6 +249,9 @@ TEST_CASE("integration: enable external tracer", "[integration]")
249
249
  {
250
250
  SECTION("query")
251
251
  {
252
+ if (!guard.cluster_version().supports_query()) {
253
+ SKIP("cluster does not support query");
254
+ }
252
255
  tracer->reset();
253
256
  couchbase::core::operations::query_request req{ R"(SELECT "ruby rules" AS greeting)" };
254
257
  req.parent_span = parent_span;
@@ -431,6 +431,10 @@ TEST_CASE("integration: subdoc with public API", "[integration]")
431
431
  {
432
432
  test::utils::integration_test_guard integration;
433
433
 
434
+ if (integration.cluster_version().is_mock()) {
435
+ SKIP("GOCAVES incorrectly uses error indexes for subdoc mutations. See https://github.com/couchbaselabs/gocaves/issues/107");
436
+ }
437
+
434
438
  test::utils::open_bucket(integration.cluster, integration.ctx.bucket);
435
439
 
436
440
  auto collection = couchbase::cluster(integration.cluster)
@@ -18,14 +18,18 @@
18
18
  #include "test_helper_integration.hxx"
19
19
 
20
20
  #include <couchbase/cluster.hxx>
21
+ #include <couchbase/fmt/cas.hxx>
21
22
  #include <couchbase/transactions/attempt_context.hxx>
23
+
22
24
  #include <tao/json.hpp>
23
25
 
24
26
  namespace blocking_txn
25
27
  {
26
28
  //! [blocking-txn]
27
29
  #include <couchbase/cluster.hxx>
30
+ #include <couchbase/fmt/cas.hxx>
28
31
  #include <couchbase/transactions/attempt_context.hxx>
32
+
29
33
  #include <tao/json.hpp>
30
34
 
31
35
  int
@@ -38,9 +42,10 @@ main(int argc, const char* argv[])
38
42
 
39
43
  int retval = 0;
40
44
 
41
- std::string connection_string{ argv[1] };
42
- std::string username{ argv[2] };
43
- std::string password{ argv[3] };
45
+ const std::string connection_string{ argv[1] };
46
+ const std::string username{ argv[2] };
47
+ const std::string password{ argv[3] };
48
+
44
49
  // run IO context on separate thread
45
50
  asio::io_context io;
46
51
  auto guard = asio::make_work_guard(io);
@@ -51,106 +56,116 @@ main(int argc, const char* argv[])
51
56
  // For example, optimize timeouts for WAN
52
57
  options.apply_profile("wan_development");
53
58
 
59
+ // [1] connect to cluster using the given connection string and the options
54
60
  auto [cluster, ec] = couchbase::cluster::connect(io, connection_string, options).get();
55
61
  if (ec) {
56
62
  fmt::print("unable to connect to the cluster: {}\n", ec.message());
57
63
  return 1;
58
64
  }
59
65
 
60
- auto coll = cluster.bucket("default").default_collection();
61
- auto id = "my-doc";
62
- auto id2 = "my_doc_2";
63
- auto id3 = "my_doc_3";
64
- ::tao::json::value content = { { "some", "content" } };
65
-
66
- // upsert all 3...
67
- auto [upsert_err, upsert_res] = coll.upsert(id, content).get();
68
- if (upsert_err.ec()) {
69
- fmt::print("upsert failed before starting transaction");
70
- return 1;
71
- }
72
- auto [upsert_err2, upsert_res2] = coll.upsert(id2, content).get();
73
- if (upsert_err2.ec()) {
74
- fmt::print("upsert failed before starting transaction");
75
- return 1;
76
- }
77
- auto [upsert_err3, upsert_res3] = coll.upsert(id3, content).get();
78
- if (upsert_err3.ec()) {
79
- fmt::print("upsert failed before starting transaction");
80
- return 1;
66
+ // [2] persist three documents to the default collection of bucket "default"
67
+ auto collection = cluster.bucket("default").default_collection();
68
+ constexpr auto id_1 = "my-doc_1";
69
+ constexpr auto id_2 = "my_doc_2";
70
+ constexpr auto id_3 = "my_doc_3";
71
+ const tao::json::value content = { { "some", "content" } };
72
+
73
+ for (const auto& id : { id_1, id_2, id_3 }) {
74
+ if (auto [ctx, res] = collection.upsert(id, content).get(); ctx.ec()) {
75
+ fmt::print(stderr, "upsert \"{}\" failed before starting transaction: {}\n", id, ctx.ec().message());
76
+ return 1;
77
+ }
81
78
  }
82
79
 
83
- //! [simple-blocking-txn]
84
- auto [e, txn_res] = cluster.transactions()->run([&](couchbase::transactions::attempt_context& ctx) {
85
- // get document
86
- auto [get_err, doc] = ctx.get(coll, id);
87
- if (get_err.ec()) {
88
- fmt::print("error getting doc {}: {}", id, get_err.ec().message());
89
- // don't continue the txn logic.
90
- return;
80
+ { // [3] blocking transaction
81
+ //! [simple-blocking-txn]
82
+ auto [tx_err, tx_res] = cluster.transactions()->run(
83
+ // [3.1] closure argument to run() method encapsulates logic, that has to be run in transaction
84
+ [&](couchbase::transactions::attempt_context& ctx) {
85
+ // [3.2] get document
86
+ auto [err_ctx, doc] = ctx.get(collection, id_1);
87
+ if (err_ctx.ec()) {
88
+ fmt::print(stderr, "failed to get document \"{}\": {}\n", id_1, err_ctx.ec().message());
89
+ // [3.3] don't continue the transaction logic
90
+ return;
91
+ }
92
+ // [3.4] replace document's content
93
+ ctx.replace(doc, ::tao::json::value{ { "some", "other content" } });
94
+ });
95
+ // [3.5] check the overall status of the transaction
96
+ if (tx_err.ec()) {
97
+ fmt::print(stderr, "error in transaction {}, cause: {}\n", tx_err.ec().message(), tx_err.cause().message());
98
+ retval = 1;
99
+ } else {
100
+ fmt::print("transaction {} completed successfully", tx_res.transaction_id);
91
101
  }
92
- // replace document content
93
- ctx.replace(doc, ::tao::json::value{ { "some", "other content" } });
94
- });
95
- if (e.ec()) {
96
- fmt::print("error in transaction {}, {}", e.ec().message(), e.cause().message());
97
- retval = 1;
98
- } else {
99
- fmt::print("transaction {} completed successfully", txn_res.transaction_id);
102
+ //! [simple-blocking-txn]
100
103
  }
101
- //! [simple-blocking-txn]
102
-
103
- //! [simple-async-txn]
104
- auto barrier = std::make_shared<std::promise<std::error_code>>();
105
- auto f = barrier->get_future();
106
- cluster.transactions()->run(
107
- [&](couchbase::transactions::async_attempt_context& ctx) {
108
- ctx.get(coll, id, [&](auto get_err, auto doc) {
109
- if (get_err.ec()) {
110
- fmt::print("error getting doc {}: {}", id, get_err.ec().message());
111
- } else {
112
- ctx.replace(doc, ::tao::json::value{ { "some", "other async content" } }, [&](auto replace_err, auto) {
113
- if (replace_err.ec()) {
114
- fmt::print("error replacing content in doc {}: {}", id, replace_err.ec().message());
104
+
105
+ { // [4] asynchronous transaction
106
+ //! [simple-async-txn]
107
+ // [4.1] create promise to retrieve result from the transaction
108
+ auto barrier = std::make_shared<std::promise<std::error_code>>();
109
+ auto f = barrier->get_future();
110
+ cluster.transactions()->run(
111
+ // [4.2] closure argument to run() method encapsulates logic, that has to be run in transaction
112
+ [&](couchbase::transactions::async_attempt_context& ctx) {
113
+ // [4.3] get document
114
+ ctx.get(collection, id_1, [&](auto err_ctx_1, auto doc) {
115
+ if (err_ctx_1.ec()) {
116
+ fmt::print(stderr, "failed to get document \"{}\": {}\n", id_1, err_ctx_1.ec().message());
117
+ return;
118
+ }
119
+ // [4.4] replace document's content
120
+ ctx.replace(doc, ::tao::json::value{ { "some", "other async content" } }, [&](auto err_ctx_2, auto res) {
121
+ if (err_ctx_2.ec()) {
122
+ fmt::print(stderr, "error replacing content in doc {}: {}\n", id_1, err_ctx_2.ec().message());
123
+ } else {
124
+ fmt::print("successfully replaced: {}, cas={}\n", id_1, res.cas());
115
125
  }
116
126
  });
117
- }
118
- });
119
- ctx.get(coll, id2, [&](auto get_err, auto doc) {
120
- if (get_err.ec()) {
121
- fmt::print("error getting doc {}: {}", id2, get_err.ec().message());
122
- } else {
123
- ctx.replace(doc, ::tao::json::value{ { "some", "other async content" } }, [&](auto replace_err, auto) {
124
- if (replace_err.ec()) {
125
- fmt::print("error replacing content in doc {}: {}", id, replace_err.ec().message());
127
+ });
128
+ ctx.get(collection, id_2, [&](auto err_ctx_1, auto doc) {
129
+ if (err_ctx_1.ec()) {
130
+ fmt::print("error getting doc {}: {}", id_2, err_ctx_1.ec().message());
131
+ return;
132
+ }
133
+ ctx.replace(doc, ::tao::json::value{ { "some", "other async content" } }, [&](auto err_ctx_2, auto res) {
134
+ if (err_ctx_2.ec()) {
135
+ fmt::print(stderr, "error replacing content in doc {}: {}\n", id_2, err_ctx_2.ec().message());
136
+ } else {
137
+ fmt::print("successfully replaced: {}, cas={}\n", id_2, res.cas());
126
138
  }
127
139
  });
128
- }
129
- });
130
- ctx.get(coll, id3, [&](auto get_err, auto doc) {
131
- if (get_err.ec()) {
132
- fmt::print("error getting doc {}: {}", id, get_err.ec().message());
133
- } else {
134
- ctx.replace(doc, ::tao::json::value{ { "some", "other async content" } }, [&](auto replace_err, auto) {
135
- if (replace_err.ec()) {
136
- fmt::print("error replacing content in doc {}: {}", id3, replace_err.ec().message());
140
+ });
141
+ ctx.get(collection, id_3, [&](auto err_ctx_1, auto doc) {
142
+ if (err_ctx_1.ec()) {
143
+ fmt::print("error getting doc {}: {}", id_3, err_ctx_1.ec().message());
144
+ return;
145
+ }
146
+ ctx.replace(doc, ::tao::json::value{ { "some", "other async content" } }, [&](auto err_ctx_2, auto res) {
147
+ if (err_ctx_2.ec()) {
148
+ fmt::print(stderr, "error replacing content in doc {}: {}\n", id_3, err_ctx_2.ec().message());
149
+ } else {
150
+ fmt::print("successfully replaced: {}, cas={}\n", id_3, res.cas());
137
151
  }
138
152
  });
153
+ });
154
+ },
155
+ // [4.5], second closure represents transaction completion logic
156
+ [barrier](auto tx_err, auto tx_res) {
157
+ if (tx_err.ec()) {
158
+ fmt::print(stderr, "error in async transaction {}, {}\n", tx_res.transaction_id, tx_err.ec().message());
139
159
  }
160
+ barrier->set_value(tx_err.ec());
140
161
  });
141
- },
142
- [barrier](auto tx_err, auto tx_result) {
143
- if (tx_err.ec()) {
144
- fmt::print("error in async transaction {}, {}", tx_result.transaction_id, tx_err.ec().message());
145
- }
146
- barrier->set_value(tx_err.ec());
147
- });
148
- if (auto async_err = f.get()) {
149
- retval = 1;
162
+ if (auto async_err = f.get()) {
163
+ retval = 1;
164
+ }
165
+ //! [simple-async-txn]
150
166
  }
151
- //! [simple-async-txn]
152
167
 
153
- // close cluster connection
168
+ // [5], close cluster connection
154
169
  cluster.close();
155
170
  guard.reset();
156
171
 
@@ -161,11 +176,11 @@ main(int argc, const char* argv[])
161
176
  //! [blocking-txn]
162
177
  } // namespace blocking_txn
163
178
 
164
- TEST_CASE("example: start using", "[integration]")
179
+ TEST_CASE("example: basic transaction", "[integration]")
165
180
  {
166
181
  test::utils::integration_test_guard integration;
167
182
  if (!integration.cluster_version().supports_collections()) {
168
- return;
183
+ SKIP("cluster does not support collections");
169
184
  }
170
185
 
171
186
  const auto env = test::utils::test_context::load_from_environment();
@@ -416,4 +416,33 @@ TEST_CASE("unit: connection string", "[unit]")
416
416
  CHECK(couchbase::core::utils::parse_connection_string("couchbase://2001:db8:85a3:8d3:1319:8a2e:370:7348").error.value() ==
417
417
  R"(failed to parse connection string (column: 18, trailer: "db8:85a3:8d3:1319:8a2e:370:7348"))");
418
418
  }
419
+
420
+ SECTION("parsing warnings")
421
+ {
422
+ auto spec = couchbase::core::utils::parse_connection_string("couchbase://127.0.0.1?kv_timeout=42&foo=bar");
423
+ CHECK(spec.warnings == std::vector<std::string>{
424
+ R"(unknown parameter "foo" in connection string (value "bar"))",
425
+ });
426
+
427
+ spec = couchbase::core::utils::parse_connection_string("couchbase://127.0.0.1?enable_dns_srv=maybe&ip_protocol=yes");
428
+ CHECK(spec.warnings ==
429
+ std::vector<std::string>{
430
+ R"(unable to parse "enable_dns_srv" parameter in connection string (value "maybe" cannot be interpreted as a boolean))",
431
+ R"(unable to parse "ip_protocol" parameter in connection string (value "yes" is not a valid IP protocol preference))",
432
+ });
433
+
434
+ spec = couchbase::core::utils::parse_connection_string("couchbase://localhost:8091=http;127.0.0.1=mcd/default?enable_dns_srv=true");
435
+ CHECK(
436
+ spec.warnings ==
437
+ std::vector<std::string>{
438
+ R"(parameter "enable_dns_srv" requires single entry in bootstrap nodes list of the connection string, ignoring (value "true"))",
439
+ });
440
+
441
+ spec = couchbase::core::utils::parse_connection_string(
442
+ "couchbase://localhost?query_timeout=10000&kv_timeout=true&management_timeout=11000");
443
+ std::string warning_prefix = R"(unable to parse "kv_timeout" parameter in connection string (value "true" is not a number))";
444
+ CHECK(spec.warnings.at(0).substr(0, warning_prefix.size()) == warning_prefix);
445
+ CHECK(spec.options.query_timeout == std::chrono::milliseconds(10000));
446
+ CHECK(spec.options.management_timeout == std::chrono::milliseconds(11000));
447
+ }
419
448
  }