Skip to content

Commit e1b68f5

Browse files
committed
PHPC-987: Causal consistency spec tests
1 parent 939e96b commit e1b68f5

10 files changed

+656
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Causal consistency: new session has no operation time
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php NEEDS('REPLICASET'); ?>
6+
--FILE--
7+
<?php
8+
require_once __DIR__ . "/../utils/basic.inc";
9+
10+
$manager = new MongoDB\Driver\Manager(REPLICASET);
11+
$session = $manager->startSession();
12+
13+
echo "Initial operation time:\n";
14+
var_dump($session->getOperationTime());
15+
16+
?>
17+
===DONE===
18+
<?php exit(0); ?>
19+
--EXPECT--
20+
Initial operation time:
21+
NULL
22+
===DONE===
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
Causal consistency: first read in session does not include afterClusterTime
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php NEEDS('REPLICASET'); ?>
6+
--FILE--
7+
<?php
8+
require_once __DIR__ . "/../utils/basic.inc";
9+
require_once __DIR__ . "/../utils/observer.php";
10+
11+
(new CommandObserver)->observe(
12+
function() {
13+
$manager = new MongoDB\Driver\Manager(REPLICASET);
14+
$session = $manager->startSession();
15+
16+
$query = new MongoDB\Driver\Query([]);
17+
$manager->executeQuery(NS, $query, ['session' => $session]);
18+
},
19+
function(stdClass $command)
20+
{
21+
$hasAfterClusterTime = isset($command->readConcern->afterClusterTime);
22+
printf("Read includes afterClusterTime: %s\n", ($hasAfterClusterTime ? 'yes' : 'no'));
23+
}
24+
);
25+
26+
?>
27+
===DONE===
28+
<?php exit(0); ?>
29+
--EXPECT--
30+
Read includes afterClusterTime: no
31+
===DONE===
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
--TEST--
2+
Causal consistency: first read or write in session updates operationTime
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php NEEDS('REPLICASET'); CLEANUP(REPLICASET); ?>
6+
--FILE--
7+
<?php
8+
require_once __DIR__ . "/../utils/basic.inc";
9+
10+
class Test implements MongoDB\Driver\Monitoring\CommandSubscriber
11+
{
12+
private $lastSeenOperationTime;
13+
14+
public function executeBulkWrite()
15+
{
16+
$this->lastSeenOperationTime = null;
17+
18+
MongoDB\Driver\Monitoring\addSubscriber($this);
19+
20+
$manager = new MongoDB\Driver\Manager(REPLICASET);
21+
$session = $manager->startSession();
22+
23+
$bulk = new MongoDB\Driver\BulkWrite;
24+
$bulk->insert(['x' => 1]);
25+
$manager->executeBulkWrite(NS, $bulk, ['session' => $session]);
26+
27+
printf("Session reports last seen operationTime: %s\n", ($session->getOperationTime() == $this->lastSeenOperationTime) ? 'yes' : 'no');
28+
29+
MongoDB\Driver\Monitoring\removeSubscriber($this);
30+
}
31+
32+
public function executeCommand()
33+
{
34+
$this->lastSeenOperationTime = null;
35+
36+
MongoDB\Driver\Monitoring\addSubscriber($this);
37+
38+
$manager = new MongoDB\Driver\Manager(REPLICASET);
39+
$session = $manager->startSession();
40+
41+
$command = new MongoDB\Driver\Command(['ping' => 1]);
42+
$manager->executeCommand(DATABASE_NAME, $command, ['session' => $session]);
43+
44+
printf("Session reports last seen operationTime: %s\n", ($session->getOperationTime() == $this->lastSeenOperationTime) ? 'yes' : 'no');
45+
46+
MongoDB\Driver\Monitoring\removeSubscriber($this);
47+
}
48+
49+
public function executeQuery()
50+
{
51+
$this->lastSeenOperationTime = null;
52+
53+
MongoDB\Driver\Monitoring\addSubscriber($this);
54+
55+
$manager = new MongoDB\Driver\Manager(REPLICASET);
56+
$session = $manager->startSession();
57+
58+
$query = new MongoDB\Driver\Query([]);
59+
$manager->executeQuery(NS, $query, ['session' => $session]);
60+
61+
printf("Session reports last seen operationTime: %s\n", ($session->getOperationTime() == $this->lastSeenOperationTime) ? 'yes' : 'no');
62+
63+
MongoDB\Driver\Monitoring\removeSubscriber($this);
64+
}
65+
66+
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
67+
{
68+
}
69+
70+
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
71+
{
72+
$reply = $event->getReply();
73+
$hasOperationTime = isset($reply->{'operationTime'});
74+
75+
printf("%s command reply includes operationTime: %s\n", $event->getCommandName(), $hasOperationTime ? 'yes' : 'no');
76+
77+
if ($hasOperationTime) {
78+
$this->lastSeenOperationTime = $reply->operationTime;
79+
}
80+
}
81+
82+
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
83+
{
84+
}
85+
}
86+
87+
echo "Testing executeBulkWrite()\n";
88+
(new Test)->executeBulkWrite();
89+
90+
echo "\nTesting executeCommand()\n";
91+
(new Test)->executeCommand();
92+
93+
echo "\nTesting executeQuery()\n";
94+
(new Test)->executeQuery();
95+
96+
?>
97+
===DONE===
98+
<?php exit(0); ?>
99+
--EXPECT--
100+
Testing executeBulkWrite()
101+
insert command reply includes operationTime: yes
102+
Session reports last seen operationTime: yes
103+
104+
Testing executeCommand()
105+
ping command reply includes operationTime: yes
106+
Session reports last seen operationTime: yes
107+
108+
Testing executeQuery()
109+
find command reply includes operationTime: yes
110+
Session reports last seen operationTime: yes
111+
===DONE===
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
--TEST--
2+
Causal consistency: first read or write in session updates operationTime (even on error)
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php NEEDS('REPLICASET'); CLEANUP(REPLICASET); ?>
6+
--FILE--
7+
<?php
8+
require_once __DIR__ . "/../utils/basic.inc";
9+
10+
class Test implements MongoDB\Driver\Monitoring\CommandSubscriber
11+
{
12+
private $lastSeenOperationTime;
13+
14+
public function executeBulkWrite()
15+
{
16+
$this->lastSeenOperationTime = null;
17+
18+
MongoDB\Driver\Monitoring\addSubscriber($this);
19+
20+
$manager = new MongoDB\Driver\Manager(REPLICASET);
21+
$session = $manager->startSession();
22+
23+
$bulk = new MongoDB\Driver\BulkWrite;
24+
$bulk->insert(['_id' => 1]);
25+
$bulk->insert(['_id' => 1]);
26+
27+
throws(function() use ($manager, $bulk, $session) {
28+
$manager->executeBulkWrite(NS, $bulk, ['session' => $session]);
29+
}, 'MongoDB\Driver\Exception\BulkWriteException');
30+
31+
printf("Session reports last seen operationTime: %s\n", ($session->getOperationTime() == $this->lastSeenOperationTime) ? 'yes' : 'no');
32+
33+
MongoDB\Driver\Monitoring\removeSubscriber($this);
34+
}
35+
36+
public function executeCommand()
37+
{
38+
$this->lastSeenOperationTime = null;
39+
40+
MongoDB\Driver\Monitoring\addSubscriber($this);
41+
42+
$manager = new MongoDB\Driver\Manager(REPLICASET);
43+
$session = $manager->startSession();
44+
45+
$command = new MongoDB\Driver\Command([
46+
'aggregate' => COLLECTION_NAME,
47+
'pipeline' => [
48+
['$unsupportedOperator' => 1],
49+
],
50+
'cursor' => new stdClass,
51+
]);
52+
53+
throws(function() use ($manager, $command, $session) {
54+
$manager->executeCommand(DATABASE_NAME, $command, ['session' => $session]);
55+
}, 'MongoDB\Driver\Exception\RuntimeException');
56+
57+
/* We cannot access the server reply if an exception is thrown for a
58+
* failed command (see: PHPC-1076). For the time being, just assert that
59+
* the operationTime is not null. */
60+
printf("Session has non-null operationTime: %s\n", ($session->getOperationTime() !== null ? 'yes' : 'no'));
61+
62+
MongoDB\Driver\Monitoring\removeSubscriber($this);
63+
}
64+
65+
public function executeQuery()
66+
{
67+
$this->lastSeenOperationTime = null;
68+
69+
MongoDB\Driver\Monitoring\addSubscriber($this);
70+
71+
$manager = new MongoDB\Driver\Manager(REPLICASET);
72+
$session = $manager->startSession();
73+
74+
$query = new MongoDB\Driver\Query(['$unsupportedOperator' => 1]);
75+
76+
throws(function() use ($manager, $query, $session) {
77+
$manager->executeQuery(NS, $query, ['session' => $session]);
78+
}, 'MongoDB\Driver\Exception\RuntimeException');
79+
80+
/* We cannot access the server reply if an exception is thrown for a
81+
* failed command (see: PHPC-1076). For the time being, just assert that
82+
* the operationTime is not null. */
83+
printf("Session has non-null operationTime: %s\n", ($session->getOperationTime() !== null ? 'yes' : 'no'));
84+
85+
MongoDB\Driver\Monitoring\removeSubscriber($this);
86+
}
87+
88+
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
89+
{
90+
}
91+
92+
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
93+
{
94+
$reply = $event->getReply();
95+
$hasOperationTime = isset($reply->operationTime);
96+
97+
printf("%s command reply includes operationTime: %s\n", $event->getCommandName(), $hasOperationTime ? 'yes' : 'no');
98+
99+
if ($hasOperationTime) {
100+
$this->lastSeenOperationTime = $reply->operationTime;
101+
}
102+
}
103+
104+
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
105+
{
106+
}
107+
}
108+
109+
echo "Testing executeBulkWrite()\n";
110+
(new Test)->executeBulkWrite();
111+
112+
echo "\nTesting executeCommand()\n";
113+
(new Test)->executeCommand();
114+
115+
echo "\nTesting executeQuery()\n";
116+
(new Test)->executeQuery();
117+
118+
?>
119+
===DONE===
120+
<?php exit(0); ?>
121+
--EXPECT--
122+
Testing executeBulkWrite()
123+
insert command reply includes operationTime: yes
124+
OK: Got MongoDB\Driver\Exception\BulkWriteException
125+
Session reports last seen operationTime: yes
126+
127+
Testing executeCommand()
128+
OK: Got MongoDB\Driver\Exception\RuntimeException
129+
Session has non-null operationTime: yes
130+
131+
Testing executeQuery()
132+
OK: Got MongoDB\Driver\Exception\RuntimeException
133+
Session has non-null operationTime: yes
134+
===DONE===

0 commit comments

Comments
 (0)