diff --git a/driver-kotlin-coroutine/src/integration/kotlin/com/mongodb/kotlin/client/coroutine/UnifiedCrudTest.kt b/driver-kotlin-coroutine/src/integration/kotlin/com/mongodb/kotlin/client/coroutine/UnifiedCrudTest.kt index 47e1ea6a781..036ec5afcc4 100644 --- a/driver-kotlin-coroutine/src/integration/kotlin/com/mongodb/kotlin/client/coroutine/UnifiedCrudTest.kt +++ b/driver-kotlin-coroutine/src/integration/kotlin/com/mongodb/kotlin/client/coroutine/UnifiedCrudTest.kt @@ -15,17 +15,11 @@ */ package com.mongodb.kotlin.client.coroutine -import com.mongodb.client.unified.UnifiedCrudTest.doSkips import java.io.IOException import java.net.URISyntaxException import org.junit.jupiter.params.provider.Arguments internal class UnifiedCrudTest() : UnifiedTest() { - - override fun skips(fileDescription: String, testDescription: String) { - doSkips(fileDescription, testDescription) - } - companion object { @JvmStatic @Throws(URISyntaxException::class, IOException::class) diff --git a/driver-kotlin-sync/src/integration/kotlin/com/mongodb/kotlin/client/UnifiedCrudTest.kt b/driver-kotlin-sync/src/integration/kotlin/com/mongodb/kotlin/client/UnifiedCrudTest.kt index 55d77d42e7b..eb06f5c1875 100644 --- a/driver-kotlin-sync/src/integration/kotlin/com/mongodb/kotlin/client/UnifiedCrudTest.kt +++ b/driver-kotlin-sync/src/integration/kotlin/com/mongodb/kotlin/client/UnifiedCrudTest.kt @@ -15,17 +15,11 @@ */ package com.mongodb.kotlin.client -import com.mongodb.client.unified.UnifiedCrudTest.doSkips import java.io.IOException import java.net.URISyntaxException import org.junit.jupiter.params.provider.Arguments internal class UnifiedCrudTest() : UnifiedTest() { - - override fun skips(fileDescription: String, testDescription: String) { - doSkips(fileDescription, testDescription) - } - companion object { @JvmStatic @Throws(URISyntaxException::class, IOException::class) diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ChangeStreamsTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ChangeStreamsTest.java index db5537b12d2..6775cc8570e 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ChangeStreamsTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ChangeStreamsTest.java @@ -16,89 +16,13 @@ package com.mongodb.reactivestreams.client.unified; -import com.mongodb.lang.Nullable; -import org.bson.BsonArray; -import org.bson.BsonDocument; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.provider.Arguments; import java.io.IOException; import java.net.URISyntaxException; -import java.util.Arrays; import java.util.Collection; -import java.util.List; - -import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.disableSleep; -import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.disableWaitForBatchCursorCreation; -import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.enableSleepAfterCursorOpen; -import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.enableWaitForBatchCursorCreation; -import static org.junit.jupiter.api.Assumptions.assumeFalse; final class ChangeStreamsTest extends UnifiedReactiveStreamsTest { - - private static final List ERROR_REQUIRED_FROM_CHANGE_STREAM_INITIALIZATION_TESTS = - Arrays.asList( - "Test with document comment - pre 4.4" - ); - - private static final List EVENT_SENSITIVE_TESTS = - Arrays.asList( - "Test that comment is set on getMore", - "Test that comment is not set on getMore - pre 4.4" - ); - - private static final List TESTS_WITH_EXTRA_EVENTS = - Arrays.asList( - "Test with document comment", - "Test with string comment" - ); - - private static final List REQUIRES_BATCH_CURSOR_CREATION_WAITING = - Arrays.asList( - "Change Stream should error when an invalid aggregation stage is passed in", - "The watch helper must not throw a custom exception when executed against a single server topology, " - + "but instead depend on a server error" - ); - - @Override - protected void skips(final String fileDescription, final String testDescription) { - assumeFalse(ERROR_REQUIRED_FROM_CHANGE_STREAM_INITIALIZATION_TESTS.contains(testDescription)); - assumeFalse(EVENT_SENSITIVE_TESTS.contains(testDescription)); - assumeFalse(TESTS_WITH_EXTRA_EVENTS.contains(testDescription)); - } - - @BeforeEach - @Override - public void setUp(@Nullable final String fileDescription, - @Nullable final String testDescription, - final String schemaVersion, - @Nullable final BsonArray runOnRequirements, - final BsonArray entitiesArray, - final BsonArray initialData, - final BsonDocument definition) { - super.setUp( - fileDescription, - testDescription, - schemaVersion, - runOnRequirements, - entitiesArray, - initialData, - definition); - enableSleepAfterCursorOpen(256); - if (REQUIRES_BATCH_CURSOR_CREATION_WAITING.contains(testDescription)) { - enableWaitForBatchCursorCreation(); - } - } - - @AfterEach - @Override - public void cleanUp() { - super.cleanUp(); - disableSleep(); - disableWaitForBatchCursorCreation(); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/change-streams"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ClientSideOperationTimeoutTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ClientSideOperationTimeoutTest.java index b109931bedf..168ff4b8f81 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ClientSideOperationTimeoutTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ClientSideOperationTimeoutTest.java @@ -101,6 +101,7 @@ The Reactive Streams specification prevents us from allowing a subsequent next c public void shouldPassAllOutcomes( @Nullable final String fileDescription, @Nullable final String testDescription, + @Nullable final String directoryName, final String schemaVersion, @Nullable final BsonArray runOnRequirements, final BsonArray entitiesArray, @@ -109,6 +110,7 @@ public void shouldPassAllOutcomes( try { super.shouldPassAllOutcomes(fileDescription, testDescription, + directoryName, schemaVersion, runOnRequirements, entitiesArray, diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CollectionManagementTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CollectionManagementTest.java index 593bcc7fd9e..5e3038a06c8 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CollectionManagementTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CollectionManagementTest.java @@ -22,14 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class CollectionManagementTest extends UnifiedReactiveStreamsTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - assumeFalse(testDescription.equals("modifyCollection to changeStreamPreAndPostImages enabled")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/collection-management"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CommandLoggingTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CommandLoggingTest.java index eed17b8ec33..10d563cb928 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CommandLoggingTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CommandLoggingTest.java @@ -22,16 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class CommandLoggingTest extends UnifiedReactiveStreamsTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - // The driver has a hack where getLastError command is executed as part of the handshake in order to get a connectionId - // even when the hello command response doesn't contain it. - assumeFalse(fileDescription.equals("pre-42-server-connection-id")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/command-logging"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CommandMonitoringTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CommandMonitoringTest.java index c47777d1709..c30ca720b46 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CommandMonitoringTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/CommandMonitoringTest.java @@ -22,16 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class CommandMonitoringTest extends UnifiedReactiveStreamsTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - // The driver has a hack where getLastError command is executed as part of the handshake in order to get a connectionId - // even when the hello command response doesn't contain it. - assumeFalse(fileDescription.equals("pre-42-server-connection-id")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/command-monitoring"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ConnectionPoolLoggingTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ConnectionPoolLoggingTest.java index 5a6ee9474c1..12db392686f 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ConnectionPoolLoggingTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/ConnectionPoolLoggingTest.java @@ -22,16 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class ConnectionPoolLoggingTest extends UnifiedReactiveStreamsTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - // The implementation of the functionality related to clearing the connection pool before closing the connection - // will be carried out once the specification is finalized and ready. - assumeFalse(testDescription.equals("Connection checkout fails due to error establishing connection")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/connection-monitoring-and-pooling/logging"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/LoadBalancerTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/LoadBalancerTest.java index ff57a6afff1..f60f42139b4 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/LoadBalancerTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/LoadBalancerTest.java @@ -16,88 +16,13 @@ package com.mongodb.reactivestreams.client.unified; -import com.mongodb.lang.Nullable; -import org.bson.BsonArray; -import org.bson.BsonDocument; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.provider.Arguments; import java.io.IOException; import java.net.URISyntaxException; -import java.util.Arrays; import java.util.Collection; -import java.util.List; - -import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.disableSleep; -import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.enableSleepAfterCursorClose; -import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.enableSleepAfterCursorOpen; -import static org.junit.jupiter.api.Assumptions.assumeFalse; final class LoadBalancerTest extends UnifiedReactiveStreamsTest { - - private static final List CURSOR_OPEN_TIMING_SENSITIVE_TESTS = - Arrays.asList( - "pinned connections are returned when the cursor is drained", - "only connections for a specific serviceId are closed when pools are cleared", - "pinned connections are returned to the pool when the cursor is closed", - "no connection is pinned if all documents are returned in the initial batch", - "stale errors are ignored", - "a connection can be shared by a transaction and a cursor", - "wait queue timeout errors include cursor statistics"); - - private static final List CURSOR_CLOSE_TIMING_SENSITIVE_TESTS = - Arrays.asList( - "pinned connections are returned to the pool when the cursor is closed", - "only connections for a specific serviceId are closed when pools are cleared", - "pinned connections are returned after a network error during a killCursors request", - "a connection can be shared by a transaction and a cursor"); - - @Override - protected void skips(final String fileDescription, final String testDescription) { - // Reactive streams driver can't implement these tests because the underlying cursor is closed on error, which - // breaks assumption in the tests that closing the cursor is something that happens under user control - assumeFalse(testDescription.equals("pinned connections are not returned after an network error during getMore")); - assumeFalse(testDescription.equals("pinned connections are not returned to the pool after a non-network error on getMore")); - // Reactive streams driver can't implement this test because there is no way to tell that a change stream cursor - // that has not yet received any results has even initiated the change stream - assumeFalse(testDescription.equals("change streams pin to a connection")); - } - - @Override - @BeforeEach - public void setUp( - @Nullable final String fileDescription, - @Nullable final String testDescription, - final String schemaVersion, - @Nullable final BsonArray runOnRequirements, - final BsonArray entitiesArray, - final BsonArray initialData, - final BsonDocument definition) { - super.setUp( - fileDescription, - testDescription, - schemaVersion, - runOnRequirements, - entitiesArray, - initialData, - definition); - if (CURSOR_OPEN_TIMING_SENSITIVE_TESTS.contains(testDescription)) { - enableSleepAfterCursorOpen(256); - } - - if (CURSOR_CLOSE_TIMING_SENSITIVE_TESTS.contains(testDescription)) { - enableSleepAfterCursorClose(256); - } - } - - @Override - @AfterEach - public void cleanUp() { - super.cleanUp(); - disableSleep(); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/load-balancers"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedCrudTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedCrudTest.java index e3154d351aa..b8fd81ac7c7 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedCrudTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedCrudTest.java @@ -22,14 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.client.unified.UnifiedCrudTest.doSkips; - final class UnifiedCrudTest extends UnifiedReactiveStreamsTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - doSkips(fileDescription, testDescription); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/crud"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedGridFSTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedGridFSTest.java index 6a8eba3e96c..eefc6839d17 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedGridFSTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedGridFSTest.java @@ -22,17 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class UnifiedGridFSTest extends UnifiedReactiveStreamsTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - // contentType is deprecated in GridFS spec, and 4.x Java driver no longer support it, so skipping this test - assumeFalse(testDescription.equals("upload when contentType is provided")); - // Re-enable when JAVA-4214 is fixed - assumeFalse(testDescription.equals("delete when files entry does not exist and there are orphaned chunks")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/gridfs"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedReactiveStreamsTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedReactiveStreamsTest.java index d0c0844bbc8..62c1315e240 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedReactiveStreamsTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedReactiveStreamsTest.java @@ -22,6 +22,7 @@ import com.mongodb.client.MongoDatabase; import com.mongodb.client.gridfs.GridFSBucket; import com.mongodb.client.unified.UnifiedTest; +import com.mongodb.client.unified.UnifiedTestModifications; import com.mongodb.client.vault.ClientEncryption; import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.gridfs.GridFSBuckets; @@ -31,6 +32,14 @@ import com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient; import com.mongodb.reactivestreams.client.syncadapter.SyncMongoDatabase; +import static com.mongodb.client.unified.UnifiedTestModifications.Modifier; +import static com.mongodb.client.unified.UnifiedTestModifications.TestDef; +import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.disableSleep; +import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.disableWaitForBatchCursorCreation; +import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.enableSleepAfterCursorClose; +import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.enableSleepAfterCursorOpen; +import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.enableWaitForBatchCursorCreation; + public abstract class UnifiedReactiveStreamsTest extends UnifiedTest { protected UnifiedReactiveStreamsTest() { } @@ -49,4 +58,40 @@ protected GridFSBucket createGridFSBucket(final MongoDatabase database) { protected ClientEncryption createClientEncryption(final MongoClient keyVaultClient, final ClientEncryptionSettings clientEncryptionSettings) { return new SyncClientEncryption(new ClientEncryptionImpl(((SyncMongoClient) keyVaultClient).getWrapped(), clientEncryptionSettings)); } + + @Override + protected boolean isReactive() { + return true; + } + + @Override + protected void postSetUp(final TestDef testDef) { + super.postSetUp(testDef); + if (testDef.wasAssignedModifier(UnifiedTestModifications.Modifier.IGNORE_EXTRA_EVENTS)) { + ignoreExtraEvents(); // no disable needed + } + if (testDef.wasAssignedModifier(Modifier.SLEEP_AFTER_CURSOR_OPEN)) { + enableSleepAfterCursorOpen(256); + } + if (testDef.wasAssignedModifier(Modifier.SLEEP_AFTER_CURSOR_CLOSE)) { + enableSleepAfterCursorClose(256); + } + if (testDef.wasAssignedModifier(Modifier.WAIT_FOR_BATCH_CURSOR_CREATION)) { + enableWaitForBatchCursorCreation(); + } + } + + @Override + protected void postCleanUp(final TestDef testDef) { + super.postCleanUp(testDef); + if (testDef.wasAssignedModifier(Modifier.WAIT_FOR_BATCH_CURSOR_CREATION)) { + disableWaitForBatchCursorCreation(); + } + if (testDef.wasAssignedModifier(Modifier.SLEEP_AFTER_CURSOR_CLOSE)) { + disableSleep(); + } + if (testDef.wasAssignedModifier(Modifier.SLEEP_AFTER_CURSOR_OPEN)) { + disableSleep(); + } + } } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedRetryableReadsTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedRetryableReadsTest.java index 5a0246ccf6c..4f2336f4173 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedRetryableReadsTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedRetryableReadsTest.java @@ -16,61 +16,13 @@ package com.mongodb.reactivestreams.client.unified; -import com.mongodb.lang.Nullable; -import org.bson.BsonArray; -import org.bson.BsonDocument; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.provider.Arguments; import java.io.IOException; import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.client.unified.UnifiedRetryableReadsTest.doSkips; -import static com.mongodb.client.unified.UnifiedTestSkips.testDef; -import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.disableWaitForBatchCursorCreation; -import static com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient.enableWaitForBatchCursorCreation; - final class UnifiedRetryableReadsTest extends UnifiedReactiveStreamsTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - doSkips(testDef("unified-test-format/retryable-reads", fileDescription, testDescription)); - } - - @Override - @BeforeEach - public void setUp( - final String fileDescription, - final String testDescription, - final String schemaVersion, - @Nullable final BsonArray runOnRequirements, - final BsonArray entitiesArray, - final BsonArray initialData, - final BsonDocument definition) { - super.setUp( - fileDescription, - testDescription, - schemaVersion, - runOnRequirements, - entitiesArray, - initialData, - definition); - if (fileDescription.startsWith("changeStreams") || testDescription.contains("ChangeStream")) { - // Several reactive change stream tests fail if we don't block waiting for batch cursor creation. - enableWaitForBatchCursorCreation(); - // The reactive driver will execute extra getMore commands for change streams. Ignore them. - ignoreExtraEvents(); - } - } - - @Override - @AfterEach - public void cleanUp() { - super.cleanUp(); - disableWaitForBatchCursorCreation(); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/retryable-reads"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedRetryableWritesTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedRetryableWritesTest.java index 4d63bae7279..8fbfb43d92d 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedRetryableWritesTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedRetryableWritesTest.java @@ -22,15 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.client.unified.UnifiedRetryableWritesTest.doSkips; -import static com.mongodb.client.unified.UnifiedTestSkips.testDef; - final class UnifiedRetryableWritesTest extends UnifiedReactiveStreamsTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - doSkips(testDef("unified-test-format/retryable-writes", fileDescription, testDescription)); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/retryable-writes"); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedServerDiscoveryAndMonitoringTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedServerDiscoveryAndMonitoringTest.java index 73695fd5f52..e4fb6da3627 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedServerDiscoveryAndMonitoringTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedServerDiscoveryAndMonitoringTest.java @@ -22,16 +22,8 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.client.unified.UnifiedTestSkips.testDef; - final class UnifiedServerDiscoveryAndMonitoringTest extends UnifiedReactiveStreamsTest { private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/server-discovery-and-monitoring"); } - - @Override - protected void skips(final String fileDescription, final String testDescription) { - com.mongodb.client.unified.UnifiedServerDiscoveryAndMonitoringTest.doSkips( - testDef("unified-test-format/server-discovery-and-monitoring", fileDescription, testDescription)); - } } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedTransactionsTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedTransactionsTest.java index 18a92f8eee8..c1990e5d830 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedTransactionsTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/unified/UnifiedTransactionsTest.java @@ -22,22 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.ClusterFixture.isSharded; -import static com.mongodb.ClusterFixture.serverVersionLessThan; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class UnifiedTransactionsTest extends UnifiedReactiveStreamsTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - assumeFalse(fileDescription.equals("count")); - if (serverVersionLessThan(4, 4) && isSharded()) { - assumeFalse(fileDescription.equals("pin-mongos") && testDescription.equals("distinct")); - assumeFalse(fileDescription.equals("read-concern") && testDescription.equals("only first distinct includes readConcern")); - assumeFalse(fileDescription.equals("read-concern") && testDescription.equals("distinct ignores collection readConcern")); - assumeFalse(fileDescription.equals("reads") && testDescription.equals("distinct")); - } - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/transactions"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/CollectionManagementTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/CollectionManagementTest.java index cbc371c1913..1830fa24c9d 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/CollectionManagementTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/CollectionManagementTest.java @@ -22,14 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class CollectionManagementTest extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - assumeFalse(testDescription.equals("modifyCollection to changeStreamPreAndPostImages enabled")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/collection-management"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/CommandLoggingTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/CommandLoggingTest.java index 02fbae2fd40..23302ebdd52 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/CommandLoggingTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/CommandLoggingTest.java @@ -22,18 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.ClusterFixture.isServerlessTest; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class CommandLoggingTest extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - assumeFalse(isServerlessTest()); - // The driver has a hack where getLastError command is executed as part of the handshake in order to get a connectionId - // even when the hello command response doesn't contain it. - assumeFalse(fileDescription.equals("pre-42-server-connection-id")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/command-logging"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/CommandMonitoringTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/CommandMonitoringTest.java index 345639fba60..c6148aaaef4 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/CommandMonitoringTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/CommandMonitoringTest.java @@ -22,18 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.ClusterFixture.isServerlessTest; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - -final class CommandMonitoringTest extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - assumeFalse(isServerlessTest()); - // The driver has a hack where getLastError command is executed as part of the handshake in order to get a connectionId - // even when the hello command response doesn't contain it. - assumeFalse(fileDescription.equals("pre-42-server-connection-id")); - } - +public final class CommandMonitoringTest extends UnifiedSyncTest { private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/command-monitoring"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/ConnectionPoolLoggingTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/ConnectionPoolLoggingTest.java index 8d34eb0a1fa..6079f1931b7 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/ConnectionPoolLoggingTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/ConnectionPoolLoggingTest.java @@ -22,16 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class ConnectionPoolLoggingTest extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - // The implementation of the functionality related to clearing the connection pool before closing the connection - // will be carried out once the specification is finalized and ready. - assumeFalse(testDescription.equals("Connection checkout fails due to error establishing connection")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/connection-monitoring-and-pooling/logging"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedAtlasDataLakeTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedAtlasDataLakeTest.java index 7b3183f0fee..009a78d3d3f 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedAtlasDataLakeTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedAtlasDataLakeTest.java @@ -22,15 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.ClusterFixture.isDataLakeTest; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - final class UnifiedAtlasDataLakeTest extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - assumeTrue(isDataLakeTest()); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/atlas-data-lake-testing"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedCrudTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedCrudTest.java index 22c5a5e3807..eaf7546bece 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedCrudTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedCrudTest.java @@ -22,50 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet; -import static com.mongodb.ClusterFixture.serverVersionAtLeast; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - public final class UnifiedCrudTest extends UnifiedSyncTest { - public static void doSkips(final String fileDescription, final String testDescription) { - assumeFalse(testDescription.equals("Deprecated count with empty collection")); - assumeFalse(testDescription.equals("Deprecated count with collation")); - assumeFalse(testDescription.equals("Deprecated count without a filter")); - assumeFalse(testDescription.equals("Deprecated count with a filter")); - assumeFalse(testDescription.equals("Deprecated count with skip and limit")); - assumeFalse(testDescription.equals("Unacknowledged findOneAndReplace with hint string on 4.4+ server")); - assumeFalse(testDescription.equals("Unacknowledged findOneAndReplace with hint document on 4.4+ server")); - assumeFalse(testDescription.equals("Unacknowledged findOneAndUpdate with hint string on 4.4+ server")); - assumeFalse(testDescription.equals("Unacknowledged findOneAndUpdate with hint document on 4.4+ server")); - assumeFalse(testDescription.equals("Unacknowledged findOneAndDelete with hint string on 4.4+ server")); - assumeFalse(testDescription.equals("Unacknowledged findOneAndDelete with hint document on 4.4+ server")); - if (isDiscoverableReplicaSet() && serverVersionAtLeast(8, 0)) { - assumeFalse(testDescription.equals("Aggregate with $out includes read preference for 5.0+ server")); - assumeFalse(testDescription.equals("Database-level aggregate with $out includes read preference for 5.0+ server")); - } - if (fileDescription.equals("updateOne-sort")) { - assumeFalse(testDescription.equals("UpdateOne with sort option"), "Skipping until JAVA-5622 is implemented"); - assumeFalse(testDescription.equals("updateOne with sort option unsupported (server-side error)"), "Skipping until JAVA-5622 is implemented"); - } - if (fileDescription.equals("replaceOne-sort")) { - assumeFalse(testDescription.equals("ReplaceOne with sort option"), "Skipping until JAVA-5622 is implemented"); - assumeFalse(testDescription.equals("replaceOne with sort option unsupported (server-side error)"), "Skipping until JAVA-5622 is implemented"); - } - if (fileDescription.equals("BulkWrite updateOne-sort")) { - assumeFalse(testDescription.equals("BulkWrite updateOne with sort option"), "Skipping until JAVA-5622 is implemented"); - assumeFalse(testDescription.equals("BulkWrite updateOne with sort option unsupported (server-side error)"), "Skipping until JAVA-5622 is implemented"); - } - if (fileDescription.equals("BulkWrite replaceOne-sort")) { - assumeFalse(testDescription.equals("BulkWrite replaceOne with sort option"), "Skipping until JAVA-5622 is implemented"); - assumeFalse(testDescription.equals("BulkWrite replaceOne with sort option unsupported (server-side error)"), "Skipping until JAVA-5622 is implemented"); - } - } - - @Override - protected void skips(final String fileDescription, final String testDescription) { - doSkips(fileDescription, testDescription); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/crud"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedGridFSTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedGridFSTest.java index 0413e2c0c0c..baac34f4959 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedGridFSTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedGridFSTest.java @@ -22,15 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class UnifiedGridFSTest extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - // contentType is deprecated in GridFS spec, and 4.x Java driver no longer support it, so skipping this test - assumeFalse(testDescription.equals("upload when contentType is provided")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/gridfs"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedRetryableReadsTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedRetryableReadsTest.java index 75a8d8f1adb..9859bcc782e 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedRetryableReadsTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedRetryableReadsTest.java @@ -22,30 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.client.unified.UnifiedTestSkips.TestDef; -import static com.mongodb.client.unified.UnifiedTestSkips.testDef; - public final class UnifiedRetryableReadsTest extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - doSkips(testDef("unified-test-format/retryable-reads", fileDescription, testDescription)); - } - - public static void doSkips(final TestDef def) { - def.skipDeprecated("Deprecated feature removed") - .file("retryable-reads", "count") - .file("retryable-reads", "count-serverErrors"); - - def.skipDeprecated("Deprecated feature never implemented") - .file("retryable-reads", "listDatabaseObjects") - .file("retryable-reads", "listDatabaseObjects-serverErrors") - .file("retryable-reads", "listCollectionObjects") - .file("retryable-reads", "listCollectionObjects-serverErrors"); - - def.skipJira("https://jira.mongodb.org/browse/JAVA-5224") - .test("retryable-reads", "ReadConcernMajorityNotAvailableYet is a retryable read", "Find succeeds on second attempt after ReadConcernMajorityNotAvailableYet"); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/retryable-reads"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedRetryableWritesTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedRetryableWritesTest.java index ab15619b7fc..2397aeb8b0d 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedRetryableWritesTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedRetryableWritesTest.java @@ -16,39 +16,13 @@ package com.mongodb.client.unified; -import com.mongodb.client.unified.UnifiedTestSkips.TestDef; import org.junit.jupiter.params.provider.Arguments; import java.io.IOException; import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet; -import static com.mongodb.ClusterFixture.isSharded; -import static com.mongodb.ClusterFixture.serverVersionLessThan; -import static com.mongodb.client.unified.UnifiedTestSkips.testDef; - public final class UnifiedRetryableWritesTest extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - doSkips(testDef("unified-test-format/retryable-writes", fileDescription, testDescription)); - } - - public static void doSkips(final TestDef def) { - if (isSharded() && serverVersionLessThan(5, 0)) { - def.skipJira("https://jira.mongodb.org/browse/JAVA-5125") - .testContains("retryable-writes", "succeeds after WriteConcernError") - .testContains("retryable-writes", "succeeds after retryable writeConcernError"); - } - if (isDiscoverableReplicaSet() && serverVersionLessThan(4, 4)) { - def.skipJira("https://jira.mongodb.org/browse/JAVA-5341") - .test("retryable-writes", "retryable-writes insertOne serverErrors", "RetryableWriteError label is added based on writeConcernError in pre-4.4 mongod response"); - } - def.skipJira("https://jira.mongodb.org/browse/JAVA-4586") - .testContains("retryable-writes", "client bulkWrite") - .testContains("retryable-writes", "client.clientBulkWrite"); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/retryable-writes"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedServerDiscoveryAndMonitoringTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedServerDiscoveryAndMonitoringTest.java index 89f81073d88..a88fe334525 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedServerDiscoveryAndMonitoringTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedServerDiscoveryAndMonitoringTest.java @@ -22,36 +22,8 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.client.unified.UnifiedTestSkips.TestDef; -import static com.mongodb.client.unified.UnifiedTestSkips.testDef; - public final class UnifiedServerDiscoveryAndMonitoringTest extends UnifiedSyncTest { private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/server-discovery-and-monitoring"); } - - @Override - protected void skips(final String fileDescription, final String testDescription) { - doSkips(testDef("unified-test-format/server-discovery-and-monitoring", fileDescription, testDescription)); - } - - public static void doSkips(final TestDef def) { - def.skipJira("https://jira.mongodb.org/browse/JAVA-5230") - .test("server-discovery-and-monitoring", "serverMonitoringMode", "connect with serverMonitoringMode=auto >=4.4") - .test("server-discovery-and-monitoring", "serverMonitoringMode", "connect with serverMonitoringMode=stream >=4.4"); - def.skipJira("https://jira.mongodb.org/browse/JAVA-4770") - .file("server-discovery-and-monitoring", "standalone-logging") - .file("server-discovery-and-monitoring", "replicaset-logging") - .file("server-discovery-and-monitoring", "sharded-logging") - .file("server-discovery-and-monitoring", "loadbalanced-logging"); - def.skipJira("https://jira.mongodb.org/browse/JAVA-5229") - .file("server-discovery-and-monitoring", "standalone-emit-topology-description-changed-before-close") - .file("server-discovery-and-monitoring", "replicaset-emit-topology-description-changed-before-close") - .file("server-discovery-and-monitoring", "sharded-emit-topology-description-changed-before-close") - .file("server-discovery-and-monitoring", "loadbalanced-emit-topology-description-changed-before-close"); - def.skipJira("https://jira.mongodb.org/browse/JAVA-5564") - .test("server-discovery-and-monitoring", "serverMonitoringMode", "poll waits after successful heartbeat"); - def.skipJira("https://jira.mongodb.org/browse/JAVA-4536") - .file("server-discovery-and-monitoring", "interruptInUse"); - } } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTest.java index 58ad07034ec..d1d1fc58c8a 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTest.java @@ -21,6 +21,7 @@ import com.mongodb.MongoNamespace; import com.mongodb.ReadPreference; import com.mongodb.UnixServerAddress; +import com.mongodb.client.unified.UnifiedTestModifications.TestDef; import com.mongodb.event.TestServerMonitorListener; import com.mongodb.internal.logging.LogMessage; import com.mongodb.logging.TestLoggingInterceptor; @@ -80,6 +81,7 @@ import static com.mongodb.client.test.CollectionHelper.getCurrentClusterTime; import static com.mongodb.client.test.CollectionHelper.killAllSessions; import static com.mongodb.client.unified.RunOnRequirementsMatcher.runOnRequirementsMet; +import static com.mongodb.client.unified.UnifiedTestModifications.testDef; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.toList; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -114,6 +116,7 @@ public abstract class UnifiedTest { private UnifiedTestContext rootContext; private boolean ignoreExtraEvents; private BsonDocument startingClusterTime; + private TestDef testDef; private class UnifiedTestContext { private final AssertionContext context = new AssertionContext(); @@ -157,17 +160,19 @@ protected static Collection getTestData(final String directory) throw BsonDocument fileDocument = getTestDocument(file); for (BsonValue cur : fileDocument.getArray("tests")) { - data.add(UnifiedTest.createTestData(fileDocument, cur.asDocument())); + data.add(UnifiedTest.createTestData(directory, fileDocument, cur.asDocument())); } } return data; } @NonNull - private static Arguments createTestData(final BsonDocument fileDocument, final BsonDocument testDocument) { + private static Arguments createTestData( + final String directory, final BsonDocument fileDocument, final BsonDocument testDocument) { return Arguments.of( fileDocument.getString("description").getValue(), testDocument.getString("description").getValue(), + directory, fileDocument.getString("schemaVersion").getValue(), fileDocument.getArray("runOnRequirements", null), fileDocument.getArray("createEntities", new BsonArray()), @@ -189,6 +194,7 @@ protected BsonDocument getDefinition() { public void setUp( @Nullable final String fileDescription, @Nullable final String testDescription, + @Nullable final String directoryName, final String schemaVersion, @Nullable final BsonArray runOnRequirements, final BsonArray entitiesArray, @@ -208,6 +214,8 @@ public void setUp( rootContext = new UnifiedTestContext(); rootContext.getAssertionContext().push(ContextElement.ofTest(definition)); ignoreExtraEvents = false; + testDef = testDef(directoryName, fileDescription, testDescription, isReactive()); + UnifiedTestModifications.doSkips(testDef); skips(fileDescription, testDescription); assertTrue( schemaVersion.equals("1.0") @@ -255,6 +263,11 @@ public void setUp( this::createMongoClient, this::createGridFSBucket, this::createClientEncryption); + + postSetUp(testDef); + } + + protected void postSetUp(final TestDef def) { } @AfterEach @@ -263,20 +276,29 @@ public void cleanUp() { failPoint.disableFailPoint(); } entities.close(); + postCleanUp(testDef); + } + + protected void postCleanUp(final TestDef testDef) { } /** - * This method is called once per {@link #setUp(String, String, String, BsonArray, BsonArray, BsonArray, BsonDocument)}, - * unless {@link #setUp(String, String, String, BsonArray, BsonArray, BsonArray, BsonDocument)} fails unexpectedly. + * This method is called once per {@link #setUp(String, String, String, String, org.bson.BsonArray, org.bson.BsonArray, org.bson.BsonArray, org.bson.BsonDocument)}, + * unless {@link #setUp(String, String, String, String, org.bson.BsonArray, org.bson.BsonArray, org.bson.BsonArray, org.bson.BsonDocument)} fails unexpectedly. */ protected void skips(final String fileDescription, final String testDescription) { } + protected boolean isReactive() { + return false; + } + @ParameterizedTest(name = "{0}: {1}") @MethodSource("data") public void shouldPassAllOutcomes( @Nullable final String fileDescription, @Nullable final String testDescription, + @Nullable final String directoryName, final String schemaVersion, @Nullable final BsonArray runOnRequirements, final BsonArray entitiesArray, diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestFailureValidator.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestFailureValidator.java index 2694ee8066e..b5bf53f4b88 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestFailureValidator.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestFailureValidator.java @@ -36,6 +36,7 @@ final class UnifiedTestFailureValidator extends UnifiedSyncTest { @Override @BeforeEach public void setUp( + final String directoryName, @Nullable final String fileDescription, @Nullable final String testDescription, final String schemaVersion, @@ -45,6 +46,7 @@ public void setUp( final BsonDocument definition) { try { super.setUp( + directoryName, fileDescription, testDescription, schemaVersion, @@ -63,6 +65,7 @@ public void setUp( public void shouldPassAllOutcomes( @Nullable final String fileDescription, @Nullable final String testDescription, + @Nullable final String directoryName, final String schemaVersion, @Nullable final BsonArray runOnRequirements, final BsonArray entitiesArray, @@ -73,6 +76,7 @@ public void shouldPassAllOutcomes( super.shouldPassAllOutcomes( fileDescription, testDescription, + directoryName, schemaVersion, runOnRequirements, entitiesArray, diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java new file mode 100644 index 00000000000..ea8180ead0e --- /dev/null +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java @@ -0,0 +1,514 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.client.unified; + +import com.mongodb.assertions.Assertions; +import com.mongodb.lang.NonNull; +import com.mongodb.lang.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Supplier; + +import static com.mongodb.ClusterFixture.isDataLakeTest; +import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet; +import static com.mongodb.ClusterFixture.isServerlessTest; +import static com.mongodb.ClusterFixture.isSharded; +import static com.mongodb.ClusterFixture.serverVersionLessThan; +import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.IGNORE_EXTRA_EVENTS; +import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.SLEEP_AFTER_CURSOR_CLOSE; +import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.SLEEP_AFTER_CURSOR_OPEN; +import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.WAIT_FOR_BATCH_CURSOR_CREATION; +import static org.junit.jupiter.api.Assumptions.assumeFalse; + +public final class UnifiedTestModifications { + public static void doSkips(final TestDef def) { + + // atlas-data-lake + + def.skipAccordingToSpec("Data lake tests should only run on data lake") + .when(() -> !isDataLakeTest()) + .directory("atlas-data-lake-testing"); + + // change-streams + + def.skipNoncompliantReactive("error required from change stream initialization") // TODO reason? + .test("change-streams", "change-streams", "Test with document comment - pre 4.4"); + def.skipNoncompliantReactive("event sensitive tests") // TODO reason? + .test("change-streams", "change-streams", "Test that comment is set on getMore") + .test("change-streams", "change-streams", "Test that comment is not set on getMore - pre 4.4"); + def.modify(IGNORE_EXTRA_EVENTS) + .test("change-streams", "change-streams", "Test with document comment") + .test("change-streams", "change-streams", "Test with string comment"); + def.modify(SLEEP_AFTER_CURSOR_OPEN) + .directory("change-streams"); + def.modify(WAIT_FOR_BATCH_CURSOR_CREATION) + .test("change-streams", "change-streams-errors", "Change Stream should error when an invalid aggregation stage is passed in") + .test("change-streams", "change-streams-errors", "The watch helper must not throw a custom exception when executed against a single server topology, but instead depend on a server error"); + + // client-side-operation-timeout (CSOT) + + // TODO + + // collection-management + + def.skipNoncompliant("") // TODO reason? + .test("collection-management", "modifyCollection-pre_and_post_images", "modifyCollection to changeStreamPreAndPostImages enabled"); + + // command-logging-and-monitoring + + def.skipNoncompliant("TODO") + .when(() -> !def.isReactive() && isServerlessTest()) // TODO why reactive check? + .directory("command-logging") + .directory("command-monitoring"); + + def.skipNoncompliant("The driver has a hack where getLastError command " + + "is executed as part of the handshake in order to " + + "get a connectionId even when the hello command " + + "response doesn't contain it.") + .file("command-monitoring", "pre-42-server-connection-id") + .file("command-logging", "pre-42-server-connection-id"); + + // connection-monitoring-and-pooling + + // TODO reason, jira + // added as part of https://jira.mongodb.org/browse/JAVA-4976 , but unknown Jira to complete + // The implementation of the functionality related to clearing the connection pool before closing the connection + // will be carried out once the specification is finalized and ready. + def.skipTodo("") + .test("connection-monitoring-and-pooling/logging", "connection-logging", "Connection checkout fails due to error establishing connection"); + + // load-balancers + + def.modify(SLEEP_AFTER_CURSOR_OPEN) + .test("load-balancers", "state change errors are correctly handled", "only connections for a specific serviceId are closed when pools are cleared") + .test("load-balancers", "state change errors are correctly handled", "stale errors are ignored") + .test("load-balancers", "cursors are correctly pinned to connections for load-balanced clusters", "pinned connections are returned when the cursor is drained") + .test("load-balancers", "cursors are correctly pinned to connections for load-balanced clusters", "pinned connections are returned to the pool when the cursor is closed") + .test("load-balancers", "cursors are correctly pinned to connections for load-balanced clusters", "no connection is pinned if all documents are returned in the initial batch") + .test("load-balancers", "transactions are correctly pinned to connections for load-balanced clusters", "a connection can be shared by a transaction and a cursor") + .test("load-balancers", "wait queue timeout errors include details about checked out connections", "wait queue timeout errors include cursor statistics"); + def.modify(SLEEP_AFTER_CURSOR_CLOSE) + .test("load-balancers", "state change errors are correctly handled", "only connections for a specific serviceId are closed when pools are cleared") + .test("load-balancers", "cursors are correctly pinned to connections for load-balanced clusters", "pinned connections are returned to the pool when the cursor is closed") + .test("load-balancers", "cursors are correctly pinned to connections for load-balanced clusters", "pinned connections are returned after a network error during a killCursors request") + .test("load-balancers", "transactions are correctly pinned to connections for load-balanced clusters", "a connection can be shared by a transaction and a cursor"); + def.skipNoncompliantReactive("Reactive streams driver can't implement " + + "these tests because the underlying cursor is closed " + + "on error, which breaks assumption in the tests that " + + "closing the cursor is something that happens under " + + "user control") + .test("load-balancers", "cursors are correctly pinned to connections for load-balanced clusters", "pinned connections are not returned after an network error during getMore") + .test("load-balancers", "cursors are correctly pinned to connections for load-balanced clusters", "pinned connections are not returned to the pool after a non-network error on getMore"); + def.skipNoncompliantReactive("Reactive streams driver can't implement " + + "this test because there is no way to tell that a " + + "change stream cursor that has not yet received any " + + "results has even initiated the change stream") + .test("load-balancers", "cursors are correctly pinned to connections for load-balanced clusters", "change streams pin to a connection"); + + // crud + + def.skipDeprecated("Deprecated count method removed, cf https://github.com/mongodb/mongo-java-driver/pull/1328#discussion_r1513641410") + .test("crud", "count-empty", "Deprecated count with empty collection") + .test("crud", "count-collation", "Deprecated count with collation") + .test("crud", "count", "Deprecated count without a filter") + .test("crud", "count", "Deprecated count with a filter") + .test("crud", "count", "Deprecated count with skip and limit"); + def.skipTodo("See downstream changes comment on https://jira.mongodb.org/browse/JAVA-4275") + .test("crud", "findOneAndReplace-hint-unacknowledged", "Unacknowledged findOneAndReplace with hint string on 4.4+ server") + .test("crud", "findOneAndReplace-hint-unacknowledged", "Unacknowledged findOneAndReplace with hint document on 4.4+ server") + .test("crud", "findOneAndUpdate-hint-unacknowledged", "Unacknowledged findOneAndUpdate with hint string on 4.4+ server") + .test("crud", "findOneAndUpdate-hint-unacknowledged", "Unacknowledged findOneAndUpdate with hint document on 4.4+ server") + .test("crud", "findOneAndDelete-hint-unacknowledged", "Unacknowledged findOneAndDelete with hint string on 4.4+ server") + .test("crud", "findOneAndDelete-hint-unacknowledged", "Unacknowledged findOneAndDelete with hint document on 4.4+ server"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-5622") + .test("crud", "updateOne-sort", "UpdateOne with sort option") + .test("crud", "updateOne-sort", "updateOne with sort option unsupported (server-side error)") + .test("crud", "replaceOne-sort", "ReplaceOne with sort option") + .test("crud", "replaceOne-sort", "replaceOne with sort option unsupported (server-side error)") + .test("crud", "BulkWrite updateOne-sort", "BulkWrite updateOne with sort option") + .test("crud", "BulkWrite updateOne-sort", "BulkWrite updateOne with sort option unsupported (server-side error)") + .test("crud", "BulkWrite replaceOne-sort", "BulkWrite replaceOne with sort option") + .test("crud", "BulkWrite replaceOne-sort", "BulkWrite replaceOne with sort option unsupported (server-side error)"); + + // gridfs + + def.skipDeprecated("contentType is deprecated in GridFS spec, and 4.x Java driver no longer supports it") + .test("gridfs", "gridfs-upload", "upload when contentType is provided"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-4214") + .test("gridfs", "gridfs-delete", "delete when files entry does not exist and there are orphaned chunks"); + + // retryable-reads + + def.modify(WAIT_FOR_BATCH_CURSOR_CREATION, IGNORE_EXTRA_EVENTS) + //.testContains("retryable-reads", "ChangeStream") + .test("retryable-reads", "retryable reads handshake failures", "client.createChangeStream succeeds after retryable handshake network error") + .test("retryable-reads", "retryable reads handshake failures", "client.createChangeStream succeeds after retryable handshake server error (ShutdownInProgress)") + .test("retryable-reads", "retryable reads handshake failures", "database.createChangeStream succeeds after retryable handshake network error") + .test("retryable-reads", "retryable reads handshake failures", "database.createChangeStream succeeds after retryable handshake server error (ShutdownInProgress)") + .test("retryable-reads", "retryable reads handshake failures", "collection.createChangeStream succeeds after retryable handshake network error") + .test("retryable-reads", "retryable reads handshake failures", "collection.createChangeStream succeeds after retryable handshake server error (ShutdownInProgress)"); + def.modify(WAIT_FOR_BATCH_CURSOR_CREATION, IGNORE_EXTRA_EVENTS) + .file("retryable-reads", "changeStreams-client.watch-serverErrors") + .file("retryable-reads", "changeStreams-client.watch") + .file("retryable-reads", "changeStreams-db.coll.watch-serverErrors") + .file("retryable-reads", "changeStreams-db.coll.watch") + .file("retryable-reads", "changeStreams-db.watch-serverErrors") + .file("retryable-reads", "changeStreams-db.watch"); + def.skipDeprecated("Deprecated feature removed") + .file("retryable-reads", "count") + .file("retryable-reads", "count-serverErrors"); + def.skipDeprecated("Deprecated feature never implemented") + .file("retryable-reads", "listDatabaseObjects") + .file("retryable-reads", "listDatabaseObjects-serverErrors") + .file("retryable-reads", "listCollectionObjects") + .file("retryable-reads", "listCollectionObjects-serverErrors"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-5224") + .test("retryable-reads", "ReadConcernMajorityNotAvailableYet is a retryable read", "Find succeeds on second attempt after ReadConcernMajorityNotAvailableYet"); + + // retryable-writes + + def.skipJira("https://jira.mongodb.org/browse/JAVA-5125") + .when(() -> isSharded() && serverVersionLessThan(5, 0)) + //.testContains("retryable-writes", "succeeds after WriteConcernError") + .test("retryable-writes", "bulkWrite-errorLabels", "BulkWrite succeeds after WriteConcernError ShutdownInProgress") + .test("retryable-writes", "updateOne-errorLabels", "UpdateOne succeeds after WriteConcernError ShutdownInProgress") + .test("retryable-writes", "deleteOne-errorLabels", "DeleteOne succeeds after WriteConcernError ShutdownInProgress") + .test("retryable-writes", "insertOne-errorLabels", "InsertOne succeeds after WriteConcernError InterruptedAtShutdown") + .test("retryable-writes", "insertOne-errorLabels", "InsertOne succeeds after WriteConcernError InterruptedDueToReplStateChange") + .test("retryable-writes", "insertOne-errorLabels", "InsertOne succeeds after WriteConcernError PrimarySteppedDown") + .test("retryable-writes", "insertOne-errorLabels", "InsertOne succeeds after WriteConcernError ShutdownInProgress") + .test("retryable-writes", "insertMany-errorLabels", "InsertMany succeeds after WriteConcernError ShutdownInProgress") + .test("retryable-writes", "replaceOne-errorLabels", "ReplaceOne succeeds after WriteConcernError ShutdownInProgress") + .test("retryable-writes", "findOneAndUpdate-errorLabels", "FindOneAndUpdate succeeds after WriteConcernError ShutdownInProgress") + .test("retryable-writes", "findOneAndDelete-errorLabels", "FindOneAndDelete succeeds after WriteConcernError ShutdownInProgress") + .test("retryable-writes", "findOneAndReplace-errorLabels", "FindOneAndReplace succeeds after WriteConcernError ShutdownInProgress") + //.testContains("retryable-writes", "succeeds after retryable writeConcernError") + .test("retryable-writes", "client bulkWrite retryable writes", "client bulkWrite with no multi: true operations succeeds after retryable writeConcernError") + .test("retryable-writes", "retryable-writes insertOne serverErrors", "InsertOne succeeds after retryable writeConcernError") + .test("retryable-writes", "retryable-writes bulkWrite serverErrors", "BulkWrite succeeds after retryable writeConcernError in first batch"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-5341") + .when(() -> isDiscoverableReplicaSet() && serverVersionLessThan(4, 4)) + .test("retryable-writes", "retryable-writes insertOne serverErrors", "RetryableWriteError label is added based on writeConcernError in pre-4.4 mongod response"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-4586") + //.testContains("retryable-writes", "client bulkWrite") + .test("retryable-writes", "client bulkWrite retryable writes", "client bulkWrite with no multi: true operations succeeds after retryable top-level error") + .test("retryable-writes", "client bulkWrite retryable writes", "client bulkWrite with multi: true operations fails after retryable top-level error") + .test("retryable-writes", "client bulkWrite retryable writes", "client bulkWrite with no multi: true operations succeeds after retryable writeConcernError") + .test("retryable-writes", "client bulkWrite retryable writes", "client bulkWrite with multi: true operations fails after retryable writeConcernError") + .test("retryable-writes", "client bulkWrite retryable writes", "client bulkWrite with retryWrites: false does not retry") + .test("retryable-writes", "client bulkWrite retryable writes with client errors", "client bulkWrite with one network error succeeds after retry") + .test("retryable-writes", "client bulkWrite retryable writes with client errors", "client bulkWrite with two network errors fails after retry") + //.testContains("retryable-writes", "client.clientBulkWrite") + .test("retryable-writes", "retryable writes handshake failures", "client.clientBulkWrite succeeds after retryable handshake network error") + .test("retryable-writes", "retryable writes handshake failures", "client.clientBulkWrite succeeds after retryable handshake server error (ShutdownInProgress)"); + + // server-discovery-and-monitoring (SDAM) + + def.skipJira("https://jira.mongodb.org/browse/JAVA-5230") + .test("server-discovery-and-monitoring", "serverMonitoringMode", "connect with serverMonitoringMode=auto >=4.4") + .test("server-discovery-and-monitoring", "serverMonitoringMode", "connect with serverMonitoringMode=stream >=4.4"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-4770") + .file("server-discovery-and-monitoring", "standalone-logging") + .file("server-discovery-and-monitoring", "replicaset-logging") + .file("server-discovery-and-monitoring", "sharded-logging") + .file("server-discovery-and-monitoring", "loadbalanced-logging"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-5229") + .file("server-discovery-and-monitoring", "standalone-emit-topology-description-changed-before-close") + .file("server-discovery-and-monitoring", "replicaset-emit-topology-description-changed-before-close") + .file("server-discovery-and-monitoring", "sharded-emit-topology-description-changed-before-close") + .file("server-discovery-and-monitoring", "loadbalanced-emit-topology-description-changed-before-close"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-5564") + .test("server-discovery-and-monitoring", "serverMonitoringMode", "poll waits after successful heartbeat"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-4536") + .file("server-discovery-and-monitoring", "interruptInUse"); + + // transactions + + def.skipDeprecated("Deprecated feature removed") + .file("transactions", "count"); + def.skipDeprecated("Only affects 4.2, which is EOL, see https://github.com/mongodb/mongo-java-driver/pull/1310/files#r1491812405") + .when(() -> serverVersionLessThan(4, 4) && isSharded()) + .test("transactions", "pin-mongos", "distinct") + .test("transactions", "read-concern", "only first distinct includes readConcern") + .test("transactions", "read-concern", "distinct ignores collection readConcern") + .test("transactions", "reads", "distinct"); + + // valid-pass + + def.skipDeprecated("MongoDB releases prior to 4.4 incorrectly add " + + "errorLabels as a field within the writeConcernError " + + "document instead of as a top-level field. Rather " + + "than handle that in code, we skip the test on older " + + "server versions.") + .when(() -> serverVersionLessThan(4, 4)) + .test("valid-pass", "poc-retryable-writes", "InsertOne fails after multiple retryable writeConcernErrors"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-5389") + .file("valid-pass", "expectedEventsForClient-topologyDescriptionChangedEvent"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-4862") + .file("valid-pass", "entity-commandCursor"); + def.skipJira("https://jira.mongodb.org/browse/JAVA-5631") + .file("valid-pass", "kmsProviders-explicit_kms_credentials") + .file("valid-pass", "kmsProviders-mixed_kms_credential_fields"); + } + + private UnifiedTestModifications() {} + + public static TestDef testDef(final String dir, final String file, final String test, final boolean reactive) { + return new TestDef(dir, file, test, reactive); + } + + public static final class TestDef { + private final String dir; + private final String file; + private final String test; + private final boolean reactive; + + private final List modifiers = new ArrayList<>(); + + private TestDef(final String dir, final String file, final String test, final boolean reactive) { + this.dir = dir; + this.file = file; + this.test = test; + this.reactive = reactive; + } + + /** + * Test is skipped because it is pending implementation, and there is + * a Jira ticket tracking this which has more information. + * + * @param skip reason for skipping the test; must start with a Jira URL + */ + public TestApplicator skipJira(final String skip) { + Assertions.assertTrue(skip.startsWith("https://jira.mongodb.org/browse/JAVA-")); + return new TestApplicator(this, skip); + } + + /** + * Test is skipped because the feature under test was deprecated, and + * was removed in the Java driver. + * + * @param skip reason for skipping the test + */ + public TestApplicator skipDeprecated(final String skip) { + return new TestApplicator(this, skip); + } + + /** + * Test is skipped because the Java driver cannot comply with the spec. + * + * @param skip reason for skipping the test + */ + public TestApplicator skipNoncompliant(final String skip) { + return new TestApplicator(this, skip); + } + + /** + * Test is skipped because the Java Reactive driver cannot comply with the spec. + * + * @param skip reason for skipping the test + */ + public TestApplicator skipNoncompliantReactive(final String skip) { + return new TestApplicator(this, skip); + } + + /** + * The test is skipped, as specified. This should be paired with a + * "when" clause. + */ + public TestApplicator skipAccordingToSpec(final String skip) { + return new TestApplicator(this, skip); + } + + /** + * The test is skipped for an unknown reason. + */ + public TestApplicator skipTodo(final String skip) { + return new TestApplicator(this, skip); + } + + public TestApplicator modify(final Modifier... modifiers) { + return new TestApplicator(this, Arrays.asList(modifiers)); + } + + public boolean isReactive() { + return reactive; + } + + public boolean wasAssignedModifier(final Modifier modifier) { + return this.modifiers.contains(modifier); + } + } + + /** + * Applies settings to the underlying test definition. Chainable. + */ + public static final class TestApplicator { + private final TestDef testDef; + + private final boolean shouldSkip; + @Nullable + private final String reasonToApply; + private final List modifiersToApply; + private Supplier precondition; + private boolean matchWasPerformed = false; + + private TestApplicator( + final TestDef testDef, + final List modifiersToApply) { + this.testDef = testDef; + this.shouldSkip = false; + this.reasonToApply = null; + this.modifiersToApply = modifiersToApply; + } + + private TestApplicator( + final TestDef testDef, + @NonNull + final String reason) { + this.testDef = testDef; + this.shouldSkip = true; + this.reasonToApply = reason; + this.modifiersToApply = new ArrayList<>(); + } + + private TestApplicator onMatch(final boolean match) { + matchWasPerformed = true; + if (precondition != null && !precondition.get()) { + return this; + } + if (shouldSkip) { + assumeFalse(match, reasonToApply); + } else { + if (match) { + this.testDef.modifiers.addAll(this.modifiersToApply); + } + } + return this; + } + + /** + * Applies to all tests in directory. + * @param dir the directory name + * @return this + */ + public TestApplicator directory(final String dir) { + boolean match = ("unified-test-format/" + dir).equals(testDef.dir); + return onMatch(match); + } + + /** + * Applies to all tests in file under the directory. + * @param dir the directory name + * @param file the test file's "description" field + * @return this + */ + public TestApplicator file(final String dir, final String file) { + boolean match = ("unified-test-format/" + dir).equals(testDef.dir) + && file.equals(testDef.file); + return onMatch(match); + } + + /** + * Applies to the test where dir, file, and test match. + * @param dir the directory name + * @param file the test file's "description" field + * @param test the individual test's "description" field + * @return this + */ + public TestApplicator test(final String dir, final String file, final String test) { + boolean match = testDef.dir.equals("unified-test-format/" + dir) + && testDef.file.equals(file) + && testDef.test.equals(test); + return onMatch(match); + } + + /** + * Utility method: emit replacement to standard out. + * @param dir the directory name + * @param fragment the substring to check in the test "description" field + * @return this + */ + public TestApplicator testContains(final String dir, final String fragment) { + boolean match = ("unified-test-format/" + dir).equals(testDef.dir) + && testDef.test.contains(fragment); + if (match) { + System.out.printf( + "!!! REPLACE %s WITH: .test(\"%s\", \"%s\", \"%s\")%n", + fragment, + testDef.dir.replace("unified-test-format/", ""), + testDef.file, + testDef.test); + } + return this; + } + + /** + * Utility method: emit file info to standard out + * @param dir the directory name + * @param test the individual test's "description" field + * @return this + */ + public TestApplicator test(final String dir, final String test) { + boolean match = testDef.test.equals(test); + if (match) { + System.out.printf( + "!!! ADD: \"%s\", \"%s\", \"%s\"%n", + testDef.dir, testDef.file, test); + } + return this; + } + + /** + * Ensuing matching methods are applied only when the condition is met. + * For example, if tests should only be skipped (or modified) on + * serverless, check for serverless in the condition. + * Must be the first method called in the chain. + * @param precondition the condition; methods are no-op when false. + * @return this + */ + public TestApplicator when(final Supplier precondition) { + if (this.precondition != null || this.matchWasPerformed) { + throw new IllegalStateException("Condition must be specified first and once."); + } + this.precondition = precondition; + return this; + } + } + + public enum Modifier { + /** + * Reactive only. + * The reactive driver produces extra getMore commands. + * This will ignore all extra commands, including the getMores. + */ + IGNORE_EXTRA_EVENTS, + /** + * Reactive only. + */ + SLEEP_AFTER_CURSOR_OPEN, + /** + * Reactive only. + */ + SLEEP_AFTER_CURSOR_CLOSE, + /** + * Reactive only. + */ + WAIT_FOR_BATCH_CURSOR_CREATION, + } +} diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestSkips.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestSkips.java deleted file mode 100644 index cd2a14247e3..00000000000 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestSkips.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2008-present MongoDB, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.mongodb.client.unified; - -import com.mongodb.assertions.Assertions; - -import static org.junit.jupiter.api.Assumptions.assumeFalse; - -public final class UnifiedTestSkips { - - private UnifiedTestSkips() {} - - public static TestDef testDef(final String dir, final String file, final String test) { - return new TestDef(dir, file, test); - } - - public static final class TestDef { - private final String dir; - private final String file; - private final String test; - - private TestDef(final String dir, final String file, final String test) { - this.dir = dir; - this.file = file; - this.test = test; - } - - /** - * Test is skipped because it is pending implementation, and there is - * a Jira ticket tracking this which has more information. - * - * @param skip reason for skipping the test; must start with a Jira URL - */ - public Skip skipJira(final String skip) { - Assertions.assertTrue(skip.startsWith("https://jira.mongodb.org/browse/JAVA-")); - return new Skip(this, skip); - } - - /** - * Test is skipped because the feature under test was deprecated, and - * was removed in the Java driver. - * - * @param skip reason for skipping the test - */ - public Skip skipDeprecated(final String skip) { - return new Skip(this, skip); - } - - /** - * Test is skipped because the Java driver cannot comply with the spec. - * - * @param skip reason for skipping the test - */ - public Skip skipNoncompliant(final String skip) { - return new Skip(this, skip); - } - } - - public static final class Skip { - private final TestDef testDef; - private final String reason; - - private Skip(final TestDef testDef, final String reason) { - this.testDef = testDef; - this.reason = reason; - } - - /** - * All tests in file under dir skipped. - * @param dir the directory name - * @param file the test file's "description" field - * @return this - */ - public Skip file(final String dir, final String file) { - boolean match = ("unified-test-format/" + dir).equals(testDef.dir) - && file.equals(testDef.file); - assumeFalse(match, reason); - return this; - } - - /** - * Test skipped if dir, file, and test match. - * @param dir the directory name - * @param file the test file's "description" field - * @param test the individual test's "description" field - * @return this - */ - public Skip test(final String dir, final String file, final String test) { - boolean match = ("unified-test-format/" + dir).equals(testDef.dir) - && file.equals(testDef.file) - && test.equals(testDef.test); - assumeFalse(match, reason); - return this; - } - - /** - * Test skipped if the test description contains the fragment as a substring - * Avoid using this, except during development. - * @param dir the directory name - * @param fragment the substring to check in the test "description" field - * @return this - */ - public Skip testContains(final String dir, final String fragment) { - boolean match = ("unified-test-format/" + dir).equals(testDef.dir) - && testDef.test.contains(fragment); - assumeFalse(match, reason); - return this; - } - } -} diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestValidator.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestValidator.java index 0626ab89e09..414d161677d 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestValidator.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestValidator.java @@ -22,24 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.ClusterFixture.serverVersionLessThan; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class UnifiedTestValidator extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - assumeFalse(testDescription.equals("InsertOne fails after multiple retryable writeConcernErrors") && serverVersionLessThan(4, 4), - "MongoDB releases prior to 4.4 incorrectly add errorLabels as a field within the writeConcernError document " - + "instead of as a top-level field. Rather than handle that in code, we skip the test on older server versions."); - // Feature to be implemented in scope of JAVA-5389 - assumeFalse(fileDescription.equals("expectedEventsForClient-topologyDescriptionChangedEvent")); - // Feature to be implemented in scope JAVA-4862 - assumeFalse(fileDescription.equals("entity-commandCursor")); - // To be investigated in JAVA-5631 - assumeFalse(fileDescription.equals("kmsProviders-explicit_kms_credentials")); - assumeFalse(fileDescription.equals("kmsProviders-mixed_kms_credential_fields")); - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/valid-pass"); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTransactionsTest.java b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTransactionsTest.java index 5acf74cd972..cf95ba9795a 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTransactionsTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTransactionsTest.java @@ -22,22 +22,7 @@ import java.net.URISyntaxException; import java.util.Collection; -import static com.mongodb.ClusterFixture.isSharded; -import static com.mongodb.ClusterFixture.serverVersionLessThan; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - final class UnifiedTransactionsTest extends UnifiedSyncTest { - @Override - protected void skips(final String fileDescription, final String testDescription) { - assumeFalse(fileDescription.equals("count")); - if (serverVersionLessThan(4, 4) && isSharded()) { - assumeFalse(fileDescription.equals("pin-mongos") && testDescription.equals("distinct")); - assumeFalse(fileDescription.equals("read-concern") && testDescription.equals("only first distinct includes readConcern")); - assumeFalse(fileDescription.equals("read-concern") && testDescription.equals("distinct ignores collection readConcern")); - assumeFalse(fileDescription.equals("reads") && testDescription.equals("distinct")); - } - } - private static Collection data() throws URISyntaxException, IOException { return getTestData("unified-test-format/transactions"); } diff --git a/driver-workload-executor/src/main/com/mongodb/workload/WorkloadExecutor.java b/driver-workload-executor/src/main/com/mongodb/workload/WorkloadExecutor.java index 88248e13ca3..0e995cb34fd 100644 --- a/driver-workload-executor/src/main/com/mongodb/workload/WorkloadExecutor.java +++ b/driver-workload-executor/src/main/com/mongodb/workload/WorkloadExecutor.java @@ -97,7 +97,9 @@ protected boolean terminateLoop() { BsonArray runOnRequirements = fileDocument.getArray("runOnRequirements", null); BsonArray createEntities = fileDocument.getArray("createEntities", new BsonArray()); BsonArray initialData = fileDocument.getArray("initialData", new BsonArray()); - unifiedTest.setUp(null, + unifiedTest.setUp( + null, + null, null, schemaVersion, runOnRequirements, @@ -105,6 +107,7 @@ protected boolean terminateLoop() { initialData, testDocument); unifiedTest.shouldPassAllOutcomes( + null, null, null, schemaVersion,