Skip to content

Commit bfb5fb9

Browse files
authored
Add tests to improve coverage of untested or under-tested APIs (#1975)
* 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
1 parent 3fe80e4 commit bfb5fb9

9 files changed

Lines changed: 207 additions & 0 deletions
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
MongoDB\Driver\BulkWriteCommand::__construct() multiple options combined
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php skip_if_not_live(); ?>
6+
<?php skip_if_server_version('<', '8.0'); ?>
7+
<?php skip_if_not_clean(); ?>
8+
--FILE--
9+
<?php
10+
11+
require_once __DIR__ . "/../utils/basic.inc";
12+
13+
class CommandLogger implements MongoDB\Driver\Monitoring\CommandSubscriber
14+
{
15+
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event): void
16+
{
17+
if ($event->getCommandName() !== 'bulkWrite') {
18+
return;
19+
}
20+
21+
$command = $event->getCommand();
22+
23+
printf("ordered: %s\n", var_export($command->ordered, true));
24+
printf("comment: %s\n", json_encode($command->comment));
25+
}
26+
27+
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event): void
28+
{
29+
}
30+
31+
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event): void
32+
{
33+
}
34+
}
35+
36+
$manager = create_test_manager();
37+
38+
$bulk = new MongoDB\Driver\BulkWriteCommand([
39+
'ordered' => false,
40+
'comment' => 'test comment',
41+
'verboseResults' => true,
42+
]);
43+
$bulk->insertOne(NS, ['_id' => 1]);
44+
$bulk->insertOne(NS, ['_id' => 2]);
45+
46+
$manager->addSubscriber(new CommandLogger);
47+
$result = $manager->executeBulkWriteCommand($bulk);
48+
49+
var_dump($result->getInsertedCount());
50+
var_dump($result->getInsertResults() !== null);
51+
52+
?>
53+
===DONE===
54+
<?php exit(0); ?>
55+
--EXPECT--
56+
ordered: false
57+
comment: "test comment"
58+
int(2)
59+
bool(true)
60+
===DONE===

tests/bulkwritecommand/bulkwritecommand-ctor-ordered-002.phpt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ try {
2323
printf("%s(%d): %s\n", get_class($e), $e->getCode(), $e->getMessage());
2424
var_dump($e->getPartialResult());
2525
var_dump($e->getWriteErrors());
26+
var_dump($e->getWriteConcernErrors());
2627
}
2728

2829
?>
@@ -64,4 +65,6 @@ array(1) {
6465
}
6566
}
6667
}
68+
array(0) {
69+
}
6770
===DONE===
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
MongoDB\Driver\Command construction (invalid maxAwaitTimeMS range)
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/basic.inc';
7+
8+
echo throws(function() {
9+
new MongoDB\Driver\Command(['ping' => 1], ['maxAwaitTimeMS' => -1]);
10+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
11+
12+
?>
13+
===DONE===
14+
<?php exit(0); ?>
15+
--EXPECT--
16+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
17+
Expected "maxAwaitTimeMS" option to be >= 0, -1 given
18+
===DONE===
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
MongoDB\Driver\Exception\ConnectionTimeoutException::hasErrorLabel()
3+
--FILE--
4+
<?php
5+
6+
$exception = new MongoDB\Driver\Exception\ConnectionTimeoutException();
7+
$labels = ['test', 'foo'];
8+
9+
$reflection = new ReflectionClass($exception);
10+
$errorLabelsProperty = $reflection->getProperty('errorLabels');
11+
$errorLabelsProperty->setValue($exception, $labels);
12+
13+
var_dump($exception->hasErrorLabel('foo'));
14+
var_dump($exception->hasErrorLabel('bar'));
15+
16+
?>
17+
===DONE===
18+
<?php exit(0); ?>
19+
--EXPECT--
20+
bool(true)
21+
bool(false)
22+
===DONE===
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
MongoDB\Driver\Exception\ExecutionTimeoutException::hasErrorLabel()
3+
--FILE--
4+
<?php
5+
6+
$exception = new MongoDB\Driver\Exception\ExecutionTimeoutException();
7+
$labels = ['test', 'foo'];
8+
9+
$reflection = new ReflectionClass($exception);
10+
$errorLabelsProperty = $reflection->getProperty('errorLabels');
11+
$errorLabelsProperty->setValue($exception, $labels);
12+
13+
var_dump($exception->hasErrorLabel('foo'));
14+
var_dump($exception->hasErrorLabel('bar'));
15+
16+
?>
17+
===DONE===
18+
<?php exit(0); ?>
19+
--EXPECT--
20+
bool(true)
21+
bool(false)
22+
===DONE===
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
MongoDB\Driver\Query construction with maxAwaitTimeMS option
3+
--FILE--
4+
<?php
5+
6+
$q = new MongoDB\Driver\Query([], ['maxAwaitTimeMS' => 0]);
7+
echo "maxAwaitTimeMS=0: OK\n";
8+
9+
$q = new MongoDB\Driver\Query([], ['maxAwaitTimeMS' => 1000]);
10+
echo "maxAwaitTimeMS=1000: OK\n";
11+
12+
?>
13+
===DONE===
14+
<?php exit(0); ?>
15+
--EXPECT--
16+
maxAwaitTimeMS=0: OK
17+
maxAwaitTimeMS=1000: OK
18+
===DONE===
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
MongoDB\Driver\Query construction with maxAwaitTimeMS option (64-bit)
3+
--SKIPIF--
4+
<?php if (8 !== PHP_INT_SIZE) { die('skip Only for 64-bit platform'); } ?>
5+
--FILE--
6+
<?php
7+
8+
$q = new MongoDB\Driver\Query([], ['maxAwaitTimeMS' => 4294967295]);
9+
echo "maxAwaitTimeMS=4294967295: OK\n";
10+
11+
?>
12+
===DONE===
13+
<?php exit(0); ?>
14+
--EXPECT--
15+
maxAwaitTimeMS=4294967295: OK
16+
===DONE===
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
MongoDB\Driver\Session::getServer()
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php skip_if_not_libmongoc_crypto(); ?>
6+
<?php skip_if_not_live(); ?>
7+
--FILE--
8+
<?php
9+
require_once __DIR__ . "/../utils/basic.inc";
10+
11+
$manager = create_test_manager();
12+
$session = $manager->startSession();
13+
14+
/* Session::getServer() currently returns null, as sessions are not pinned
15+
* to a server. */
16+
var_dump($session->getServer());
17+
18+
?>
19+
===DONE===
20+
<?php exit(0); ?>
21+
--EXPECT--
22+
NULL
23+
===DONE===

tests/session/session-getTransactionOptions-001.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ $options = [
1919
['readConcern' => new \MongoDB\Driver\ReadConcern('majority')],
2020
['readPreference' => new \MongoDB\Driver\ReadPreference('primaryPreferred')],
2121
['writeConcern' => new \MongoDB\Driver\WriteConcern('majority')],
22+
[
23+
'maxCommitTimeMS' => 5000,
24+
'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::MAJORITY),
25+
'readPreference' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::PRIMARY),
26+
'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY),
27+
],
2228
];
2329

2430
foreach ($options as $test) {
@@ -82,4 +88,23 @@ array(2) {
8288
string(8) "majority"
8389
}
8490
}
91+
array(4) {
92+
["maxCommitTimeMS"]=>
93+
int(5000)
94+
["readConcern"]=>
95+
object(MongoDB\Driver\ReadConcern)#%d (1) {
96+
["level"]=>
97+
string(8) "majority"
98+
}
99+
["readPreference"]=>
100+
object(MongoDB\Driver\ReadPreference)#%d (1) {
101+
["mode"]=>
102+
string(7) "primary"
103+
}
104+
["writeConcern"]=>
105+
object(MongoDB\Driver\WriteConcern)#%d (1) {
106+
["w"]=>
107+
string(8) "majority"
108+
}
109+
}
85110
===DONE===

0 commit comments

Comments
 (0)