From bfb5fb9da484031a9177a578ae19b98ea6970a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 8 Apr 2026 09:47:28 +0200 Subject: [PATCH] Add tests to improve coverage of untested or under-tested APIs (#1975) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add tests to improve coverage of untested or under-tested APIs - Session::getServer() — no test existed; documents that the method returns null when the session is not pinned to a server (pinning was removed for sharded clusters in MongoDB 6.0+) - Session::startTransaction() with all options combined — each option (maxCommitTimeMS, readConcern, readPreference, writeConcern) was only tested in isolation; this test verifies they coexist correctly and are all reflected by getTransactionOptions() - ExecutionTimeoutException::hasErrorLabel() — hasErrorLabel() was tested on RuntimeException and BulkWriteException but not on this subclass - ConnectionTimeoutException::hasErrorLabel() — same gap as above - BulkWriteCommandException::getWriteConcernErrors() — the method appeared in debug output but was never explicitly asserted; this test verifies it returns an empty array when only write errors occur - Query construction with maxAwaitTimeMS — only error/range validation tests existed; this test verifies valid values are accepted - BulkWriteCommand constructor with multiple options combined — each option (ordered, comment, verboseResults) was tested in isolation; this test verifies they work together - Command construction with invalid maxAwaitTimeMS — the >= 0 validation existed in Command.c but had no corresponding test * Address Copilot review comments - query-ctor-maxAwaitTimeMS-001: remove UINT32_MAX case (4294967295 overflows PHP_INT_MAX on 32-bit platforms, causing float coercion) - session-getServer-001: update comment to accurately reflect that mongos pinning was removed in MongoDB 6.0+ * Merge new tests into existing files where appropriate - bulkwritecommand-ctor-ordered-002: add getWriteConcernErrors() assertion (verifies empty array when only write errors occur); removes the need for a separate bulkwritecommandexception-getwriteconcernerrors-001.phpt - session-getTransactionOptions-001: add combined-options case (all four transaction options together); removes the need for a separate session-startTransaction-002.phpt --- ...ritecommand-ctor-options-combined-001.phpt | 60 +++++++++++++++++++ .../bulkwritecommand-ctor-ordered-002.phpt | 3 + tests/command/command-ctor_error-002.phpt | 18 ++++++ ...iontimeoutexception-haserrorlabel-001.phpt | 22 +++++++ ...iontimeoutexception-haserrorlabel-001.phpt | 22 +++++++ .../query/query-ctor-maxAwaitTimeMS-001.phpt | 18 ++++++ .../query/query-ctor-maxAwaitTimeMS-002.phpt | 16 +++++ tests/session/session-getServer-001.phpt | 23 +++++++ .../session-getTransactionOptions-001.phpt | 25 ++++++++ 9 files changed, 207 insertions(+) create mode 100644 tests/bulkwritecommand/bulkwritecommand-ctor-options-combined-001.phpt create mode 100644 tests/command/command-ctor_error-002.phpt create mode 100644 tests/exception/connectiontimeoutexception-haserrorlabel-001.phpt create mode 100644 tests/exception/executiontimeoutexception-haserrorlabel-001.phpt create mode 100644 tests/query/query-ctor-maxAwaitTimeMS-001.phpt create mode 100644 tests/query/query-ctor-maxAwaitTimeMS-002.phpt create mode 100644 tests/session/session-getServer-001.phpt diff --git a/tests/bulkwritecommand/bulkwritecommand-ctor-options-combined-001.phpt b/tests/bulkwritecommand/bulkwritecommand-ctor-options-combined-001.phpt new file mode 100644 index 000000000..9912848b2 --- /dev/null +++ b/tests/bulkwritecommand/bulkwritecommand-ctor-options-combined-001.phpt @@ -0,0 +1,60 @@ +--TEST-- +MongoDB\Driver\BulkWriteCommand::__construct() multiple options combined +--SKIPIF-- + + + + +--FILE-- +getCommandName() !== 'bulkWrite') { + return; + } + + $command = $event->getCommand(); + + printf("ordered: %s\n", var_export($command->ordered, true)); + printf("comment: %s\n", json_encode($command->comment)); + } + + public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event): void + { + } + + public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event): void + { + } +} + +$manager = create_test_manager(); + +$bulk = new MongoDB\Driver\BulkWriteCommand([ + 'ordered' => false, + 'comment' => 'test comment', + 'verboseResults' => true, +]); +$bulk->insertOne(NS, ['_id' => 1]); +$bulk->insertOne(NS, ['_id' => 2]); + +$manager->addSubscriber(new CommandLogger); +$result = $manager->executeBulkWriteCommand($bulk); + +var_dump($result->getInsertedCount()); +var_dump($result->getInsertResults() !== null); + +?> +===DONE=== + +--EXPECT-- +ordered: false +comment: "test comment" +int(2) +bool(true) +===DONE=== diff --git a/tests/bulkwritecommand/bulkwritecommand-ctor-ordered-002.phpt b/tests/bulkwritecommand/bulkwritecommand-ctor-ordered-002.phpt index 24ad876d4..bacb0a4d4 100644 --- a/tests/bulkwritecommand/bulkwritecommand-ctor-ordered-002.phpt +++ b/tests/bulkwritecommand/bulkwritecommand-ctor-ordered-002.phpt @@ -23,6 +23,7 @@ try { printf("%s(%d): %s\n", get_class($e), $e->getCode(), $e->getMessage()); var_dump($e->getPartialResult()); var_dump($e->getWriteErrors()); + var_dump($e->getWriteConcernErrors()); } ?> @@ -64,4 +65,6 @@ array(1) { } } } +array(0) { +} ===DONE=== diff --git a/tests/command/command-ctor_error-002.phpt b/tests/command/command-ctor_error-002.phpt new file mode 100644 index 000000000..f133145c5 --- /dev/null +++ b/tests/command/command-ctor_error-002.phpt @@ -0,0 +1,18 @@ +--TEST-- +MongoDB\Driver\Command construction (invalid maxAwaitTimeMS range) +--FILE-- + 1], ['maxAwaitTimeMS' => -1]); +}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; + +?> +===DONE=== + +--EXPECT-- +OK: Got MongoDB\Driver\Exception\InvalidArgumentException +Expected "maxAwaitTimeMS" option to be >= 0, -1 given +===DONE=== diff --git a/tests/exception/connectiontimeoutexception-haserrorlabel-001.phpt b/tests/exception/connectiontimeoutexception-haserrorlabel-001.phpt new file mode 100644 index 000000000..0da38c822 --- /dev/null +++ b/tests/exception/connectiontimeoutexception-haserrorlabel-001.phpt @@ -0,0 +1,22 @@ +--TEST-- +MongoDB\Driver\Exception\ConnectionTimeoutException::hasErrorLabel() +--FILE-- +getProperty('errorLabels'); +$errorLabelsProperty->setValue($exception, $labels); + +var_dump($exception->hasErrorLabel('foo')); +var_dump($exception->hasErrorLabel('bar')); + +?> +===DONE=== + +--EXPECT-- +bool(true) +bool(false) +===DONE=== diff --git a/tests/exception/executiontimeoutexception-haserrorlabel-001.phpt b/tests/exception/executiontimeoutexception-haserrorlabel-001.phpt new file mode 100644 index 000000000..fd7d93c79 --- /dev/null +++ b/tests/exception/executiontimeoutexception-haserrorlabel-001.phpt @@ -0,0 +1,22 @@ +--TEST-- +MongoDB\Driver\Exception\ExecutionTimeoutException::hasErrorLabel() +--FILE-- +getProperty('errorLabels'); +$errorLabelsProperty->setValue($exception, $labels); + +var_dump($exception->hasErrorLabel('foo')); +var_dump($exception->hasErrorLabel('bar')); + +?> +===DONE=== + +--EXPECT-- +bool(true) +bool(false) +===DONE=== diff --git a/tests/query/query-ctor-maxAwaitTimeMS-001.phpt b/tests/query/query-ctor-maxAwaitTimeMS-001.phpt new file mode 100644 index 000000000..6a4039fb0 --- /dev/null +++ b/tests/query/query-ctor-maxAwaitTimeMS-001.phpt @@ -0,0 +1,18 @@ +--TEST-- +MongoDB\Driver\Query construction with maxAwaitTimeMS option +--FILE-- + 0]); +echo "maxAwaitTimeMS=0: OK\n"; + +$q = new MongoDB\Driver\Query([], ['maxAwaitTimeMS' => 1000]); +echo "maxAwaitTimeMS=1000: OK\n"; + +?> +===DONE=== + +--EXPECT-- +maxAwaitTimeMS=0: OK +maxAwaitTimeMS=1000: OK +===DONE=== diff --git a/tests/query/query-ctor-maxAwaitTimeMS-002.phpt b/tests/query/query-ctor-maxAwaitTimeMS-002.phpt new file mode 100644 index 000000000..427c46eb6 --- /dev/null +++ b/tests/query/query-ctor-maxAwaitTimeMS-002.phpt @@ -0,0 +1,16 @@ +--TEST-- +MongoDB\Driver\Query construction with maxAwaitTimeMS option (64-bit) +--SKIPIF-- + +--FILE-- + 4294967295]); +echo "maxAwaitTimeMS=4294967295: OK\n"; + +?> +===DONE=== + +--EXPECT-- +maxAwaitTimeMS=4294967295: OK +===DONE=== diff --git a/tests/session/session-getServer-001.phpt b/tests/session/session-getServer-001.phpt new file mode 100644 index 000000000..77c39c6ff --- /dev/null +++ b/tests/session/session-getServer-001.phpt @@ -0,0 +1,23 @@ +--TEST-- +MongoDB\Driver\Session::getServer() +--SKIPIF-- + + + +--FILE-- +startSession(); + +/* Session::getServer() currently returns null, as sessions are not pinned + * to a server. */ +var_dump($session->getServer()); + +?> +===DONE=== + +--EXPECT-- +NULL +===DONE=== diff --git a/tests/session/session-getTransactionOptions-001.phpt b/tests/session/session-getTransactionOptions-001.phpt index b1ad1d1c8..2a09079d5 100644 --- a/tests/session/session-getTransactionOptions-001.phpt +++ b/tests/session/session-getTransactionOptions-001.phpt @@ -19,6 +19,12 @@ $options = [ ['readConcern' => new \MongoDB\Driver\ReadConcern('majority')], ['readPreference' => new \MongoDB\Driver\ReadPreference('primaryPreferred')], ['writeConcern' => new \MongoDB\Driver\WriteConcern('majority')], + [ + 'maxCommitTimeMS' => 5000, + 'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::MAJORITY), + 'readPreference' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::PRIMARY), + 'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY), + ], ]; foreach ($options as $test) { @@ -82,4 +88,23 @@ array(2) { string(8) "majority" } } +array(4) { + ["maxCommitTimeMS"]=> + int(5000) + ["readConcern"]=> + object(MongoDB\Driver\ReadConcern)#%d (1) { + ["level"]=> + string(8) "majority" + } + ["readPreference"]=> + object(MongoDB\Driver\ReadPreference)#%d (1) { + ["mode"]=> + string(7) "primary" + } + ["writeConcern"]=> + object(MongoDB\Driver\WriteConcern)#%d (1) { + ["w"]=> + string(8) "majority" + } +} ===DONE===