couchbase 4.2.5-dev.3 → 4.2.6-dev

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 (122) hide show
  1. package/README.md +81 -9
  2. package/deps/couchbase-cxx-client/CMakeLists.txt +9 -1
  3. package/deps/couchbase-cxx-client/bin/api.rb +234 -0
  4. package/deps/couchbase-cxx-client/bin/create-search-index +18 -135
  5. package/deps/couchbase-cxx-client/bin/init-cluster +17 -139
  6. package/deps/couchbase-cxx-client/bin/load-sample-buckets +54 -0
  7. package/deps/couchbase-cxx-client/core/cluster.hxx +33 -12
  8. package/deps/couchbase-cxx-client/core/cluster_options.hxx +3 -0
  9. package/deps/couchbase-cxx-client/core/crud_component.cxx +51 -22
  10. package/deps/couchbase-cxx-client/core/impl/build_deferred_query_indexes.cxx +115 -50
  11. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +6 -0
  12. package/deps/couchbase-cxx-client/core/impl/create_bucket.cxx +155 -0
  13. package/deps/couchbase-cxx-client/core/impl/create_query_index.cxx +172 -59
  14. package/deps/couchbase-cxx-client/core/impl/dns_srv_tracker.cxx +2 -1
  15. package/deps/couchbase-cxx-client/core/impl/drop_bucket.cxx +66 -0
  16. package/deps/couchbase-cxx-client/core/impl/drop_query_index.cxx +138 -59
  17. package/deps/couchbase-cxx-client/core/impl/flush_bucket.cxx +66 -0
  18. package/deps/couchbase-cxx-client/core/impl/get_all_buckets.cxx +163 -0
  19. package/deps/couchbase-cxx-client/core/impl/get_all_query_indexes.cxx +67 -37
  20. package/deps/couchbase-cxx-client/core/impl/get_bucket.cxx +153 -0
  21. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.cxx +113 -0
  22. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.hxx +60 -0
  23. package/deps/couchbase-cxx-client/core/impl/key_value_error_category.cxx +2 -4
  24. package/deps/couchbase-cxx-client/core/impl/manager_error_context.cxx +100 -0
  25. package/deps/couchbase-cxx-client/core/impl/query.cxx +1 -0
  26. package/deps/couchbase-cxx-client/core/impl/update_bucket.cxx +130 -0
  27. package/deps/couchbase-cxx-client/core/impl/watch_query_indexes.cxx +53 -29
  28. package/deps/couchbase-cxx-client/core/io/dns_client.cxx +71 -38
  29. package/deps/couchbase-cxx-client/core/io/dns_config.cxx +5 -4
  30. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +5 -6
  31. package/deps/couchbase-cxx-client/core/meta/features.hxx +6 -0
  32. package/deps/couchbase-cxx-client/core/operations/document_query.cxx +11 -0
  33. package/deps/couchbase-cxx-client/core/operations/document_query.hxx +1 -0
  34. package/deps/couchbase-cxx-client/core/origin.cxx +270 -0
  35. package/deps/couchbase-cxx-client/core/origin.hxx +2 -0
  36. package/deps/couchbase-cxx-client/core/protocol/status.cxx +2 -2
  37. package/deps/couchbase-cxx-client/core/range_scan_options.cxx +3 -27
  38. package/deps/couchbase-cxx-client/core/range_scan_options.hxx +13 -17
  39. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +367 -170
  40. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +13 -2
  41. package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +5 -3
  42. package/deps/couchbase-cxx-client/core/scan_options.hxx +0 -19
  43. package/deps/couchbase-cxx-client/core/scan_result.cxx +19 -5
  44. package/deps/couchbase-cxx-client/core/scan_result.hxx +5 -2
  45. package/deps/couchbase-cxx-client/core/timeout_defaults.hxx +2 -3
  46. package/deps/couchbase-cxx-client/core/topology/capabilities.hxx +1 -0
  47. package/deps/couchbase-cxx-client/core/topology/capabilities_fmt.hxx +2 -0
  48. package/deps/couchbase-cxx-client/core/topology/collections_manifest_fmt.hxx +1 -1
  49. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +5 -0
  50. package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +2 -0
  51. package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +4 -0
  52. package/deps/couchbase-cxx-client/couchbase/behavior_options.hxx +19 -2
  53. package/deps/couchbase-cxx-client/couchbase/bucket_manager.hxx +135 -0
  54. package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +0 -30
  55. package/deps/couchbase-cxx-client/couchbase/cluster.hxx +14 -0
  56. package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +7 -48
  57. package/deps/couchbase-cxx-client/couchbase/create_bucket_options.hxx +41 -0
  58. package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +0 -29
  59. package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +0 -33
  60. package/deps/couchbase-cxx-client/couchbase/drop_bucket_options.hxx +41 -0
  61. package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +0 -30
  62. package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +0 -31
  63. package/deps/couchbase-cxx-client/couchbase/error_codes.hxx +1 -2
  64. package/deps/couchbase-cxx-client/couchbase/flush_bucket_options.hxx +41 -0
  65. package/deps/couchbase-cxx-client/couchbase/get_all_buckets_options.hxx +44 -0
  66. package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +0 -30
  67. package/deps/couchbase-cxx-client/couchbase/get_bucket_options.hxx +43 -0
  68. package/deps/couchbase-cxx-client/couchbase/management/bucket_settings.hxx +116 -0
  69. package/deps/couchbase-cxx-client/couchbase/manager_error_context.hxx +29 -53
  70. package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +16 -83
  71. package/deps/couchbase-cxx-client/couchbase/query_options.hxx +18 -0
  72. package/deps/couchbase-cxx-client/couchbase/security_options.hxx +15 -0
  73. package/deps/couchbase-cxx-client/couchbase/update_bucket_options.hxx +41 -0
  74. package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +0 -31
  75. package/deps/couchbase-cxx-client/docs/cbc-analytics.md +1 -0
  76. package/deps/couchbase-cxx-client/docs/cbc-get.md +1 -0
  77. package/deps/couchbase-cxx-client/docs/cbc-pillowfight.md +1 -0
  78. package/deps/couchbase-cxx-client/docs/cbc-query.md +1 -0
  79. package/deps/couchbase-cxx-client/docs/cbc.md +10 -0
  80. package/deps/couchbase-cxx-client/test/CMakeLists.txt +1 -0
  81. package/deps/couchbase-cxx-client/test/test_integration_collections.cxx +6 -0
  82. package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +5 -0
  83. package/deps/couchbase-cxx-client/test/test_integration_examples.cxx +137 -1
  84. package/deps/couchbase-cxx-client/test/test_integration_management.cxx +709 -266
  85. package/deps/couchbase-cxx-client/test/test_integration_query.cxx +19 -7
  86. package/deps/couchbase-cxx-client/test/test_integration_range_scan.cxx +351 -112
  87. package/deps/couchbase-cxx-client/test/test_integration_search.cxx +10 -1
  88. package/deps/couchbase-cxx-client/test/test_transaction_public_async_api.cxx +13 -12
  89. package/deps/couchbase-cxx-client/test/test_transaction_public_blocking_api.cxx +27 -21
  90. package/deps/couchbase-cxx-client/test/test_unit_query.cxx +75 -0
  91. package/deps/couchbase-cxx-client/test/utils/server_version.hxx +5 -0
  92. package/deps/couchbase-cxx-client/test/utils/wait_until.cxx +29 -10
  93. package/deps/couchbase-cxx-client/test/utils/wait_until.hxx +3 -1
  94. package/deps/couchbase-cxx-client/tools/utils.cxx +4 -1
  95. package/dist/binding.d.ts +21 -16
  96. package/dist/binding.js +1 -4
  97. package/dist/bindingutilities.d.ts +6 -1
  98. package/dist/bindingutilities.js +36 -1
  99. package/dist/collection.d.ts +65 -3
  100. package/dist/collection.js +107 -0
  101. package/dist/crudoptypes.d.ts +34 -0
  102. package/dist/crudoptypes.js +18 -1
  103. package/dist/queryexecutor.js +1 -0
  104. package/dist/querytypes.d.ts +7 -0
  105. package/dist/rangeScan.d.ts +107 -0
  106. package/dist/rangeScan.js +91 -0
  107. package/dist/streamablepromises.d.ts +6 -0
  108. package/dist/streamablepromises.js +25 -1
  109. package/package.json +13 -14
  110. package/scripts/createPlatformPackages.js +1 -4
  111. package/src/addondata.hpp +1 -0
  112. package/src/binding.cpp +5 -2
  113. package/src/connection.cpp +108 -2
  114. package/src/connection.hpp +1 -0
  115. package/src/constants.cpp +2 -12
  116. package/src/jstocbpp_autogen.hpp +49 -22
  117. package/src/jstocbpp_basic.hpp +2 -8
  118. package/src/mutationtoken.cpp +13 -0
  119. package/src/scan_iterator.cpp +90 -0
  120. package/src/scan_iterator.hpp +30 -0
  121. package/tools/gen-bindings-json.py +9 -8
  122. package/deps/couchbase-cxx-client/core/impl/collection_query_index_manager.cxx +0 -93
@@ -74,244 +74,358 @@ TEST_CASE("integration: bucket management", "[integration]")
74
74
 
75
75
  SECTION("crud")
76
76
  {
77
- couchbase::core::management::cluster::bucket_settings bucket_settings;
78
- bucket_settings.name = bucket_name;
79
- bucket_settings.ram_quota_mb = 100;
80
- bucket_settings.num_replicas = 1;
81
- bucket_settings.bucket_type = couchbase::core::management::cluster::bucket_type::couchbase;
82
- bucket_settings.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::value_only;
83
- bucket_settings.flush_enabled = true;
84
- if (integration.cluster_version().is_enterprise()) {
85
- bucket_settings.max_expiry = 10;
86
- bucket_settings.compression_mode = couchbase::core::management::cluster::bucket_compression::active;
87
- }
88
- bucket_settings.replica_indexes = true;
89
- bucket_settings.conflict_resolution_type = couchbase::core::management::cluster::bucket_conflict_resolution::sequence_number;
90
-
91
- {
92
- couchbase::core::operations::management::bucket_create_request req;
93
- req.bucket = bucket_settings;
94
- auto resp = test::utils::execute(integration.cluster, req);
95
- REQUIRE_SUCCESS(resp.ctx.ec);
96
- }
97
-
98
- {
99
- auto resp = wait_for_bucket_created(integration, bucket_name);
100
- REQUIRE_SUCCESS(resp.ctx.ec);
101
- REQUIRE(bucket_settings.bucket_type == resp.bucket.bucket_type);
102
- REQUIRE(bucket_settings.name == resp.bucket.name);
103
- REQUIRE(Approx(bucket_settings.ram_quota_mb).margin(5) == resp.bucket.ram_quota_mb);
104
- REQUIRE(bucket_settings.num_replicas == resp.bucket.num_replicas);
105
- REQUIRE(bucket_settings.flush_enabled == resp.bucket.flush_enabled);
106
- REQUIRE(bucket_settings.max_expiry == resp.bucket.max_expiry);
107
- REQUIRE(bucket_settings.eviction_policy == resp.bucket.eviction_policy);
108
- REQUIRE(bucket_settings.compression_mode == resp.bucket.compression_mode);
109
- REQUIRE(bucket_settings.replica_indexes == resp.bucket.replica_indexes);
110
- }
111
- std::uint64_t old_quota_mb{ 0 };
112
- {
113
- couchbase::core::operations::management::bucket_get_all_request req{};
114
- auto resp = test::utils::execute(integration.cluster, req);
115
- INFO(resp.ctx.http_body);
116
- REQUIRE_SUCCESS(resp.ctx.ec);
117
- bool found = false;
118
- for (const auto& bucket : resp.buckets) {
119
- if (bucket.name != bucket_name) {
120
- continue;
121
- }
122
- found = true;
123
- REQUIRE(bucket_settings.bucket_type == bucket.bucket_type);
124
- REQUIRE(bucket_settings.name == bucket.name);
125
- REQUIRE(bucket_settings.ram_quota_mb == bucket.ram_quota_mb);
126
- old_quota_mb = bucket_settings.ram_quota_mb;
127
- REQUIRE(bucket_settings.num_replicas == bucket.num_replicas);
128
- REQUIRE(bucket_settings.flush_enabled == bucket.flush_enabled);
129
- REQUIRE(bucket_settings.max_expiry == bucket.max_expiry);
130
- REQUIRE(bucket_settings.eviction_policy == bucket.eviction_policy);
131
- REQUIRE(bucket_settings.compression_mode == bucket.compression_mode);
132
- REQUIRE(bucket_settings.replica_indexes == bucket.replica_indexes);
133
- break;
134
- }
135
- REQUIRE(found);
136
- }
137
-
138
- {
139
- bucket_settings.ram_quota_mb = old_quota_mb + 20;
140
- couchbase::core::operations::management::bucket_update_request req;
141
- req.bucket = bucket_settings;
142
- auto resp = test::utils::execute(integration.cluster, req);
143
- REQUIRE_SUCCESS(resp.ctx.ec);
144
- }
145
-
146
- auto ram_quota_updated = test::utils::wait_until([&integration, &bucket_name, old_quota_mb]() {
147
- couchbase::core::operations::management::bucket_get_request req{ bucket_name };
148
- auto resp = test::utils::execute(integration.cluster, req);
149
- return !resp.ctx.ec && resp.bucket.ram_quota_mb > old_quota_mb;
150
- });
151
- REQUIRE(ram_quota_updated);
152
-
153
- {
154
- couchbase::core::operations::management::bucket_drop_request req{ bucket_name };
155
- auto resp = test::utils::execute(integration.cluster, req);
156
- REQUIRE_SUCCESS(resp.ctx.ec);
157
- }
158
-
159
- {
160
- couchbase::core::operations::management::bucket_get_request req{ bucket_name };
161
- auto resp = retry_on_error(integration, req, {});
162
- REQUIRE(resp.ctx.ec == couchbase::errc::common::bucket_not_found);
163
- }
164
-
165
- {
166
- couchbase::core::operations::management::bucket_get_all_request req;
167
- auto resp = test::utils::execute(integration.cluster, req);
168
- REQUIRE_SUCCESS(resp.ctx.ec);
169
- REQUIRE(!resp.buckets.empty());
170
- auto known_buckets =
171
- std::count_if(resp.buckets.begin(), resp.buckets.end(), [&bucket_name](auto& entry) { return entry.name == bucket_name; });
172
- REQUIRE(known_buckets == 0);
173
- }
174
- }
175
-
176
- SECTION("flush")
177
- {
178
- SECTION("flush item")
77
+ SECTION("core API")
179
78
  {
180
- couchbase::core::document_id id{ bucket_name, "_default", "_default", test::utils::uniq_id("foo") };
181
-
79
+ couchbase::core::management::cluster::bucket_settings bucket_settings;
80
+ bucket_settings.name = bucket_name;
81
+ bucket_settings.ram_quota_mb = 100;
82
+ bucket_settings.num_replicas = 1;
83
+ bucket_settings.bucket_type = couchbase::core::management::cluster::bucket_type::couchbase;
84
+ bucket_settings.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::value_only;
85
+ bucket_settings.flush_enabled = true;
86
+ if (integration.cluster_version().is_enterprise()) {
87
+ bucket_settings.max_expiry = 10;
88
+ bucket_settings.compression_mode = couchbase::core::management::cluster::bucket_compression::active;
89
+ }
90
+ bucket_settings.replica_indexes = true;
91
+ bucket_settings.conflict_resolution_type = couchbase::core::management::cluster::bucket_conflict_resolution::sequence_number;
182
92
  {
183
93
  couchbase::core::operations::management::bucket_create_request req;
184
- req.bucket.name = bucket_name;
185
- req.bucket.flush_enabled = true;
94
+ req.bucket = bucket_settings;
186
95
  auto resp = test::utils::execute(integration.cluster, req);
187
96
  REQUIRE_SUCCESS(resp.ctx.ec);
188
97
  }
189
98
 
190
- REQUIRE(test::utils::wait_until_bucket_healthy(integration.cluster, bucket_name));
191
-
192
- test::utils::open_bucket(integration.cluster, bucket_name);
193
-
194
- {
195
- const tao::json::value value = {
196
- { "a", 1.0 },
197
- };
198
- couchbase::core::operations::insert_request req{ id, couchbase::core::utils::json::generate_binary(value) };
199
- auto resp = test::utils::execute(integration.cluster, req);
200
- REQUIRE_SUCCESS(resp.ctx.ec());
201
- }
202
-
203
99
  {
204
- couchbase::core::operations::get_request req{ id };
100
+ auto resp = wait_for_bucket_created(integration, bucket_name);
101
+ REQUIRE_SUCCESS(resp.ctx.ec);
102
+ REQUIRE(bucket_settings.bucket_type == resp.bucket.bucket_type);
103
+ REQUIRE(bucket_settings.name == resp.bucket.name);
104
+ REQUIRE(Approx(bucket_settings.ram_quota_mb).margin(5) == resp.bucket.ram_quota_mb);
105
+ REQUIRE(bucket_settings.num_replicas == resp.bucket.num_replicas);
106
+ REQUIRE(bucket_settings.flush_enabled == resp.bucket.flush_enabled);
107
+ REQUIRE(bucket_settings.max_expiry == resp.bucket.max_expiry);
108
+ REQUIRE(bucket_settings.eviction_policy == resp.bucket.eviction_policy);
109
+ REQUIRE(bucket_settings.compression_mode == resp.bucket.compression_mode);
110
+ REQUIRE(bucket_settings.replica_indexes == resp.bucket.replica_indexes);
111
+ }
112
+ std::uint64_t old_quota_mb{ 0 };
113
+ {
114
+ couchbase::core::operations::management::bucket_get_all_request req{};
205
115
  auto resp = test::utils::execute(integration.cluster, req);
206
- REQUIRE_SUCCESS(resp.ctx.ec());
116
+ INFO(resp.ctx.http_body);
117
+ REQUIRE_SUCCESS(resp.ctx.ec);
118
+ bool found = false;
119
+ for (const auto& bucket : resp.buckets) {
120
+ if (bucket.name != bucket_name) {
121
+ continue;
122
+ }
123
+ found = true;
124
+ REQUIRE(bucket_settings.bucket_type == bucket.bucket_type);
125
+ REQUIRE(bucket_settings.name == bucket.name);
126
+ REQUIRE(bucket_settings.ram_quota_mb == bucket.ram_quota_mb);
127
+ old_quota_mb = bucket_settings.ram_quota_mb;
128
+ REQUIRE(bucket_settings.num_replicas == bucket.num_replicas);
129
+ REQUIRE(bucket_settings.flush_enabled == bucket.flush_enabled);
130
+ REQUIRE(bucket_settings.max_expiry == bucket.max_expiry);
131
+ REQUIRE(bucket_settings.eviction_policy == bucket.eviction_policy);
132
+ REQUIRE(bucket_settings.compression_mode == bucket.compression_mode);
133
+ REQUIRE(bucket_settings.replica_indexes == bucket.replica_indexes);
134
+ break;
135
+ }
136
+ REQUIRE(found);
207
137
  }
208
138
 
209
139
  {
210
- couchbase::core::operations::management::bucket_flush_request req{ bucket_name };
140
+ bucket_settings.ram_quota_mb = old_quota_mb + 20;
141
+ couchbase::core::operations::management::bucket_update_request req;
142
+ req.bucket = bucket_settings;
211
143
  auto resp = test::utils::execute(integration.cluster, req);
212
144
  REQUIRE_SUCCESS(resp.ctx.ec);
213
145
  }
214
146
 
215
- auto flushed = test::utils::wait_until([&integration, id]() {
216
- couchbase::core::operations::get_request req{ id };
147
+ auto ram_quota_updated = test::utils::wait_until([&integration, &bucket_name, old_quota_mb]() {
148
+ couchbase::core::operations::management::bucket_get_request req{ bucket_name };
217
149
  auto resp = test::utils::execute(integration.cluster, req);
218
- return resp.ctx.ec() == couchbase::errc::key_value::document_not_found;
150
+ return !resp.ctx.ec && resp.bucket.ram_quota_mb > old_quota_mb;
219
151
  });
220
- REQUIRE(flushed);
221
- }
222
-
223
- SECTION("no bucket")
224
- {
225
- couchbase::core::operations::management::bucket_flush_request req{ bucket_name };
226
- auto resp = test::utils::execute(integration.cluster, req);
227
- REQUIRE(resp.ctx.ec == couchbase::errc::common::bucket_not_found);
228
- }
152
+ REQUIRE(ram_quota_updated);
229
153
 
230
- SECTION("flush disabled")
231
- {
232
154
  {
233
- couchbase::core::operations::management::bucket_create_request req;
234
- req.bucket.name = bucket_name;
235
- req.bucket.flush_enabled = false;
155
+ couchbase::core::operations::management::bucket_drop_request req{ bucket_name };
236
156
  auto resp = test::utils::execute(integration.cluster, req);
237
157
  REQUIRE_SUCCESS(resp.ctx.ec);
238
158
  }
239
159
 
240
- REQUIRE(test::utils::wait_until_bucket_healthy(integration.cluster, bucket_name));
160
+ {
161
+ couchbase::core::operations::management::bucket_get_request req{ bucket_name };
162
+ auto resp = retry_on_error(integration, req, {});
163
+ REQUIRE(resp.ctx.ec == couchbase::errc::common::bucket_not_found);
164
+ }
241
165
 
242
166
  {
243
- couchbase::core::operations::management::bucket_flush_request req{ bucket_name };
167
+ couchbase::core::operations::management::bucket_get_all_request req;
244
168
  auto resp = test::utils::execute(integration.cluster, req);
245
- REQUIRE(resp.ctx.ec == couchbase::errc::management::bucket_not_flushable);
169
+ REQUIRE_SUCCESS(resp.ctx.ec);
170
+ REQUIRE(!resp.buckets.empty());
171
+ auto known_buckets = std::count_if(
172
+ resp.buckets.begin(), resp.buckets.end(), [&bucket_name](auto& entry) { return entry.name == bucket_name; });
173
+ REQUIRE(known_buckets == 0);
246
174
  }
247
175
  }
248
- }
249
-
250
- if (integration.cluster_version().supports_memcached_buckets()) {
251
- SECTION("memcached")
176
+ SECTION("public API")
252
177
  {
178
+ couchbase::cluster c(integration.cluster);
179
+ couchbase::management::cluster::bucket_settings bucket_settings;
180
+ bucket_settings.name = bucket_name;
181
+ bucket_settings.ram_quota_mb = 100;
182
+ bucket_settings.num_replicas = 1;
183
+ bucket_settings.bucket_type = couchbase::management::cluster::bucket_type::couchbase;
184
+ bucket_settings.eviction_policy = couchbase::management::cluster::bucket_eviction_policy::value_only;
185
+ bucket_settings.flush_enabled = true;
186
+ if (integration.cluster_version().is_enterprise()) {
187
+ bucket_settings.max_expiry = 10;
188
+ bucket_settings.compression_mode = couchbase::management::cluster::bucket_compression::active;
189
+ }
190
+ bucket_settings.replica_indexes = true;
191
+ bucket_settings.conflict_resolution_type = couchbase::management::cluster::bucket_conflict_resolution::sequence_number;
192
+ {
193
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
194
+ REQUIRE_SUCCESS(ctx.ec());
195
+ }
253
196
  {
254
- couchbase::core::management::cluster::bucket_settings bucket_settings;
255
- bucket_settings.name = bucket_name;
256
- bucket_settings.bucket_type = couchbase::core::management::cluster::bucket_type::memcached;
257
- bucket_settings.num_replicas = 0;
258
- couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
259
- auto resp = test::utils::execute(integration.cluster, req);
260
- REQUIRE_SUCCESS(resp.ctx.ec);
197
+ auto bucket_exists = test::utils::wait_until([&bucket_name, &c]() {
198
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
199
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
200
+ });
201
+ REQUIRE(bucket_exists);
202
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
203
+ REQUIRE_SUCCESS(ctx.ec());
204
+ REQUIRE(bucket_settings.bucket_type == bucket.bucket_type);
205
+ REQUIRE(bucket_settings.name == bucket.name);
206
+ REQUIRE(Approx(bucket_settings.ram_quota_mb).margin(5) == bucket.ram_quota_mb);
207
+ REQUIRE(bucket_settings.num_replicas == bucket.num_replicas);
208
+ REQUIRE(bucket_settings.flush_enabled == bucket.flush_enabled);
209
+ REQUIRE(bucket_settings.max_expiry == bucket.max_expiry);
210
+ REQUIRE(bucket_settings.eviction_policy == bucket.eviction_policy);
211
+ REQUIRE(bucket_settings.compression_mode == bucket.compression_mode);
212
+ REQUIRE(bucket_settings.replica_indexes == bucket.replica_indexes);
213
+ }
214
+ std::uint64_t old_quota_mb{ 0 };
215
+ {
216
+ auto [ctx, buckets] = c.buckets().get_all_buckets({}).get();
217
+ INFO(ctx.content());
218
+ REQUIRE_SUCCESS(ctx.ec());
219
+ bool found = false;
220
+ for (const auto& bucket : buckets) {
221
+ if (bucket.name != bucket_name) {
222
+ continue;
223
+ }
224
+ found = true;
225
+ REQUIRE(bucket_settings.bucket_type == bucket.bucket_type);
226
+ REQUIRE(bucket_settings.name == bucket.name);
227
+ REQUIRE(bucket_settings.ram_quota_mb == bucket.ram_quota_mb);
228
+ old_quota_mb = bucket_settings.ram_quota_mb;
229
+ REQUIRE(bucket_settings.num_replicas == bucket.num_replicas);
230
+ REQUIRE(bucket_settings.flush_enabled == bucket.flush_enabled);
231
+ REQUIRE(bucket_settings.max_expiry == bucket.max_expiry);
232
+ REQUIRE(bucket_settings.eviction_policy == bucket.eviction_policy);
233
+ REQUIRE(bucket_settings.compression_mode == bucket.compression_mode);
234
+ REQUIRE(bucket_settings.replica_indexes == bucket.replica_indexes);
235
+ break;
236
+ }
237
+ REQUIRE(found);
261
238
  }
262
239
 
263
240
  {
264
- auto resp = wait_for_bucket_created(integration, bucket_name);
265
- REQUIRE_SUCCESS(resp.ctx.ec);
266
- REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::memcached);
241
+ bucket_settings.ram_quota_mb = old_quota_mb + 20;
242
+ auto ctx = c.buckets().update_bucket(bucket_settings, {}).get();
243
+ REQUIRE_SUCCESS(ctx.ec());
244
+ }
245
+ auto ram_quota_updated = test::utils::wait_until([&bucket_name, c, old_quota_mb]() {
246
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
247
+ return !ctx.ec() && bucket.ram_quota_mb > old_quota_mb;
248
+ });
249
+ REQUIRE(ram_quota_updated);
250
+ {
251
+ auto ctx = c.buckets().drop_bucket(bucket_name, {}).get();
252
+ REQUIRE_SUCCESS(ctx.ec());
253
+ }
254
+ {
255
+ auto bucket_not_found = test::utils::wait_until([&bucket_name, c]() {
256
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
257
+ return ctx.ec() == couchbase::errc::common::bucket_not_found;
258
+ });
259
+ REQUIRE(bucket_not_found);
260
+ }
261
+ {
262
+ auto [ctx, buckets] = c.buckets().get_all_buckets({}).get();
263
+ REQUIRE_SUCCESS(ctx.ec());
264
+ REQUIRE(!buckets.empty());
265
+ auto known_buckets =
266
+ std::count_if(buckets.begin(), buckets.end(), [&bucket_name](auto& entry) { return entry.name == bucket_name; });
267
+ REQUIRE(known_buckets == 0);
267
268
  }
268
269
  }
269
270
  }
270
271
 
271
- SECTION("ephemeral")
272
+ SECTION("flush")
272
273
  {
273
- couchbase::core::management::cluster::bucket_settings bucket_settings;
274
- bucket_settings.name = bucket_name;
275
- bucket_settings.bucket_type = couchbase::core::management::cluster::bucket_type::ephemeral;
276
-
277
- SECTION("default eviction")
274
+ SECTION("core api")
278
275
  {
276
+ SECTION("flush item")
277
+ {
278
+ couchbase::core::document_id id{ bucket_name, "_default", "_default", test::utils::uniq_id("foo") };
279
+
280
+ {
281
+ couchbase::core::operations::management::bucket_create_request req;
282
+ req.bucket.name = bucket_name;
283
+ req.bucket.flush_enabled = true;
284
+ auto resp = test::utils::execute(integration.cluster, req);
285
+ REQUIRE_SUCCESS(resp.ctx.ec);
286
+ }
287
+
288
+ REQUIRE(test::utils::wait_until_bucket_healthy(integration.cluster, bucket_name));
289
+
290
+ test::utils::open_bucket(integration.cluster, bucket_name);
291
+
292
+ {
293
+ const tao::json::value value = {
294
+ { "a", 1.0 },
295
+ };
296
+ couchbase::core::operations::insert_request req{ id, couchbase::core::utils::json::generate_binary(value) };
297
+ auto resp = test::utils::execute(integration.cluster, req);
298
+ REQUIRE_SUCCESS(resp.ctx.ec());
299
+ }
300
+
301
+ {
302
+ couchbase::core::operations::get_request req{ id };
303
+ auto resp = test::utils::execute(integration.cluster, req);
304
+ REQUIRE_SUCCESS(resp.ctx.ec());
305
+ }
306
+
307
+ {
308
+ couchbase::core::operations::management::bucket_flush_request req{ bucket_name };
309
+ auto resp = test::utils::execute(integration.cluster, req);
310
+ REQUIRE_SUCCESS(resp.ctx.ec);
311
+ }
312
+
313
+ auto flushed = test::utils::wait_until([&integration, id]() {
314
+ couchbase::core::operations::get_request req{ id };
315
+ auto resp = test::utils::execute(integration.cluster, req);
316
+ return resp.ctx.ec() == couchbase::errc::key_value::document_not_found;
317
+ });
318
+ REQUIRE(flushed);
319
+ }
320
+ SECTION("no bucket")
279
321
  {
280
- couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
322
+ couchbase::core::operations::management::bucket_flush_request req{ bucket_name };
281
323
  auto resp = test::utils::execute(integration.cluster, req);
282
- REQUIRE_SUCCESS(resp.ctx.ec);
324
+ REQUIRE(resp.ctx.ec == couchbase::errc::common::bucket_not_found);
283
325
  }
284
326
 
327
+ SECTION("flush disabled")
285
328
  {
286
- auto resp = wait_for_bucket_created(integration, bucket_name);
287
- REQUIRE_SUCCESS(resp.ctx.ec);
288
- REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::ephemeral);
289
- REQUIRE(resp.bucket.eviction_policy == couchbase::core::management::cluster::bucket_eviction_policy::no_eviction);
329
+ {
330
+ couchbase::core::operations::management::bucket_create_request req;
331
+ req.bucket.name = bucket_name;
332
+ req.bucket.flush_enabled = false;
333
+ auto resp = test::utils::execute(integration.cluster, req);
334
+ REQUIRE_SUCCESS(resp.ctx.ec);
335
+ }
336
+
337
+ REQUIRE(test::utils::wait_until_bucket_healthy(integration.cluster, bucket_name));
338
+
339
+ {
340
+ couchbase::core::operations::management::bucket_flush_request req{ bucket_name };
341
+ auto resp = test::utils::execute(integration.cluster, req);
342
+ REQUIRE(resp.ctx.ec == couchbase::errc::management::bucket_not_flushable);
343
+ }
290
344
  }
291
345
  }
292
-
293
- SECTION("nru eviction")
346
+ SECTION("public API")
294
347
  {
348
+ couchbase::cluster c(integration.cluster);
349
+ SECTION("flush item")
295
350
  {
296
- bucket_settings.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used;
297
- couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
298
- auto resp = test::utils::execute(integration.cluster, req);
299
- REQUIRE_SUCCESS(resp.ctx.ec);
351
+ auto id = test::utils::uniq_id("foo");
352
+
353
+ {
354
+ couchbase::management::cluster::bucket_settings bucket_settings;
355
+ bucket_settings.name = bucket_name;
356
+ bucket_settings.flush_enabled = true;
357
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
358
+ REQUIRE_SUCCESS(ctx.ec());
359
+ }
360
+
361
+ REQUIRE(test::utils::wait_until_bucket_healthy(integration.cluster, bucket_name));
362
+
363
+ test::utils::open_bucket(integration.cluster, bucket_name);
364
+
365
+ auto default_coll = c.bucket(bucket_name).default_collection();
366
+ {
367
+ const tao::json::value value = {
368
+ { "a", 1.0 },
369
+ };
370
+
371
+ auto [ctx, resp] = default_coll.insert(id, value, {}).get();
372
+ REQUIRE_SUCCESS(ctx.ec());
373
+ }
374
+ {
375
+ auto [ctx, resp] = default_coll.get(id, {}).get();
376
+ REQUIRE_SUCCESS(ctx.ec());
377
+ }
378
+ {
379
+ auto ctx = c.buckets().flush_bucket(bucket_name, {}).get();
380
+ REQUIRE_SUCCESS(ctx.ec());
381
+ }
382
+ auto flushed = test::utils::wait_until([id, default_coll]() {
383
+ auto [ctx, resp] = default_coll.get(id, {}).get();
384
+ return ctx.ec() == couchbase::errc::key_value::document_not_found;
385
+ });
386
+ REQUIRE(flushed);
300
387
  }
301
388
 
389
+ SECTION("no bucket")
302
390
  {
303
- auto resp = wait_for_bucket_created(integration, bucket_name);
304
- REQUIRE_SUCCESS(resp.ctx.ec);
305
- REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::ephemeral);
306
- REQUIRE(resp.bucket.eviction_policy == couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used);
391
+ auto ctx = c.buckets().flush_bucket(bucket_name, {}).get();
392
+ REQUIRE(ctx.ec() == couchbase::errc::common::bucket_not_found);
393
+ }
394
+
395
+ SECTION("flush disabled")
396
+ {
397
+ {
398
+ couchbase::management::cluster::bucket_settings bucket_settings;
399
+ bucket_settings.name = bucket_name;
400
+ bucket_settings.flush_enabled = false;
401
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
402
+ REQUIRE_SUCCESS(ctx.ec());
403
+ }
404
+
405
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
406
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
407
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
408
+ });
409
+ REQUIRE(bucket_exists);
410
+
411
+ {
412
+ auto ctx = c.buckets().flush_bucket(bucket_name, {}).get();
413
+ REQUIRE(ctx.ec() == couchbase::errc::management::bucket_not_flushable);
414
+ }
307
415
  }
308
416
  }
417
+ }
309
418
 
310
- if (integration.cluster_version().supports_storage_backend()) {
311
- SECTION("storage backend")
419
+ if (integration.cluster_version().supports_memcached_buckets()) {
420
+ SECTION("memcached")
421
+ {
422
+ SECTION("core api")
312
423
  {
313
424
  {
314
- bucket_settings.storage_backend = couchbase::core::management::cluster::bucket_storage_backend::couchstore;
425
+ couchbase::core::management::cluster::bucket_settings bucket_settings;
426
+ bucket_settings.name = bucket_name;
427
+ bucket_settings.bucket_type = couchbase::core::management::cluster::bucket_type::memcached;
428
+ bucket_settings.num_replicas = 0;
315
429
  couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
316
430
  auto resp = test::utils::execute(integration.cluster, req);
317
431
  REQUIRE_SUCCESS(resp.ctx.ec);
@@ -320,57 +434,78 @@ TEST_CASE("integration: bucket management", "[integration]")
320
434
  {
321
435
  auto resp = wait_for_bucket_created(integration, bucket_name);
322
436
  REQUIRE_SUCCESS(resp.ctx.ec);
323
- REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::ephemeral);
324
- REQUIRE(resp.bucket.storage_backend == couchbase::core::management::cluster::bucket_storage_backend::unknown);
437
+ REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::memcached);
438
+ }
439
+ }
440
+ SECTION("public api")
441
+ {
442
+ couchbase::cluster c(integration.cluster);
443
+ {
444
+ couchbase::management::cluster::bucket_settings bucket_settings;
445
+ bucket_settings.name = bucket_name;
446
+ bucket_settings.bucket_type = couchbase::management::cluster::bucket_type::memcached;
447
+ bucket_settings.num_replicas = 0;
448
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
449
+ REQUIRE_SUCCESS(ctx.ec());
450
+ }
451
+
452
+ {
453
+ auto bucket_exists = test::utils::wait_until([&bucket_name, &c]() {
454
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
455
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
456
+ });
457
+ REQUIRE(bucket_exists);
458
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
459
+ REQUIRE_SUCCESS(ctx.ec());
460
+ REQUIRE(bucket.bucket_type == couchbase::management::cluster::bucket_type::memcached);
325
461
  }
326
462
  }
327
463
  }
328
464
  }
329
465
 
330
- SECTION("couchbase")
466
+ SECTION("ephemeral")
331
467
  {
332
- couchbase::core::management::cluster::bucket_settings bucket_settings;
333
- bucket_settings.name = bucket_name;
334
- bucket_settings.bucket_type = couchbase::core::management::cluster::bucket_type::couchbase;
335
-
336
- SECTION("default eviction")
468
+ SECTION("core api")
337
469
  {
338
- {
339
-
340
- couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
341
- auto resp = test::utils::execute(integration.cluster, req);
342
- REQUIRE_SUCCESS(resp.ctx.ec);
343
- }
470
+ couchbase::core::management::cluster::bucket_settings bucket_settings;
471
+ bucket_settings.name = bucket_name;
472
+ bucket_settings.bucket_type = couchbase::core::management::cluster::bucket_type::ephemeral;
344
473
 
474
+ SECTION("default eviction")
345
475
  {
346
- auto resp = wait_for_bucket_created(integration, bucket_name);
347
- REQUIRE_SUCCESS(resp.ctx.ec);
348
- REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::couchbase);
349
- REQUIRE(resp.bucket.eviction_policy == couchbase::core::management::cluster::bucket_eviction_policy::value_only);
350
- }
351
- }
476
+ {
477
+ couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
478
+ auto resp = test::utils::execute(integration.cluster, req);
479
+ REQUIRE_SUCCESS(resp.ctx.ec);
480
+ }
352
481
 
353
- SECTION("full eviction")
354
- {
355
- {
356
- bucket_settings.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::full;
357
- couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
358
- auto resp = test::utils::execute(integration.cluster, req);
359
- REQUIRE_SUCCESS(resp.ctx.ec);
482
+ {
483
+ auto resp = wait_for_bucket_created(integration, bucket_name);
484
+ REQUIRE_SUCCESS(resp.ctx.ec);
485
+ REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::ephemeral);
486
+ REQUIRE(resp.bucket.eviction_policy == couchbase::core::management::cluster::bucket_eviction_policy::no_eviction);
487
+ }
360
488
  }
361
489
 
490
+ SECTION("nru eviction")
362
491
  {
363
- auto resp = wait_for_bucket_created(integration, bucket_name);
364
- REQUIRE_SUCCESS(resp.ctx.ec);
365
- REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::couchbase);
366
- REQUIRE(resp.bucket.eviction_policy == couchbase::core::management::cluster::bucket_eviction_policy::full);
492
+ {
493
+ bucket_settings.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used;
494
+ couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
495
+ auto resp = test::utils::execute(integration.cluster, req);
496
+ REQUIRE_SUCCESS(resp.ctx.ec);
497
+ }
498
+
499
+ {
500
+ auto resp = wait_for_bucket_created(integration, bucket_name);
501
+ REQUIRE_SUCCESS(resp.ctx.ec);
502
+ REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::ephemeral);
503
+ REQUIRE(resp.bucket.eviction_policy == couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used);
504
+ }
367
505
  }
368
- }
369
506
 
370
- if (integration.cluster_version().supports_storage_backend()) {
371
- SECTION("storage backend")
372
- {
373
- SECTION("couchstore")
507
+ if (integration.cluster_version().supports_storage_backend()) {
508
+ SECTION("storage backend")
374
509
  {
375
510
  {
376
511
  bucket_settings.storage_backend = couchbase::core::management::cluster::bucket_storage_backend::couchstore;
@@ -382,52 +517,112 @@ TEST_CASE("integration: bucket management", "[integration]")
382
517
  {
383
518
  auto resp = wait_for_bucket_created(integration, bucket_name);
384
519
  REQUIRE_SUCCESS(resp.ctx.ec);
385
- REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::couchbase);
386
- REQUIRE(resp.bucket.storage_backend == couchbase::core::management::cluster::bucket_storage_backend::couchstore);
520
+ REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::ephemeral);
521
+ REQUIRE(resp.bucket.storage_backend == couchbase::core::management::cluster::bucket_storage_backend::unknown);
387
522
  }
388
523
  }
524
+ }
525
+ }
526
+ SECTION("public api")
527
+ {
528
+ couchbase::cluster c(integration.cluster);
529
+ couchbase::management::cluster::bucket_settings bucket_settings;
530
+ bucket_settings.name = bucket_name;
531
+ bucket_settings.bucket_type = couchbase::management::cluster::bucket_type::ephemeral;
532
+
533
+ SECTION("default eviction")
534
+ {
535
+ {
536
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
537
+ REQUIRE_SUCCESS(ctx.ec());
538
+ }
389
539
 
390
- SECTION("magma")
540
+ {
541
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
542
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
543
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
544
+ });
545
+ REQUIRE(bucket_exists);
546
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
547
+ REQUIRE_SUCCESS(ctx.ec());
548
+ REQUIRE(bucket.bucket_type == couchbase::management::cluster::bucket_type::ephemeral);
549
+ REQUIRE(bucket.eviction_policy == couchbase::management::cluster::bucket_eviction_policy::no_eviction);
550
+ }
551
+ }
552
+
553
+ SECTION("nru eviction")
554
+ {
555
+ {
556
+ bucket_settings.eviction_policy = couchbase::management::cluster::bucket_eviction_policy::not_recently_used;
557
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
558
+ REQUIRE_SUCCESS(ctx.ec());
559
+ }
560
+
561
+ {
562
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
563
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
564
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
565
+ });
566
+ REQUIRE(bucket_exists);
567
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
568
+ REQUIRE_SUCCESS(ctx.ec());
569
+ REQUIRE(bucket.bucket_type == couchbase::management::cluster::bucket_type::ephemeral);
570
+ REQUIRE(bucket.eviction_policy == couchbase::management::cluster::bucket_eviction_policy::not_recently_used);
571
+ }
572
+ }
573
+ if (integration.cluster_version().supports_storage_backend()) {
574
+ SECTION("storage backend")
391
575
  {
392
576
  {
393
- bucket_settings.ram_quota_mb = integration.cluster_version().is_neo() ? 1'024 : 256;
394
- bucket_settings.storage_backend = couchbase::core::management::cluster::bucket_storage_backend::magma;
395
- couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
396
- auto resp = test::utils::execute(integration.cluster, req);
397
- REQUIRE_SUCCESS(resp.ctx.ec);
577
+ bucket_settings.storage_backend = couchbase::management::cluster::bucket_storage_backend::couchstore;
578
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
579
+ REQUIRE_SUCCESS(ctx.ec());
398
580
  }
399
581
 
400
582
  {
401
- auto resp = wait_for_bucket_created(integration, bucket_name);
402
- REQUIRE_SUCCESS(resp.ctx.ec);
403
- REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::couchbase);
404
- REQUIRE(resp.bucket.storage_backend == couchbase::core::management::cluster::bucket_storage_backend::magma);
583
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
584
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
585
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
586
+ });
587
+ REQUIRE(bucket_exists);
588
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
589
+ REQUIRE_SUCCESS(ctx.ec());
590
+ REQUIRE(bucket.bucket_type == couchbase::management::cluster::bucket_type::ephemeral);
591
+ REQUIRE(bucket.storage_backend == couchbase::management::cluster::bucket_storage_backend::unknown);
405
592
  }
406
593
  }
407
594
  }
408
595
  }
409
596
  }
410
-
411
- SECTION("update no bucket")
597
+ SECTION("couchbase")
412
598
  {
413
-
414
- couchbase::core::management::cluster::bucket_settings bucket_settings;
415
- bucket_settings.name = bucket_name;
416
- couchbase::core::operations::management::bucket_update_request req;
417
- req.bucket = bucket_settings;
418
- auto resp = test::utils::execute(integration.cluster, req);
419
- REQUIRE(resp.ctx.ec == couchbase::errc::common::bucket_not_found);
420
- }
421
-
422
- if (integration.cluster_version().supports_minimum_durability_level()) {
423
- SECTION("minimum durability level")
599
+ SECTION("core api")
424
600
  {
425
601
  couchbase::core::management::cluster::bucket_settings bucket_settings;
426
602
  bucket_settings.name = bucket_name;
603
+ bucket_settings.bucket_type = couchbase::core::management::cluster::bucket_type::couchbase;
427
604
 
428
- SECTION("default")
605
+ SECTION("default eviction")
429
606
  {
430
607
  {
608
+
609
+ couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
610
+ auto resp = test::utils::execute(integration.cluster, req);
611
+ REQUIRE_SUCCESS(resp.ctx.ec);
612
+ }
613
+
614
+ {
615
+ auto resp = wait_for_bucket_created(integration, bucket_name);
616
+ REQUIRE_SUCCESS(resp.ctx.ec);
617
+ REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::couchbase);
618
+ REQUIRE(resp.bucket.eviction_policy == couchbase::core::management::cluster::bucket_eviction_policy::value_only);
619
+ }
620
+ }
621
+
622
+ SECTION("full eviction")
623
+ {
624
+ {
625
+ bucket_settings.eviction_policy = couchbase::core::management::cluster::bucket_eviction_policy::full;
431
626
  couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
432
627
  auto resp = test::utils::execute(integration.cluster, req);
433
628
  REQUIRE_SUCCESS(resp.ctx.ec);
@@ -436,15 +631,182 @@ TEST_CASE("integration: bucket management", "[integration]")
436
631
  {
437
632
  auto resp = wait_for_bucket_created(integration, bucket_name);
438
633
  REQUIRE_SUCCESS(resp.ctx.ec);
439
- REQUIRE(resp.bucket.minimum_durability_level == couchbase::durability_level::none);
634
+ REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::couchbase);
635
+ REQUIRE(resp.bucket.eviction_policy == couchbase::core::management::cluster::bucket_eviction_policy::full);
440
636
  }
441
637
  }
442
638
 
443
- if (integration.number_of_nodes() >= 2) {
444
- SECTION("majority")
639
+ if (integration.cluster_version().supports_storage_backend()) {
640
+ SECTION("storage backend")
641
+ {
642
+ SECTION("couchstore")
643
+ {
644
+ {
645
+ bucket_settings.storage_backend = couchbase::core::management::cluster::bucket_storage_backend::couchstore;
646
+ couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
647
+ auto resp = test::utils::execute(integration.cluster, req);
648
+ REQUIRE_SUCCESS(resp.ctx.ec);
649
+ }
650
+
651
+ {
652
+ auto resp = wait_for_bucket_created(integration, bucket_name);
653
+ REQUIRE_SUCCESS(resp.ctx.ec);
654
+ REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::couchbase);
655
+ REQUIRE(resp.bucket.storage_backend ==
656
+ couchbase::core::management::cluster::bucket_storage_backend::couchstore);
657
+ }
658
+ }
659
+
660
+ SECTION("magma")
661
+ {
662
+ {
663
+ bucket_settings.ram_quota_mb = integration.cluster_version().is_neo() ? 1'024 : 256;
664
+ bucket_settings.storage_backend = couchbase::core::management::cluster::bucket_storage_backend::magma;
665
+ couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
666
+ auto resp = test::utils::execute(integration.cluster, req);
667
+ REQUIRE_SUCCESS(resp.ctx.ec);
668
+ }
669
+
670
+ {
671
+ auto resp = wait_for_bucket_created(integration, bucket_name);
672
+ REQUIRE_SUCCESS(resp.ctx.ec);
673
+ REQUIRE(resp.bucket.bucket_type == couchbase::core::management::cluster::bucket_type::couchbase);
674
+ REQUIRE(resp.bucket.storage_backend == couchbase::core::management::cluster::bucket_storage_backend::magma);
675
+ }
676
+ }
677
+ }
678
+ }
679
+ }
680
+ SECTION("public api")
681
+ {
682
+ couchbase::cluster c(integration.cluster);
683
+ couchbase::management::cluster::bucket_settings bucket_settings;
684
+ bucket_settings.name = bucket_name;
685
+ bucket_settings.bucket_type = couchbase::management::cluster::bucket_type::couchbase;
686
+
687
+ SECTION("default eviction")
688
+ {
689
+ {
690
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
691
+ REQUIRE_SUCCESS(ctx.ec());
692
+ }
693
+
694
+ {
695
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
696
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
697
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
698
+ });
699
+ REQUIRE(bucket_exists);
700
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
701
+ REQUIRE_SUCCESS(ctx.ec());
702
+ REQUIRE(bucket.bucket_type == couchbase::management::cluster::bucket_type::couchbase);
703
+ REQUIRE(bucket.eviction_policy == couchbase::management::cluster::bucket_eviction_policy::value_only);
704
+ }
705
+ }
706
+
707
+ SECTION("full eviction")
708
+ {
709
+ {
710
+ bucket_settings.eviction_policy = couchbase::management::cluster::bucket_eviction_policy::full;
711
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
712
+ REQUIRE_SUCCESS(ctx.ec());
713
+ }
714
+
715
+ {
716
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
717
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
718
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
719
+ });
720
+ REQUIRE(bucket_exists);
721
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
722
+ REQUIRE_SUCCESS(ctx.ec());
723
+ REQUIRE(bucket.bucket_type == couchbase::management::cluster::bucket_type::couchbase);
724
+ REQUIRE(bucket.eviction_policy == couchbase::management::cluster::bucket_eviction_policy::full);
725
+ }
726
+ }
727
+
728
+ if (integration.cluster_version().supports_storage_backend()) {
729
+ SECTION("storage backend")
730
+ {
731
+ SECTION("couchstore")
732
+ {
733
+ {
734
+ bucket_settings.storage_backend = couchbase::management::cluster::bucket_storage_backend::couchstore;
735
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
736
+ REQUIRE_SUCCESS(ctx.ec());
737
+ }
738
+
739
+ {
740
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
741
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
742
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
743
+ });
744
+ REQUIRE(bucket_exists);
745
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
746
+ REQUIRE_SUCCESS(ctx.ec());
747
+ REQUIRE(bucket.bucket_type == couchbase::management::cluster::bucket_type::couchbase);
748
+ REQUIRE(bucket.storage_backend == couchbase::management::cluster::bucket_storage_backend::couchstore);
749
+ }
750
+ }
751
+
752
+ SECTION("magma")
753
+ {
754
+ {
755
+ bucket_settings.ram_quota_mb = integration.cluster_version().is_neo() ? 1'024 : 256;
756
+ bucket_settings.storage_backend = couchbase::management::cluster::bucket_storage_backend::magma;
757
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
758
+ REQUIRE_SUCCESS(ctx.ec());
759
+ }
760
+
761
+ {
762
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
763
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
764
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
765
+ });
766
+ REQUIRE(bucket_exists);
767
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
768
+ REQUIRE_SUCCESS(ctx.ec());
769
+ REQUIRE(bucket.bucket_type == couchbase::management::cluster::bucket_type::couchbase);
770
+ REQUIRE(bucket.storage_backend == couchbase::management::cluster::bucket_storage_backend::magma);
771
+ }
772
+ }
773
+ }
774
+ }
775
+ }
776
+ }
777
+
778
+ SECTION("update no bucket")
779
+ {
780
+ SECTION("core api")
781
+ {
782
+ couchbase::core::management::cluster::bucket_settings bucket_settings;
783
+ bucket_settings.name = bucket_name;
784
+ couchbase::core::operations::management::bucket_update_request req;
785
+ req.bucket = bucket_settings;
786
+ auto resp = test::utils::execute(integration.cluster, req);
787
+ REQUIRE(resp.ctx.ec == couchbase::errc::common::bucket_not_found);
788
+ }
789
+ SECTION("public api")
790
+ {
791
+ couchbase::cluster c(integration.cluster);
792
+ couchbase::management::cluster::bucket_settings bucket_settings;
793
+ bucket_settings.name = bucket_name;
794
+ auto ctx = c.buckets().update_bucket(bucket_settings, {}).get();
795
+ REQUIRE(ctx.ec() == couchbase::errc::common::bucket_not_found);
796
+ }
797
+ }
798
+
799
+ if (integration.cluster_version().supports_minimum_durability_level()) {
800
+ SECTION("minimum durability level")
801
+ {
802
+ SECTION("core api")
803
+ {
804
+ couchbase::core::management::cluster::bucket_settings bucket_settings;
805
+ bucket_settings.name = bucket_name;
806
+
807
+ SECTION("default")
445
808
  {
446
809
  {
447
- bucket_settings.minimum_durability_level = couchbase::durability_level::majority;
448
810
  couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
449
811
  auto resp = test::utils::execute(integration.cluster, req);
450
812
  REQUIRE_SUCCESS(resp.ctx.ec);
@@ -453,7 +815,70 @@ TEST_CASE("integration: bucket management", "[integration]")
453
815
  {
454
816
  auto resp = wait_for_bucket_created(integration, bucket_name);
455
817
  REQUIRE_SUCCESS(resp.ctx.ec);
456
- REQUIRE(resp.bucket.minimum_durability_level == couchbase::durability_level::majority);
818
+ REQUIRE(resp.bucket.minimum_durability_level == couchbase::durability_level::none);
819
+ }
820
+ }
821
+
822
+ if (integration.number_of_nodes() >= 2) {
823
+ SECTION("majority")
824
+ {
825
+ {
826
+ bucket_settings.minimum_durability_level = couchbase::durability_level::majority;
827
+ couchbase::core::operations::management::bucket_create_request req{ bucket_settings };
828
+ auto resp = test::utils::execute(integration.cluster, req);
829
+ REQUIRE_SUCCESS(resp.ctx.ec);
830
+ }
831
+
832
+ {
833
+ auto resp = wait_for_bucket_created(integration, bucket_name);
834
+ REQUIRE_SUCCESS(resp.ctx.ec);
835
+ REQUIRE(resp.bucket.minimum_durability_level == couchbase::durability_level::majority);
836
+ }
837
+ }
838
+ }
839
+ }
840
+ SECTION("public api")
841
+ {
842
+ couchbase::cluster c(integration.cluster);
843
+ couchbase::management::cluster::bucket_settings bucket_settings;
844
+ bucket_settings.name = bucket_name;
845
+
846
+ SECTION("default")
847
+ {
848
+ {
849
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
850
+ REQUIRE_SUCCESS(ctx.ec());
851
+ }
852
+ {
853
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
854
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
855
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
856
+ });
857
+ REQUIRE(bucket_exists);
858
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
859
+ REQUIRE_SUCCESS(ctx.ec());
860
+ REQUIRE(bucket.minimum_durability_level == couchbase::durability_level::none);
861
+ }
862
+ }
863
+ if (integration.number_of_nodes() >= 2) {
864
+ SECTION("majority")
865
+ {
866
+ {
867
+ bucket_settings.minimum_durability_level = couchbase::durability_level::majority;
868
+ auto ctx = c.buckets().create_bucket(bucket_settings, {}).get();
869
+ REQUIRE_SUCCESS(ctx.ec());
870
+ }
871
+
872
+ {
873
+ auto bucket_exists = test::utils::wait_until([&bucket_name, c]() {
874
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
875
+ return ctx.ec() != couchbase::errc::common::bucket_not_found;
876
+ });
877
+ REQUIRE(bucket_exists);
878
+ auto [ctx, bucket] = c.buckets().get_bucket(bucket_name, {}).get();
879
+ REQUIRE_SUCCESS(ctx.ec());
880
+ REQUIRE(bucket.minimum_durability_level == couchbase::durability_level::majority);
881
+ }
457
882
  }
458
883
  }
459
884
  }
@@ -1036,6 +1461,12 @@ TEST_CASE("integration: user management collections roles", "[integration]")
1036
1461
  REQUIRE(resp.user.roles[0].scope == scope_name);
1037
1462
  REQUIRE(resp.user.roles[0].collection == collection_name);
1038
1463
  }
1464
+
1465
+ {
1466
+ couchbase::core::operations::management::scope_drop_request req{ integration.ctx.bucket, scope_name };
1467
+ auto resp = test::utils::execute(integration.cluster, req);
1468
+ REQUIRE_SUCCESS(resp.ctx.ec);
1469
+ }
1039
1470
  }
1040
1471
 
1041
1472
  TEST_CASE("integration: query index management", "[integration]")
@@ -1499,7 +1930,8 @@ TEST_CASE("integration: collections query index management", "[integration]")
1499
1930
  req.collection_name = collection_name;
1500
1931
  req.is_primary = true;
1501
1932
  resp = test::utils::execute(integration.cluster, req);
1502
- return resp.ctx.ec != couchbase::errc::common::bucket_not_found;
1933
+ return resp.ctx.ec != couchbase::errc::common::bucket_not_found &&
1934
+ resp.ctx.ec != couchbase::errc::common::scope_not_found;
1503
1935
  });
1504
1936
  REQUIRE(operation_completed);
1505
1937
  REQUIRE_SUCCESS(resp.ctx.ec);
@@ -1524,7 +1956,7 @@ TEST_CASE("integration: collections query index management", "[integration]")
1524
1956
  bool operation_completed = test::utils::wait_until([&manager, &ec]() {
1525
1957
  auto ctx = manager.create_primary_index({}).get();
1526
1958
  ec = ctx.ec();
1527
- return ctx.ec() != couchbase::errc::common::bucket_not_found;
1959
+ return ec != couchbase::errc::common::bucket_not_found && ec != couchbase::errc::common::scope_not_found;
1528
1960
  });
1529
1961
 
1530
1962
  REQUIRE(operation_completed);
@@ -1554,7 +1986,8 @@ TEST_CASE("integration: collections query index management", "[integration]")
1554
1986
  req.index_name = index_name;
1555
1987
  req.is_primary = true;
1556
1988
  resp = test::utils::execute(integration.cluster, req);
1557
- return resp.ctx.ec != couchbase::errc::common::bucket_not_found;
1989
+ return resp.ctx.ec != couchbase::errc::common::bucket_not_found &&
1990
+ resp.ctx.ec != couchbase::errc::common::scope_not_found;
1558
1991
  });
1559
1992
  REQUIRE(operation_completed);
1560
1993
  REQUIRE_SUCCESS(resp.ctx.ec);
@@ -1628,7 +2061,8 @@ TEST_CASE("integration: collections query index management", "[integration]")
1628
2061
  req.collection_name = collection_name;
1629
2062
  req.fields = { "field" };
1630
2063
  resp = test::utils::execute(integration.cluster, req);
1631
- return resp.ctx.ec != couchbase::errc::common::bucket_not_found;
2064
+ return resp.ctx.ec != couchbase::errc::common::bucket_not_found &&
2065
+ resp.ctx.ec != couchbase::errc::common::scope_not_found;
1632
2066
  });
1633
2067
  REQUIRE(operation_completed);
1634
2068
  REQUIRE_SUCCESS(resp.ctx.ec);
@@ -1781,7 +2215,8 @@ TEST_CASE("integration: collections query index management", "[integration]")
1781
2215
  req.fields = { "field" };
1782
2216
  req.deferred = true;
1783
2217
  resp = test::utils::execute(integration.cluster, req);
1784
- return resp.ctx.ec != couchbase::errc::common::bucket_not_found;
2218
+ return resp.ctx.ec != couchbase::errc::common::bucket_not_found &&
2219
+ resp.ctx.ec != couchbase::errc::common::scope_not_found;
1785
2220
  });
1786
2221
  REQUIRE(operation_completed);
1787
2222
  REQUIRE_SUCCESS(resp.ctx.ec);
@@ -1954,18 +2389,20 @@ TEST_CASE("integration: collections query index management", "[integration]")
1954
2389
  .ec() == couchbase::errc::common::ambiguous_timeout);
1955
2390
  }
1956
2391
  }
1957
- SECTION("watch missing collection")
1958
- {
1959
- SECTION("public API")
1960
- {
1961
- couchbase::cluster c(integration.cluster);
1962
- auto coll = c.bucket(integration.ctx.bucket).scope(scope_name).collection("missing_collection");
1963
- REQUIRE(coll.query_indexes()
1964
- .watch_indexes({ index_name }, couchbase::watch_query_indexes_options().timeout(std::chrono::seconds(5)))
1965
- .get()
1966
- .ec() == couchbase::errc::common::ambiguous_timeout);
1967
- }
1968
- }
2392
+ SECTION("watch missing collection"){ SECTION("public API"){ couchbase::cluster c(integration.cluster);
2393
+ auto coll = c.bucket(integration.ctx.bucket).scope(scope_name).collection("missing_collection");
2394
+ REQUIRE(coll.query_indexes()
2395
+ .watch_indexes({ index_name }, couchbase::watch_query_indexes_options().timeout(std::chrono::seconds(5)))
2396
+ .get()
2397
+ .ec() == couchbase::errc::common::ambiguous_timeout);
2398
+ }
2399
+ }
2400
+
2401
+ {
2402
+ couchbase::core::operations::management::scope_drop_request req{ integration.ctx.bucket, scope_name };
2403
+ auto resp = test::utils::execute(integration.cluster, req);
2404
+ REQUIRE_SUCCESS(resp.ctx.ec);
2405
+ }
1969
2406
  }
1970
2407
 
1971
2408
  TEST_CASE("integration: analytics index management", "[integration]")
@@ -2597,6 +3034,12 @@ TEST_CASE("integration: analytics external link management", "[integration]")
2597
3034
  run_azure_link_test(integration, dataverse_name, link_name);
2598
3035
  }
2599
3036
  }
3037
+
3038
+ {
3039
+ couchbase::core::operations::management::scope_drop_request req{ integration.ctx.bucket, scope_name };
3040
+ auto resp = test::utils::execute(integration.cluster, req);
3041
+ REQUIRE_SUCCESS(resp.ctx.ec);
3042
+ }
2600
3043
  }
2601
3044
  }
2602
3045
  }
@@ -2662,7 +3105,7 @@ TEST_CASE("integration: search index management", "[integration]")
2662
3105
  if (integration.cluster_version().is_serverless_config_profile()) {
2663
3106
  index.plan_params_json = serverless_plan_params;
2664
3107
  }
2665
- index.params_json = R"({ "store": { "indexType": "upside_down", "kvStoreName": "moss" }})";
3108
+ index.params_json = R"({ "store": { "kvStoreName": "moss" }})";
2666
3109
  couchbase::core::operations::management::search_index_upsert_request req{};
2667
3110
  req.index = index;
2668
3111
  auto resp = test::utils::execute(integration.cluster, req);