From b4e9d21d44bc440cd2e013e4d7709f99955f38c2 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Tue, 16 Jun 2026 12:36:05 +0100 Subject: [PATCH 1/2] JAVA-6237: Explicit Encryption Case 2 uses contention-10 collection Servers implementing SERVER-91887 require payloads to exactly match the collection's configured contention factor, not just avoid exceeding it. Updates the specifications submodule to d30d717b (specifications master). --- ...tSideEncryptionExplicitEncryptionTest.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideEncryptionExplicitEncryptionTest.java b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideEncryptionExplicitEncryptionTest.java index 45e7e26fb9..d16f926f46 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideEncryptionExplicitEncryptionTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideEncryptionExplicitEncryptionTest.java @@ -52,7 +52,6 @@ import static com.mongodb.fixture.EncryptionFixture.getKmsProviders; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeFalse; import static org.junit.jupiter.api.Assumptions.assumeTrue; import static util.JsonPoweredTestHelper.getTestDocument; @@ -74,6 +73,7 @@ public void setUp() { MongoNamespace dataKeysNamespace = new MongoNamespace("keyvault.datakeys"); BsonDocument encryptedFields = bsonDocumentFromPath("encryptedFields.json"); + BsonDocument encryptedFieldsC10 = bsonDocumentFromPath("encryptedFields-c10.json"); BsonDocument key1Document = bsonDocumentFromPath("keys/key1-document.json"); MongoDatabase explicitEncryptionDatabase = getDefaultDatabase(); @@ -82,6 +82,11 @@ public void setUp() { explicitEncryptionDatabase.createCollection("explicit_encryption", new CreateCollectionOptions().encryptedFields(encryptedFields)); + explicitEncryptionDatabase.getCollection("explicit_encryption_c10") + .drop(new DropCollectionOptions().encryptedFields(encryptedFieldsC10)); + explicitEncryptionDatabase.createCollection("explicit_encryption_c10", + new CreateCollectionOptions().encryptedFields(encryptedFieldsC10)); + MongoCollection dataKeysCollection = getMongoClient() .getDatabase(dataKeysNamespace.getDatabaseName()) .getCollection(dataKeysNamespace.getCollectionName(), BsonDocument.class) @@ -145,26 +150,18 @@ public void canInsertEncryptedIndexedAndFindWithNonZeroContention() { assumeTrue(serverVersionLessThan(9, 0)); EncryptOptions encryptOptions = new EncryptOptions("Indexed").keyId(key1Id).contentionFactor(10L); MongoCollection coll = encryptedClient.getDatabase(getDefaultDatabaseName()) - .getCollection("explicit_encryption", BsonDocument.class); + .getCollection("explicit_encryption_c10", BsonDocument.class); for (int i = 0; i < 10; i++) { BsonBinary insertPayload = clientEncryption.encrypt(ENCRYPTED_INDEXED_VALUE, encryptOptions); coll.insertOne(new BsonDocument("encryptedIndexed", insertPayload)); } - encryptOptions = new EncryptOptions("Indexed").keyId(key1Id).queryType("equality").contentionFactor(0L); + // Find with matching contentionFactor returns all 10 documents. + encryptOptions = new EncryptOptions("Indexed").keyId(key1Id).contentionFactor(10L).queryType("equality"); BsonBinary findPayload = clientEncryption.encrypt(ENCRYPTED_INDEXED_VALUE, encryptOptions); List values = coll.find(new BsonDocument("encryptedIndexed", findPayload)).into(new ArrayList<>()); - assertTrue(values.size() < 10); - values.forEach(v -> - assertEquals(ENCRYPTED_INDEXED_VALUE, v.get("encryptedIndexed")) - ); - - encryptOptions = new EncryptOptions("Indexed").keyId(key1Id).contentionFactor(10L).queryType("equality"); - BsonBinary findPayload2 = clientEncryption.encrypt(ENCRYPTED_INDEXED_VALUE, encryptOptions); - - values = coll.find(new BsonDocument("encryptedIndexed", findPayload2)).into(new ArrayList<>()); assertEquals(10, values.size()); values.forEach(v -> From 977e356198cafe08817cde52951b781238664fb2 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Mon, 6 Jul 2026 14:18:42 +0100 Subject: [PATCH 2/2] Rebased on main, added java docs / display names, reenabled Case 2 --- ...lientSideEncryptionExplicitEncryptionTest.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideEncryptionExplicitEncryptionTest.java b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideEncryptionExplicitEncryptionTest.java index d16f926f46..dd99363577 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideEncryptionExplicitEncryptionTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideEncryptionExplicitEncryptionTest.java @@ -35,6 +35,7 @@ import org.bson.BsonValue; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -43,7 +44,6 @@ import static com.mongodb.ClusterFixture.isStandalone; import static com.mongodb.ClusterFixture.serverVersionAtLeast; -import static com.mongodb.ClusterFixture.serverVersionLessThan; import static com.mongodb.client.Fixture.getDefaultDatabase; import static com.mongodb.client.Fixture.getDefaultDatabaseName; import static com.mongodb.client.Fixture.getMongoClient; @@ -56,6 +56,10 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; import static util.JsonPoweredTestHelper.getTestDocument; +/** + * @see + * Client Side Encryption spec explicit encryption prose tests + */ public abstract class AbstractClientSideEncryptionExplicitEncryptionTest { private static final BsonString ENCRYPTED_INDEXED_VALUE = new BsonString("encrypted indexed value"); private static final BsonString ENCRYPTED_UNINDEXED_VALUE = new BsonString("encrypted unindexed value"); @@ -126,6 +130,7 @@ public void cleanUp() { } @Test + @DisplayName("Case 1: can insert encrypted indexed and find") public void canInsertEncryptedIndexedAndFind() { EncryptOptions encryptOptions = new EncryptOptions("Indexed").keyId(key1Id).contentionFactor(0L); BsonBinary insertPayload = clientEncryption.encrypt(ENCRYPTED_INDEXED_VALUE, encryptOptions); @@ -143,11 +148,8 @@ public void canInsertEncryptedIndexedAndFind() { } @Test + @DisplayName("Case 2: can insert encrypted indexed and find with non-zero contention") public void canInsertEncryptedIndexedAndFindWithNonZeroContention() { - // JAVA-6237: this test inserts with contentionFactor 10 but encryptedFields.json configures the - // encryptedIndexed field with contention 0. Servers >= 9.0 reject this mismatch (SERVER-91887); - // skip until the spec prose test is corrected (DRIVERS-3547). - assumeTrue(serverVersionLessThan(9, 0)); EncryptOptions encryptOptions = new EncryptOptions("Indexed").keyId(key1Id).contentionFactor(10L); MongoCollection coll = encryptedClient.getDatabase(getDefaultDatabaseName()) .getCollection("explicit_encryption_c10", BsonDocument.class); @@ -170,6 +172,7 @@ public void canInsertEncryptedIndexedAndFindWithNonZeroContention() { } @Test + @DisplayName("Case 3: can insert encrypted unindexed") public void canInsertEncryptedUnindexed() { EncryptOptions encryptOptions = new EncryptOptions("Unindexed").keyId(key1Id); MongoCollection coll = encryptedClient.getDatabase(getDefaultDatabaseName()) @@ -185,6 +188,7 @@ public void canInsertEncryptedUnindexed() { } @Test + @DisplayName("Case 4: can roundtrip encrypted indexed") public void canRoundtripEncryptedIndexed() { EncryptOptions encryptOptions = new EncryptOptions("Indexed").keyId(key1Id).contentionFactor(0L); @@ -195,6 +199,7 @@ public void canRoundtripEncryptedIndexed() { } @Test + @DisplayName("Case 5: can roundtrip encrypted unindexed") public void canRoundtripEncryptedUnindexed() { EncryptOptions encryptOptions = new EncryptOptions("Unindexed").keyId(key1Id);