Skip to content

Commit 5fe9e18

Browse files
committed
Tests - improve consistency
Adding consistency utility functions to wait for all nodes to have a consistent view of a particular resource. Change-Id: I5ecd82ca0bc88147abf73819b2840fc7934ba1a6 Reviewed-on: https://review.couchbase.org/c/couchbase-jvm-clients/+/183021 Reviewed-by: Graham Pople <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 598ed7a commit 5fe9e18

25 files changed

+598
-141
lines changed

core-io/src/main/java/com/couchbase/client/core/util/ConsistencyUtil.java

Lines changed: 400 additions & 0 deletions
Large diffs are not rendered by default.

java-client/src/integrationTest/java/com/couchbase/client/java/AnalyticsCollectionIntegrationTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.couchbase.client.core.error.ParsingFailureException;
2121
import com.couchbase.client.core.error.ScopeNotFoundException;
2222
import com.couchbase.client.core.service.ServiceType;
23+
import com.couchbase.client.core.util.ConsistencyUtil;
2324
import com.couchbase.client.java.analytics.AnalyticsMetaData;
2425
import com.couchbase.client.java.analytics.AnalyticsResult;
2526
import com.couchbase.client.java.analytics.AnalyticsStatus;
@@ -101,8 +102,10 @@ static void setup() {
101102
waitForService(bucket, ServiceType.ANALYTICS);
102103

103104
collectionManager.createScope(scopeName);
105+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), bucket.name(), scopeName);
104106
CollectionSpec collSpec = CollectionSpec.create(collectionName, scopeName);
105107
collectionManager.createCollection(collSpec);
108+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), bucket.name(), collSpec.scopeName(), collSpec.name());
106109
waitUntilCondition(() -> collectionExists(collectionManager, collSpec));
107110

108111
waitForQueryIndexerToHaveKeyspace(cluster, config().bucketname());

java-client/src/integrationTest/java/com/couchbase/client/java/KeyValueCollectionIntegrationTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.couchbase.client.core.error.UnambiguousTimeoutException;
1919
import com.couchbase.client.core.io.CollectionIdentifier;
2020
import com.couchbase.client.core.retry.RetryReason;
21+
import com.couchbase.client.core.util.ConsistencyUtil;
2122
import com.couchbase.client.java.kv.GetResult;
2223
import com.couchbase.client.java.kv.MutationResult;
2324
import com.couchbase.client.java.manager.collection.CollectionSpec;
@@ -61,6 +62,7 @@ void recognizesCollectionAfterCreation() {
6162
String collId = UUID.randomUUID().toString().substring(0, 10);
6263
CollectionSpec collectionSpec = CollectionSpec.create(collId, CollectionIdentifier.DEFAULT_SCOPE);
6364
bucket.collections().createCollection(collectionSpec);
65+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), bucket.name(), collectionSpec.scopeName(), collectionSpec.name());
6466

6567
Collection collection = bucket.collection(collId);
6668

java-client/src/integrationTest/java/com/couchbase/client/java/QueryCollectionIntegrationTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.couchbase.client.core.error.QueryException;
2121
import com.couchbase.client.core.json.Mapper;
2222
import com.couchbase.client.core.service.ServiceType;
23+
import com.couchbase.client.core.util.ConsistencyUtil;
2324
import com.couchbase.client.java.json.JsonArray;
2425
import com.couchbase.client.java.json.JsonObject;
2526
import com.couchbase.client.java.kv.MutationResult;
@@ -98,9 +99,11 @@ static void beforeAll() {
9899
CollectionSpec collSpec = CollectionSpec.create(COLLECTION_NAME, SCOPE_NAME);
99100

100101
collectionManager.createScope(SCOPE_NAME);
102+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), bucket.name(), SCOPE_NAME);
101103
waitUntilCondition(() -> scopeExists(collectionManager, SCOPE_NAME));
102104

103105
collectionManager.createCollection(collSpec);
106+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), bucket.name(), collSpec.scopeName(), collSpec.name());
104107
waitUntilCondition(() -> collectionExists(collectionManager, collSpec));
105108

106109
waitForQueryIndexerToHaveKeyspace(cluster, COLLECTION_NAME);

java-client/src/integrationTest/java/com/couchbase/client/java/RateLimitingIntegrationTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.couchbase.client.core.msg.ResponseStatus;
3131
import com.couchbase.client.core.service.ServiceType;
3232
import com.couchbase.client.core.util.CbCollections;
33+
import com.couchbase.client.core.util.ConsistencyUtil;
3334
import com.couchbase.client.core.util.UrlQueryStringBuilder;
3435
import com.couchbase.client.java.json.JsonObject;
3536
import com.couchbase.client.java.kv.MutationResult;
@@ -249,6 +250,7 @@ void kvQuotaLimitScopesDataSize() throws Exception {
249250

250251
CollectionManager collectionManager = adminCluster.bucket(config().bucketname()).collections();
251252
collectionManager.createCollection(CollectionSpec.create(scopeName, scopeName));
253+
ConsistencyUtil.waitUntilCollectionPresent(adminCluster.core(), config().bucketname(), scopeName, scopeName);
252254

253255
Collection collection = adminCluster.bucket(config().bucketname()).scope(scopeName).collection(scopeName);
254256

@@ -422,6 +424,7 @@ void scopeQuotaLimitExceedMaxCollections() throws Exception {
422424

423425
try {
424426
collectionManager.createCollection(CollectionSpec.create("collection1", scopeName));
427+
ConsistencyUtil.waitUntilCollectionPresent(adminCluster.core(), config().bucketname(), scopeName, "collection1");
425428

426429
assertThrows(QuotaLimitedException.class, () ->
427430
collectionManager.createCollection(CollectionSpec.create("collection2", scopeName)));
@@ -626,6 +629,7 @@ void searchQuotaLimitScopesMaxIndexes() throws Exception {
626629
try {
627630
CollectionSpec collectionSpec = CollectionSpec.create(collectionName, scopeName);
628631
collectionManager.createCollection(collectionSpec);
632+
ConsistencyUtil.waitUntilCollectionPresent(adminCluster.core(), config().bucketname(), collectionSpec.scopeName(), collectionSpec.name());
629633
waitUntilCondition(() -> collectionExists(collectionManager, collectionSpec));
630634

631635
waitForService(adminCluster.bucket(config().bucketname()), ServiceType.SEARCH);

java-client/src/integrationTest/java/com/couchbase/client/java/SearchIntegrationTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.couchbase.client.java;
1818

1919
import com.couchbase.client.core.service.ServiceType;
20+
import com.couchbase.client.core.util.ConsistencyUtil;
2021
import com.couchbase.client.java.kv.MutationResult;
2122
import com.couchbase.client.java.kv.MutationState;
2223
import com.couchbase.client.java.manager.search.SearchIndex;
@@ -56,7 +57,7 @@
5657
*/
5758
@Disabled
5859
@Flaky
59-
@IgnoreWhen(missesCapabilities = Capabilities.SEARCH, clusterTypes = ClusterType.CAVES)
60+
@IgnoreWhen(missesCapabilities = Capabilities.SEARCH, clusterTypes = ClusterType.CAVES, clusterVersionIsBelow = ConsistencyUtil.CLUSTER_VERSION_MB_50101)
6061
class SearchIntegrationTest extends JavaIntegrationTest {
6162
private static final Logger LOGGER = LoggerFactory.getLogger(SearchIntegrationTest.class);
6263

@@ -73,6 +74,7 @@ static void setup() {
7374
bucket.waitUntilReady(WAIT_UNTIL_READY_DEFAULT);
7475
waitForService(bucket, ServiceType.SEARCH);
7576
cluster.searchIndexes().upsertIndex(new SearchIndex(indexName, config().bucketname()));
77+
ConsistencyUtil.waitUntilSearchIndexPresent(cluster.core(), indexName);
7678
}
7779

7880
@AfterAll

java-client/src/integrationTest/java/com/couchbase/client/java/manager/bucket/BucketManagerIntegrationTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.couchbase.client.core.error.HttpStatusCodeException;
2525
import com.couchbase.client.core.msg.kv.DurabilityLevel;
2626
import com.couchbase.client.core.service.ServiceType;
27+
import com.couchbase.client.core.util.ConsistencyUtil;
2728
import com.couchbase.client.java.Bucket;
2829
import com.couchbase.client.java.Cluster;
2930
import com.couchbase.client.java.Collection;
@@ -36,6 +37,8 @@
3637
import org.junit.jupiter.api.AfterEach;
3738
import org.junit.jupiter.api.BeforeAll;
3839
import org.junit.jupiter.api.Test;
40+
import org.junit.jupiter.api.parallel.Execution;
41+
import org.junit.jupiter.api.parallel.ExecutionMode;
3942

4043
import java.time.Duration;
4144
import java.util.HashSet;
@@ -58,6 +61,7 @@
5861
* Verifies the functionality of the bucket manager.
5962
*/
6063
@IgnoreWhen(clusterTypes = { ClusterType.MOCKED, ClusterType.CAVES, ClusterType.CAPELLA })
64+
@Execution(ExecutionMode.CONCURRENT)
6165
class BucketManagerIntegrationTest extends JavaIntegrationTest {
6266

6367
private static Cluster cluster;
@@ -93,6 +97,7 @@ static void tearDown() {
9397
}
9498

9599
private void waitUntilHealthy(String bucket) {
100+
ConsistencyUtil.waitUntilBucketPresent(cluster.core(), bucket);
96101
Util.waitUntilCondition(() -> {
97102
try {
98103
BucketSettings bkt = buckets.getBucket(bucket);
@@ -104,6 +109,7 @@ private void waitUntilHealthy(String bucket) {
104109
}
105110

106111
private void waitUntilDropped(String bucket) {
112+
ConsistencyUtil.waitUntilBucketDropped(cluster.core(), bucket);
107113
Util.waitUntilCondition(() -> {
108114
try {
109115
buckets.getBucket(bucket);
@@ -223,7 +229,7 @@ void createCouchbaseBucketWithStorageBackendMagma() {
223229
assertEquals(StorageBackend.MAGMA, settings.storageBackend());
224230
}
225231

226-
@Test
232+
@Test
227233
void shouldPickNoDurabilityLevelIfNotSpecified() {
228234
String name = UUID.randomUUID().toString();
229235
createBucket(BucketSettings.create(name)
@@ -245,7 +251,6 @@ void createAndDropBucket() {
245251
String name = UUID.randomUUID().toString();
246252

247253
createBucket(BucketSettings.create(name));
248-
waitUntilHealthy(name);
249254
assertTrue(buckets.getAllBuckets().containsKey(name));
250255

251256
buckets.dropBucket(name);
@@ -315,7 +320,6 @@ void createWithMoreThanOneReplica() {
315320
String name = UUID.randomUUID().toString();
316321

317322
createBucket(BucketSettings.create(name).numReplicas(3));
318-
waitUntilHealthy(name);
319323

320324
BucketSettings bucket = buckets.getBucket(name);
321325
assertEquals(3, bucket.numReplicas());
@@ -327,7 +331,6 @@ void customConflictResolution() {
327331
String bucketName = UUID.randomUUID().toString();
328332
try {
329333
createBucket(BucketSettings.create(bucketName).ramQuotaMB(100).conflictResolutionType(ConflictResolutionType.CUSTOM));
330-
waitUntilHealthy(bucketName);
331334

332335
BucketSettings bucket = buckets.getBucket(bucketName);
333336
assertEquals(ConflictResolutionType.CUSTOM, bucket.conflictResolutionType());
@@ -382,6 +385,7 @@ private void assertCreatedBucket(final BucketSettings settings) {
382385

383386
private void createBucket(BucketSettings settings) {
384387
buckets.createBucket(settings);
388+
ConsistencyUtil.waitUntilBucketPresent(cluster.core(), settings.name());
385389
bucketsToDrop.add(settings.name());
386390
waitUntilHealthy(settings.name());
387391
}

java-client/src/integrationTest/java/com/couchbase/client/java/manager/collection/CollectionManagerIntegrationTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.couchbase.client.core.error.ScopeExistsException;
2323
import com.couchbase.client.core.error.ScopeNotFoundException;
2424
import com.couchbase.client.core.service.ServiceType;
25+
import com.couchbase.client.core.util.ConsistencyUtil;
2526
import com.couchbase.client.java.Bucket;
2627
import com.couchbase.client.java.Cluster;
2728
import com.couchbase.client.java.util.JavaIntegrationTest;
@@ -73,13 +74,15 @@ void shouldCreateScopeAndCollection() {
7374
assertThrows(ScopeNotFoundException.class, () -> collections.createCollection(collSpec));
7475

7576
collections.createScope(scopeName);
77+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), config().bucketname(), scopeName);
7678

7779
waitUntilCondition(() -> {
7880
Optional<ScopeSpec> scope = collections.getAllScopes().stream().filter(ss -> ss.name().equals(scopeName)).findFirst();
7981
return scope.isPresent() && scope.get().equals(scopeSpec);
8082
});
8183

8284
collections.createCollection(collSpec);
85+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), collSpec.scopeName(), collSpec.name());
8386
waitUntilCondition(() -> {
8487
boolean collExists = collectionExists(collections, collSpec);
8588
if (collExists) {
@@ -95,6 +98,7 @@ void shouldThrowWhenScopeAlreadyExists() {
9598
String scope = randomString();
9699

97100
collections.createScope(scope);
101+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), config().bucketname(), scope);
98102
waitUntilCondition(() -> scopeExists(collections, scope));
99103
assertThrows(ScopeExistsException.class, () -> collections.createScope(scope));
100104
}
@@ -103,10 +107,12 @@ void shouldThrowWhenScopeAlreadyExists() {
103107
void shouldThrowWhenCollectionAlreadyExists() {
104108
String scope = randomString();
105109
collections.createScope(scope);
110+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), config().bucketname(), scope);
106111
waitUntilCondition(() -> scopeExists(collections, scope));
107112

108113
CollectionSpec collectionSpec = CollectionSpec.create(randomString(), scope);
109114
collections.createCollection(collectionSpec);
115+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), collectionSpec.scopeName(), collectionSpec.name());
110116

111117
assertThrows(CollectionExistsException.class, () -> collections.createCollection(collectionSpec));
112118
}
@@ -124,16 +130,21 @@ void shouldDropScopeAndCollections() {
124130
assertThrows(ScopeNotFoundException.class, () -> collections.dropCollection(collectionSpec1));
125131

126132
collections.createScope(scope);
133+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), config().bucketname(), scope);
127134
waitUntilCondition(() -> scopeExists(collections, scope));
128135

129136
collections.createCollection(collectionSpec1);
130137
collections.createCollection(collectionSpec2);
138+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), collectionSpec1.scopeName(), collectionSpec1.name());
139+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), collectionSpec2.scopeName(), collectionSpec2.name());
131140

132141
collections.dropCollection(collectionSpec1);
142+
ConsistencyUtil.waitUntilCollectionDropped(cluster.core(), config().bucketname(), collectionSpec1.scopeName(), collectionSpec1.name());
133143
waitUntilCondition(() -> !collectionExists(collections, collectionSpec1));
134144
assertThrows(CollectionNotFoundException.class, () -> collections.dropCollection(collectionSpec1));
135145

136146
collections.dropScope(scope);
147+
ConsistencyUtil.waitUntilScopeDropped(cluster.core(), config().bucketname(), scope);
137148
waitUntilCondition(() -> !scopeExists(collections, scope));
138149

139150
assertThrows(ScopeNotFoundException.class, () -> collections.dropCollection(collectionSpec2));
@@ -149,10 +160,13 @@ void shouldCreateCollectionWithMaxExpiry() {
149160
CollectionSpec collectionSpec2 = CollectionSpec.create(collection2, scope);
150161

151162
collections.createScope(scope);
163+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), config().bucketname(), scope);
152164
waitUntilCondition(() -> scopeExists(collections, scope));
153165

154166
collections.createCollection(collectionSpec1);
155167
collections.createCollection(collectionSpec2);
168+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), collectionSpec1.scopeName(), collectionSpec1.name());
169+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), collectionSpec2.scopeName(), collectionSpec2.name());
156170

157171
waitUntilCondition(() -> collectionExists(collections, collectionSpec1));
158172
waitUntilCondition(() -> collectionExists(collections, collectionSpec2));
@@ -178,6 +192,7 @@ void createMaxNumOfCollections() {
178192
int collectionsPerScope = 10;
179193
ScopeSpec scopeSpec = ScopeSpec.create(scopeName);
180194
collections.createScope(scopeName);
195+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), config().bucketname(), scopeName);
181196
waitUntilCondition(() -> scopeExists(collections, scopeName));
182197

183198
List<ScopeSpec> scopeList = collections.getAllScopes();
@@ -193,6 +208,7 @@ void createMaxNumOfCollections() {
193208
for (int i = 0; i < collectionsPerScope; i++) {
194209
CollectionSpec collectionSpec = CollectionSpec.create(String.valueOf(collectionsPerScope + i), scopeName);
195210
collections.createCollection(collectionSpec);
211+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), collectionSpec.scopeName(), collectionSpec.name());
196212
waitUntilCondition(() -> collectionExists(collections, collectionSpec));
197213
waitUntilCondition(() -> collections.getAllScopes().stream().anyMatch(ss -> ss.collections().contains(collectionSpec)));
198214
}

java-client/src/integrationTest/java/com/couchbase/client/java/manager/eventing/EventingFunctionManagerIntegrationTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.couchbase.client.java.manager.eventing;
1818

1919
import com.couchbase.client.core.error.*;
20+
import com.couchbase.client.core.util.ConsistencyUtil;
2021
import com.couchbase.client.java.Bucket;
2122
import com.couchbase.client.java.Cluster;
2223
import com.couchbase.client.java.Collection;
@@ -61,8 +62,11 @@ static void setup() {
6162
Bucket bucket = cluster.bucket(config().bucketname());
6263

6364
bucket.collections().createScope("eventing");
65+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), config().bucketname(), "eventing");
6466
bucket.collections().createCollection(CollectionSpec.create("source", "eventing"));
6567
bucket.collections().createCollection(CollectionSpec.create("meta", "eventing"));
68+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), "source", "eventing");
69+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), "meta", "eventing");
6670

6771
sourceCollection = bucket.scope("eventing").collection("source");
6872
metaCollection = bucket.scope("eventing").collection("meta");

java-client/src/integrationTest/java/com/couchbase/client/java/manager/query/QueryCollectionsIndexManagerIntegrationTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.couchbase.client.core.error.IndexExistsException;
2020
import com.couchbase.client.core.error.IndexNotFoundException;
2121
import com.couchbase.client.core.service.ServiceType;
22+
import com.couchbase.client.core.util.ConsistencyUtil;
2223
import com.couchbase.client.java.Bucket;
2324
import com.couchbase.client.java.Cluster;
2425
import com.couchbase.client.java.manager.collection.CollectionSpec;
@@ -51,6 +52,7 @@
5152
import static com.couchbase.client.java.manager.query.WatchQueryIndexesOptions.watchQueryIndexesOptions;
5253
import static com.couchbase.client.test.Capabilities.COLLECTIONS;
5354
import static com.couchbase.client.test.Capabilities.QUERY;
55+
import static com.couchbase.client.test.Capabilities.SUBDOC_REVIVE_DOCUMENT;
5456
import static com.couchbase.client.test.ClusterType.CAVES;
5557
import static com.couchbase.client.test.ClusterType.MOCKED;
5658
import static java.util.Collections.emptyList;
@@ -91,7 +93,9 @@ static void setup() throws Exception {
9193
waitForQueryIndexerToHaveKeyspace(cluster, bucketName);
9294

9395
bucket.collections().createScope(scopeName);
96+
ConsistencyUtil.waitUntilScopePresent(cluster.core(), config().bucketname(), scopeName);
9497
bucket.collections().createCollection(CollectionSpec.create(collectionName, scopeName));
98+
ConsistencyUtil.waitUntilCollectionPresent(cluster.core(), config().bucketname(), scopeName, collectionName);
9599
waitForQueryIndexerToHaveKeyspace(cluster, collectionName);
96100
}
97101

0 commit comments

Comments
 (0)