1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
--TEST--
PHPC-1152: Command cursors should use the same session for getMore and killCursors (explicit)
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_libmongoc_crypto(); ?>
<?php skip_if_not_live(); ?>
<?php skip_if_not_clean(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";
class Test implements MongoDB\Driver\Monitoring\CommandSubscriber
{
private $lsidByCursorId = [];
private $lsidByRequestId = [];
public function executeCommand()
{
$manager = create_test_manager();
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert(['_id' => 1]);
$bulk->insert(['_id' => 2]);
$bulk->insert(['_id' => 3]);
$manager->executeBulkWrite(NS, $bulk);
$command = new MongoDB\Driver\Command([
'aggregate' => COLLECTION_NAME,
'pipeline' => [['$match' => new stdClass]],
'cursor' => ['batchSize' => 2],
]);
$session = $manager->startSession();
MongoDB\Driver\Monitoring\addSubscriber($this);
/* This uses the same sequencing as the implicit session test; however,
* we should expect all commands (aggregate, getMore, and killCursors)
* to use the same explicit session ID. */
$cursor = $manager->executeCommand(DATABASE_NAME, $command, ['session' => $session]);
$cursor->toArray();
$cursor = $manager->executeCommand(DATABASE_NAME, $command, ['session' => $session]);
$cursor->toArray();
$cursor = $manager->executeCommand(DATABASE_NAME, $command, ['session' => $session]);
$cursor = $manager->executeCommand(DATABASE_NAME, $command, ['session' => $session]);
unset($cursor);
MongoDB\Driver\Monitoring\removeSubscriber($this);
/* We should expect one unique session ID over the course of the test,
* since all commands used the same explicit session. */
printf("Unique session IDs used: %d\n", count(array_unique($this->lsidByRequestId)));
}
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event): void
{
$requestId = $event->getRequestId();
$sessionId = bin2hex((string) $event->getCommand()->lsid->id);
printf("%s session ID: %s\n", $event->getCommandName(), $sessionId);
if ($event->getCommandName() === 'aggregate') {
if (isset($this->lsidByRequestId[$requestId])) {
throw new UnexpectedValueException('Previous command observed for request ID: ' . $requestId);
}
$this->lsidByRequestId[$requestId] = $sessionId;
}
if ($event->getCommandName() === 'getMore') {
$cursorId = (string) $event->getCommand()->getMore;
if ( ! isset($this->lsidByCursorId[$cursorId])) {
throw new UnexpectedValueException('No previous command observed for cursor ID: ' . $cursorId);
}
printf("getMore used same session as aggregate: %s\n", $sessionId === $this->lsidByCursorId[$cursorId] ? 'yes' : 'no');
}
if ($event->getCommandName() === 'killCursors') {
$cursorId = (string) $event->getCommand()->cursors[0];
if ( ! isset($this->lsidByCursorId[$cursorId])) {
throw new UnexpectedValueException('No previous command observed for cursor ID: ' . $cursorId);
}
printf("killCursors used same session as aggregate: %s\n", $sessionId === $this->lsidByCursorId[$cursorId] ? 'yes' : 'no');
}
}
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event): void
{
/* Associate the aggregate's session ID with its cursor ID so it can be
* looked up by the subsequent getMore or killCursors */
if ($event->getCommandName() === 'aggregate') {
$cursorId = (string) $event->getReply()->cursor->id;
$requestId = $event->getRequestId();
$this->lsidByCursorId[$cursorId] = $this->lsidByRequestId[$requestId];
}
}
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event): void
{
}
}
(new Test)->executeCommand();
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
aggregate session ID: %x
getMore session ID: %x
getMore used same session as aggregate: yes
aggregate session ID: %x
getMore session ID: %x
getMore used same session as aggregate: yes
aggregate session ID: %x
aggregate session ID: %x
killCursors session ID: %x
killCursors used same session as aggregate: yes
killCursors session ID: %x
killCursors used same session as aggregate: yes
Unique session IDs used: 1
===DONE===
|