From b0269f62c0d56a8c038197fdc1955225455c8e03 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Wed, 2 Oct 2024 10:01:26 +0200 Subject: [PATCH] PHPLIB-1450: Consolidate and improve skipping of tests --- tests/UnifiedSpecTests/Operation.php | 35 +++- tests/UnifiedSpecTests/UnifiedSpecTest.php | 182 ++++----------------- 2 files changed, 61 insertions(+), 156 deletions(-) diff --git a/tests/UnifiedSpecTests/Operation.php b/tests/UnifiedSpecTests/Operation.php index 0419acdb3..cc7cd703a 100644 --- a/tests/UnifiedSpecTests/Operation.php +++ b/tests/UnifiedSpecTests/Operation.php @@ -83,6 +83,24 @@ final class Operation private ?string $saveResultAsEntity = null; + private static array $unsupportedOperations = [ + self::OBJECT_TEST_RUNNER => [ + 'assertNumberConnectionsCheckedOut' => 'PHP does not implement CMAP', + 'createEntities' => 'createEntities is not implemented (PHPC-1760)', + ], + Client::class => [ + 'clientBulkWrite' => 'clientBulkWrite is not implemented (PHPLIB-847)', + 'listDatabaseObjects' => 'listDatabaseObjects is not implemented', + ], + Cursor::class => ['iterateOnce' => 'iterateOnce is not implemented (PHPC-1760)'], + Database::class => [ + 'createCommandCursor' => 'commandCursor API is not yet implemented (PHPLIB-1077)', + 'listCollectionObjects' => 'listCollectionObjects is not implemented', + 'runCursorCommand' => 'commandCursor API is not yet implemented (PHPLIB-1077)', + ], + Collection::class => ['listIndexNames' => 'listIndexNames is not implemented'], + ]; + public function __construct(stdClass $o, private Context $context) { $this->entityMap = $context->getEntityMap(); @@ -166,6 +184,7 @@ private function execute() $object = $this->entityMap[$this->object]; assertIsObject($object); + $this->skipIfOperationIsNotSupported($object::class); $this->context->setActiveClient($this->entityMap->getRootClientIdOf($this->object)); switch ($object::class) { @@ -235,10 +254,6 @@ private function executeForChangeStream(ChangeStream $changeStream) private function executeForClient(Client $client) { - if ($this->name === 'clientBulkWrite') { - Assert::markTestSkipped('clientBulkWrite operation is not implemented'); - } - $args = $this->prepareArguments(); Util::assertArgumentsBySchema(Client::class, $this->name, $args); @@ -811,6 +826,8 @@ private function executeForBucket(Bucket $bucket) private function executeForTestRunner() { + $this->skipIfOperationIsNotSupported(self::OBJECT_TEST_RUNNER); + $args = $this->prepareArguments(); Util::assertArgumentsBySchema(self::OBJECT_TEST_RUNNER, $this->name, $args); @@ -963,6 +980,16 @@ private function prepareArguments(): array return Util::prepareCommonOptions($args); } + private function skipIfOperationIsNotSupported(string $executingObjectName): void + { + $skipReason = self::$unsupportedOperations[$executingObjectName][$this->name] ?? null; + if (! $skipReason) { + return; + } + + Assert::markTestSkipped($skipReason); + } + private static function prepareBulkWriteRequest(stdClass $request): array { $request = (array) $request; diff --git a/tests/UnifiedSpecTests/UnifiedSpecTest.php b/tests/UnifiedSpecTests/UnifiedSpecTest.php index 13b7dbc0e..fc4612618 100644 --- a/tests/UnifiedSpecTests/UnifiedSpecTest.php +++ b/tests/UnifiedSpecTests/UnifiedSpecTest.php @@ -14,6 +14,8 @@ use function basename; use function dirname; use function glob; +use function preg_match; +use function sprintf; /** * Unified test format spec tests. @@ -22,145 +24,24 @@ */ class UnifiedSpecTest extends FunctionalTestCase { + /** + * Incomplete test groups are listed here. These are checked using a left- + * anchored regex. Note that regex placeholder can't be used. + */ + private static array $incompleteTestGroups = [ + // Many load balancer tests use CMAP events and/or assertNumberConnectionsCheckedOut + 'load-balancers/cursors are correctly pinned to connections for load-balanced clusters' => 'PHPC does not implement CMAP', + 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters' => 'PHPC does not implement CMAP', + 'load-balancers/state change errors are correctly handled' => 'PHPC does not implement CMAP', + 'load-balancers/wait queue timeout errors include details about checked out connections' => 'PHPC does not implement CMAP', + // mongoc_cluster_stream_for_server does not retry handshakes (CDRIVER-4532, PHPLIB-1033, PHPLIB-1042) + 'retryable-reads/retryable reads handshake failures' => 'Handshakes are not retried (CDRIVER-4532)', + 'retryable-writes/retryable writes handshake failures' => 'Handshakes are not retried (CDRIVER-4532)', + ]; + private static array $incompleteTests = [ // Many load balancer tests use CMAP events and/or assertNumberConnectionsCheckedOut - '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' => 'PHPC does not implement CMAP', - 'load-balancers/cursors are correctly pinned to connections for load-balanced clusters: pinned connections are returned when the cursor is drained' => 'PHPC does not implement CMAP', - 'load-balancers/cursors are correctly pinned to connections for load-balanced clusters: pinned connections are returned to the pool when the cursor is closed' => 'PHPC does not implement CMAP', - 'load-balancers/cursors are correctly pinned to connections for load-balanced clusters: pinned connections are not returned after an network error during getMore' => 'PHPC does not implement CMAP', - 'load-balancers/cursors are correctly pinned to connections for load-balanced clusters: pinned connections are returned after a network error during a killCursors request' => 'PHPC does not implement CMAP', - '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' => 'PHPC does not implement CMAP', - 'load-balancers/cursors are correctly pinned to connections for load-balanced clusters: aggregate pins the cursor to a connection' => 'PHPC does not implement CMAP', - 'load-balancers/cursors are correctly pinned to connections for load-balanced clusters: listCollections pins the cursor to a connection' => 'PHPC does not implement CMAP', - 'load-balancers/cursors are correctly pinned to connections for load-balanced clusters: listIndexes pins the cursor to a connection' => 'PHPC does not implement CMAP', - 'load-balancers/cursors are correctly pinned to connections for load-balanced clusters: change streams pin to a connection' => 'PHPC does not implement CMAP', 'load-balancers/monitoring events include correct fields: poolClearedEvent events include serviceId' => 'PHPC does not implement CMAP', - 'load-balancers/state change errors are correctly handled: only connections for a specific serviceId are closed when pools are cleared' => 'PHPC does not implement CMAP', - 'load-balancers/state change errors are correctly handled: errors during the initial connection hello are ignored' => 'PHPC does not implement CMAP', - 'load-balancers/state change errors are correctly handled: errors during authentication are processed' => 'PHPC does not implement CMAP', - 'load-balancers/state change errors are correctly handled: stale errors are ignored' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: all operations go to the same mongos' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: transaction can be committed multiple times' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is not released after a non-transient CRUD error' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is not released after a non-transient commit error' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is released after a non-transient abort error' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is released after a transient non-network CRUD error' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is released after a transient network CRUD error' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is released after a transient non-network commit error' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is released after a transient network commit error' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is released after a transient non-network abort error' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is released after a transient network abort error' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is released on successful abort' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is returned when a new transaction is started' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: pinned connection is returned when a non-transaction operation uses the session' => 'PHPC does not implement CMAP', - 'load-balancers/transactions are correctly pinned to connections for load-balanced clusters: a connection can be shared by a transaction and a cursor' => 'PHPC does not implement CMAP', - 'load-balancers/wait queue timeout errors include details about checked out connections: wait queue timeout errors include cursor statistics' => 'PHPC does not implement CMAP', - 'load-balancers/wait queue timeout errors include details about checked out connections: wait queue timeout errors include transaction statistics' => 'PHPC does not implement CMAP', - // listDatabaseObjects is not implemented - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after InterruptedAtShutdown' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after InterruptedDueToReplStateChange' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after NotWritablePrimary' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after NotPrimaryNoSecondaryOk' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after NotPrimaryOrSecondary' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after PrimarySteppedDown' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after ShutdownInProgress' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after HostNotFound' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after HostUnreachable' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after NetworkTimeout' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects succeeds after SocketException' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects fails after two NotWritablePrimary errors' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects-serverErrors: ListDatabaseObjects fails after NotWritablePrimary when retryReads is false' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects: ListDatabaseObjects succeeds on first attempt' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects: ListDatabaseObjects succeeds on second attempt' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects: ListDatabaseObjects fails on first attempt' => 'listDatabaseObjects is not implemented', - 'retryable-reads/listDatabaseObjects: ListDatabaseObjects fails on second attempt' => 'listDatabaseObjects is not implemented', - // listCollectionObjects is not implemented - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after InterruptedAtShutdown' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after InterruptedDueToReplStateChange' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after NotWritablePrimary' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after NotPrimaryNoSecondaryOk' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after NotPrimaryOrSecondary' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after PrimarySteppedDown' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after ShutdownInProgress' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after HostNotFound' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after HostUnreachable' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after NetworkTimeout' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects succeeds after SocketException' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects fails after two NotWritablePrimary errors' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects-serverErrors: ListCollectionObjects fails after NotWritablePrimary when retryReads is false' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects: ListCollectionObjects succeeds on first attempt' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects: ListCollectionObjects succeeds on second attempt' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects: ListCollectionObjects fails on first attempt' => 'listCollectionObjects is not implemented', - 'retryable-reads/listCollectionObjects: ListCollectionObjects fails on second attempt' => 'listCollectionObjects is not implemented', - // listIndexNames is not implemented - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after InterruptedAtShutdown' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after InterruptedDueToReplStateChange' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after NotWritablePrimary' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after NotPrimaryNoSecondaryOk' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after NotPrimaryOrSecondary' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after PrimarySteppedDown' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after ShutdownInProgress' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after HostNotFound' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after HostUnreachable' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after NetworkTimeout' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames succeeds after SocketException' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames fails after two NotWritablePrimary errors' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames-serverErrors: ListIndexNames fails after NotWritablePrimary when retryReads is false' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames: ListIndexNames succeeds on first attempt' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames: ListIndexNames succeeds on second attempt' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames: ListIndexNames fails on first attempt' => 'listIndexNames is not implemented', - 'retryable-reads/listIndexNames: ListIndexNames fails on second attempt' => 'listIndexNames is not implemented', - // mongoc_cluster_stream_for_server does not retry handshakes (CDRIVER-4532, PHPLIB-1033, PHPLIB-1042) - 'retryable-reads/retryable reads handshake failures: client.listDatabases succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: client.listDatabases succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: client.listDatabaseNames succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: client.listDatabaseNames succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: client.createChangeStream succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: client.createChangeStream succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: database.aggregate succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: database.aggregate succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: database.listCollections succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: database.listCollections succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: database.listCollectionNames succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: database.listCollectionNames succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: database.createChangeStream succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: database.createChangeStream succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.aggregate succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.aggregate succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.countDocuments succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.countDocuments succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.estimatedDocumentCount succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.estimatedDocumentCount succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.distinct succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.distinct succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.find succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.find succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.findOne succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.findOne succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.listIndexes succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.listIndexes succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.listIndexNames succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.listIndexNames succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.createChangeStream succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-reads/retryable reads handshake failures: collection.createChangeStream succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.insertOne succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.insertOne succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.insertMany succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.insertMany succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.deleteOne succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.deleteOne succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.replaceOne succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.replaceOne succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.updateOne succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.updateOne succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.findOneAndDelete succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.findOneAndDelete succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.findOneAndReplace succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.findOneAndReplace succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.findOneAndUpdate succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.findOneAndUpdate succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.bulkWrite succeeds after retryable handshake network error' => 'Handshakes are not retried (CDRIVER-4532)', - 'retryable-writes/retryable writes handshake failures: collection.bulkWrite succeeds after retryable handshake server error (ShutdownInProgress)' => 'Handshakes are not retried (CDRIVER-4532)', // Skips dating back to legacy transaction tests 'transactions/mongos-recovery-token: commitTransaction retry fails on new mongos' => 'isMaster failpoints cannot be disabled', 'transactions/pin-mongos: remain pinned after non-transient error on commit' => 'Blocked on DRIVERS-2104', @@ -172,27 +53,18 @@ class UnifiedSpecTest extends FunctionalTestCase 'valid-pass/expectedEventsForClient-eventType: eventType defaults to command if unset' => 'PHPC does not implement CMAP', // CSOT is not yet implemented (PHPC-1760) 'valid-pass/collectionData-createOptions: collection is created with the correct options' => 'CSOT is not yet implemented (PHPC-1760)', - 'valid-pass/createEntities-operation: createEntities operation' => 'CSOT is not yet implemented (PHPC-1760)', - 'valid-pass/entity-cursor-iterateOnce: iterateOnce' => 'CSOT is not yet implemented (PHPC-1760)', 'valid-pass/matches-lte-operator: special lte matching operator' => 'CSOT is not yet implemented (PHPC-1760)', - // commandCursor API is not yet implemented (PHPLIB-1077) - 'valid-pass/entity-commandCursor: runCursorCommand creates and exhausts cursor by running getMores' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'valid-pass/entity-commandCursor: createCommandCursor creates a cursor and stores it as an entity that can be iterated one document at a time' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'valid-pass/entity-commandCursor: createCommandCursor\'s cursor can be closed and will perform a killCursors operation' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: successfully executes checkMetadataConsistency cursor creating command' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: errors if the command response is not a cursor' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: creates an implicit session that is reused across getMores' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: accepts an explicit session that is reused across getMores' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: returns pinned connections to the pool when the cursor is exhausted' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: returns pinned connections to the pool when the cursor is closed' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: supports configuring getMore batchSize' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: supports configuring getMore maxTimeMS' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: supports configuring getMore comment' => 'commandCursor API is not yet implemented (PHPLIB-1077)', - 'run-command/runCursorCommand: does not close the cursor when receiving an empty batch' => 'commandCursor API is not yet implemented (PHPLIB-1077)', // libmongoc always adds readConcern to aggregate command 'index-management/search index operations ignore read and write concern: listSearchIndexes ignores read and write concern' => 'libmongoc appends readConcern to aggregate command', + // Uses an invalid object name + 'run-command/runCursorCommand: does not close the cursor when receiving an empty batch' => 'Uses an invalid object name', ]; + /** + * Any tests with duplicate names are skipped here. While test names should + * not be reused in spec tests, this offers a way to skip such tests until + * the name is changed. + */ private static array $duplicateTests = ['crud/client bulkWrite partial results: partialResult is set when first operation fails during an unordered bulk write (summary)']; /** @@ -227,6 +99,12 @@ public function setUp(): void if ($this->isLoadBalanced() && isset(self::$incompleteLoadBalancerTests[$this->dataDescription()])) { $this->markTestIncomplete(self::$incompleteLoadBalancerTests[$this->dataDescription()]); } + + foreach (self::$incompleteTestGroups as $testGroup => $reason) { + if (preg_match(sprintf('#^%s#', $testGroup), $this->dataDescription())) { + $this->markTestIncomplete($reason); + } + } } #[DataProvider('provideAtlasDataLakeTests')]