Unverified Commit 7b084d30 authored by Andreas Braun's avatar Andreas Braun

Merge pull request #729

* phplib-537:
  PHPLIB-537: Skip change stream tests on single node clusters
  PHPLIB-537: Allow more iterations for change stream spec tests on sharded clusters
  PHPLIB-537: "Cursor not found" error is no longer resumable
  PHPLIB-537: Use whitelist to check if a change stream is resumable
parents 9fa37e73 b26a7a35
...@@ -42,13 +42,31 @@ class ChangeStream implements Iterator ...@@ -42,13 +42,31 @@ class ChangeStream implements Iterator
*/ */
const CURSOR_NOT_FOUND = 43; const CURSOR_NOT_FOUND = 43;
/** @var array */ /** @var int[] */
private static $nonResumableErrorCodes = [ private static $resumableErrorCodes = [
136, // CappedPositionLost 6, // HostUnreachable
237, // CursorKilled 7, // HostNotFound
11601, // Interrupted 89, // NetworkTimeout
91, // ShutdownInProgress
189, // PrimarySteppedDown
262, // ExceededTimeLimit
9001, // SocketException
10107, // NotMaster
11600, // InterruptedAtShutdown
11602, // InterruptedDueToReplStateChange
13435, // NotMasterNoSlaveOk
13436, // NotMasterOrSecondary
63, // StaleShardVersion
150, // StaleEpoch
13388, // StaleConfig
234, // RetryChangeStream
133, // FailedToSatisfyReadPreference
216, // ElectionInProgress
]; ];
/** @var int */
private static $wireVersionForResumableChangeStreamError = 9;
/** @var callable */ /** @var callable */
private $resumeCallable; private $resumeCallable;
...@@ -180,15 +198,11 @@ class ChangeStream implements Iterator ...@@ -180,15 +198,11 @@ class ChangeStream implements Iterator
return false; return false;
} }
if ($exception->hasErrorLabel('NonResumableChangeStreamError')) { if (server_supports_feature($this->iterator->getServer(), self::$wireVersionForResumableChangeStreamError)) {
return false; return $exception->hasErrorLabel('ResumableChangeStreamError');
}
if (in_array($exception->getCode(), self::$nonResumableErrorCodes)) {
return false;
} }
return true; return in_array($exception->getCode(), self::$resumableErrorCodes);
} }
/** /**
......
...@@ -24,6 +24,7 @@ use MongoDB\Driver\Monitoring\CommandFailedEvent; ...@@ -24,6 +24,7 @@ use MongoDB\Driver\Monitoring\CommandFailedEvent;
use MongoDB\Driver\Monitoring\CommandStartedEvent; use MongoDB\Driver\Monitoring\CommandStartedEvent;
use MongoDB\Driver\Monitoring\CommandSubscriber; use MongoDB\Driver\Monitoring\CommandSubscriber;
use MongoDB\Driver\Monitoring\CommandSucceededEvent; use MongoDB\Driver\Monitoring\CommandSucceededEvent;
use MongoDB\Driver\Server;
use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\ResumeTokenException; use MongoDB\Exception\ResumeTokenException;
use MongoDB\Exception\UnexpectedValueException; use MongoDB\Exception\UnexpectedValueException;
...@@ -63,6 +64,9 @@ class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber ...@@ -63,6 +64,9 @@ class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber
/** @var array|object|null */ /** @var array|object|null */
private $resumeToken; private $resumeToken;
/** @var Server */
private $server;
/** /**
* @internal * @internal
* @param Cursor $cursor * @param Cursor $cursor
...@@ -90,6 +94,7 @@ class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber ...@@ -90,6 +94,7 @@ class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber
$this->isRewindNop = ($firstBatchSize === 0); $this->isRewindNop = ($firstBatchSize === 0);
$this->postBatchResumeToken = $postBatchResumeToken; $this->postBatchResumeToken = $postBatchResumeToken;
$this->resumeToken = $initialResumeToken; $this->resumeToken = $initialResumeToken;
$this->server = $cursor->getServer();
} }
/** @internal */ /** @internal */
...@@ -152,6 +157,14 @@ class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber ...@@ -152,6 +157,14 @@ class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber
return $this->resumeToken; return $this->resumeToken;
} }
/**
* Returns the server the cursor is running on.
*/
public function getServer() : Server
{
return $this->server;
}
/** /**
* @see https://php.net/iteratoriterator.key * @see https://php.net/iteratoriterator.key
* @return mixed * @return mixed
......
...@@ -16,7 +16,6 @@ use MongoDB\Driver\Monitoring\CommandSucceededEvent; ...@@ -16,7 +16,6 @@ use MongoDB\Driver\Monitoring\CommandSucceededEvent;
use MongoDB\Driver\ReadPreference; use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Exception\ResumeTokenException; use MongoDB\Exception\ResumeTokenException;
use MongoDB\Operation\DatabaseCommand;
use MongoDB\Operation\InsertOne; use MongoDB\Operation\InsertOne;
use MongoDB\Operation\Watch; use MongoDB\Operation\Watch;
use MongoDB\Tests\CommandObserver; use MongoDB\Tests\CommandObserver;
...@@ -155,49 +154,6 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -155,49 +154,6 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->assertSameDocument($postBatchResumeToken, $changeStream->getResumeToken()); $this->assertSameDocument($postBatchResumeToken, $changeStream->getResumeToken());
} }
/**
* Prose test 10: "ChangeStream will resume after a killCursors command is
* issued for its child cursor."
*/
public function testNextResumesAfterCursorNotFound()
{
$operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
$changeStream = $operation->execute($this->getPrimaryServer());
$changeStream->rewind();
$this->assertFalse($changeStream->valid());
$this->insertDocument(['_id' => 1, 'x' => 'foo']);
$this->advanceCursorUntilValid($changeStream);
$expectedResult = [
'_id' => $changeStream->current()->_id,
'operationType' => 'insert',
'fullDocument' => ['_id' => 1, 'x' => 'foo'],
'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
'documentKey' => ['_id' => 1],
];
$this->assertMatchesDocument($expectedResult, $changeStream->current());
$this->killChangeStreamCursor($changeStream);
$this->insertDocument(['_id' => 2, 'x' => 'bar']);
$this->advanceCursorUntilValid($changeStream);
$expectedResult = [
'_id' => $changeStream->current()->_id,
'operationType' => 'insert',
'fullDocument' => ['_id' => 2, 'x' => 'bar'],
'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
'documentKey' => ['_id' => 2],
];
$this->assertMatchesDocument($expectedResult, $changeStream->current());
}
public function testNextResumesAfterConnectionException() public function testNextResumesAfterConnectionException()
{ {
/* In order to trigger a dropped connection, we'll use a new client with /* In order to trigger a dropped connection, we'll use a new client with
...@@ -267,7 +223,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -267,7 +223,7 @@ class WatchFunctionalTest extends FunctionalTestCase
$postBatchResumeToken = $this->getPostBatchResumeTokenFromReply($events[0]['succeeded']->getReply()); $postBatchResumeToken = $this->getPostBatchResumeTokenFromReply($events[0]['succeeded']->getReply());
$this->assertFalse($changeStream->valid()); $this->assertFalse($changeStream->valid());
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$this->assertNoCommandExecuted(function () use ($changeStream) { $this->assertNoCommandExecuted(function () use ($changeStream) {
$changeStream->rewind(); $changeStream->rewind();
...@@ -346,7 +302,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -346,7 +302,7 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->assertInstanceOf(TimestampInterface::class, $operationTime); $this->assertInstanceOf(TimestampInterface::class, $operationTime);
$this->assertFalse($changeStream->valid()); $this->assertFalse($changeStream->valid());
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$this->assertNoCommandExecuted(function () use ($changeStream) { $this->assertNoCommandExecuted(function () use ($changeStream) {
$changeStream->rewind(); $changeStream->rewind();
...@@ -497,7 +453,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -497,7 +453,7 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->assertMatchesDocument($expectedResult, $changeStream->current()); $this->assertMatchesDocument($expectedResult, $changeStream->current());
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$changeStream->next(); $changeStream->next();
$this->assertFalse($changeStream->valid()); $this->assertFalse($changeStream->valid());
...@@ -524,10 +480,10 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -524,10 +480,10 @@ class WatchFunctionalTest extends FunctionalTestCase
$operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions); $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
$changeStream = $operation->execute($this->getPrimaryServer()); $changeStream = $operation->execute($this->getPrimaryServer());
/* Killing the cursor when there are no results will test that neither /* Forcing a resume when there are no results will test that neither
* the initial rewind() nor a resume attempt via next() increment the * the initial rewind() nor a resume attempt via next() increment the
* key. */ * key. */
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$this->assertNoCommandExecuted(function () use ($changeStream) { $this->assertNoCommandExecuted(function () use ($changeStream) {
$changeStream->rewind(); $changeStream->rewind();
...@@ -542,7 +498,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -542,7 +498,7 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->assertNull($changeStream->current()); $this->assertNull($changeStream->current());
// A consecutive resume attempt should still not increment the key // A consecutive resume attempt should still not increment the key
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$changeStream->next(); $changeStream->next();
$this->assertFalse($changeStream->valid()); $this->assertFalse($changeStream->valid());
...@@ -568,10 +524,10 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -568,10 +524,10 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->assertMatchesDocument($expectedResult, $changeStream->current()); $this->assertMatchesDocument($expectedResult, $changeStream->current());
/* Insert another document and kill the cursor. ChangeStream::next() /* Insert another document and force a resume. ChangeStream::next()
* should resume and pick up the last insert. */ * should resume and pick up the last insert. */
$this->insertDocument(['_id' => 2]); $this->insertDocument(['_id' => 2]);
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$changeStream->next(); $changeStream->next();
$this->assertTrue($changeStream->valid()); $this->assertTrue($changeStream->valid());
...@@ -595,7 +551,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -595,7 +551,7 @@ class WatchFunctionalTest extends FunctionalTestCase
* *
* Note: PHPLIB-448 may require rewind() to throw an exception here. */ * Note: PHPLIB-448 may require rewind() to throw an exception here. */
$this->insertDocument(['_id' => 3]); $this->insertDocument(['_id' => 3]);
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$this->assertNoCommandExecuted(function () use ($changeStream) { $this->assertNoCommandExecuted(function () use ($changeStream) {
$changeStream->rewind(); $changeStream->rewind();
...@@ -621,7 +577,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -621,7 +577,7 @@ class WatchFunctionalTest extends FunctionalTestCase
// Test one final, consecutive resume via ChangeStream::next() // Test one final, consecutive resume via ChangeStream::next()
$this->insertDocument(['_id' => 4]); $this->insertDocument(['_id' => 4]);
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$changeStream->next(); $changeStream->next();
$this->assertTrue($changeStream->valid()); $this->assertTrue($changeStream->valid());
...@@ -665,7 +621,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -665,7 +621,7 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->assertFalse($changeStream->valid()); $this->assertFalse($changeStream->valid());
$this->assertNull($changeStream->key()); $this->assertNull($changeStream->key());
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$changeStream->next(); $changeStream->next();
$this->assertFalse($changeStream->valid()); $this->assertFalse($changeStream->valid());
...@@ -731,41 +687,6 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -731,41 +687,6 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->assertFalse($cursor->isDead()); $this->assertFalse($cursor->isDead());
} }
/**
* Prose test 5: "ChangeStream will not attempt to resume after encountering
* error code 11601 (Interrupted), 136 (CappedPositionLost), or 237
* (CursorKilled) while executing a getMore command."
*
* @dataProvider provideNonResumableErrorCodes
*/
public function testNonResumableErrorCodes($errorCode)
{
$this->configureFailPoint([
'configureFailPoint' => 'failCommand',
'mode' => ['times' => 1],
'data' => ['failCommands' => ['getMore'], 'errorCode' => $errorCode],
]);
$this->insertDocument(['x' => 1]);
$operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), []);
$changeStream = $operation->execute($this->getPrimaryServer());
$changeStream->rewind();
$this->expectException(ServerException::class);
$this->expectExceptionCode($errorCode);
$changeStream->next();
}
public function provideNonResumableErrorCodes()
{
return [
'CappedPositionLost' => [136],
'CursorKilled' => [237],
'Interrupted' => [11601],
];
}
/** /**
* Prose test 2: "ChangeStream will throw an exception if the server * Prose test 2: "ChangeStream will throw an exception if the server
* response is missing the resume token (if wire version is < 8, this is a * response is missing the resume token (if wire version is < 8, this is a
...@@ -979,7 +900,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -979,7 +900,7 @@ class WatchFunctionalTest extends FunctionalTestCase
]; ];
$this->assertMatchesDocument($expectedResult, $changeStream->current()); $this->assertMatchesDocument($expectedResult, $changeStream->current());
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$this->advanceCursorUntilValid($changeStream); $this->advanceCursorUntilValid($changeStream);
$this->assertSame(1, $changeStream->key()); $this->assertSame(1, $changeStream->key());
...@@ -1218,7 +1139,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -1218,7 +1139,7 @@ class WatchFunctionalTest extends FunctionalTestCase
); );
$changeStream->rewind(); $changeStream->rewind();
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
(new CommandObserver())->observe( (new CommandObserver())->observe(
function () use (&$changeStream) { function () use (&$changeStream) {
...@@ -1402,7 +1323,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -1402,7 +1323,7 @@ class WatchFunctionalTest extends FunctionalTestCase
$changeStream = $operation->execute($secondary); $changeStream = $operation->execute($secondary);
$previousCursorId = $changeStream->getCursorId(); $previousCursorId = $changeStream->getCursorId();
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$changeStream->next(); $changeStream->next();
$this->assertNotSame($previousCursorId, $changeStream->getCursorId()); $this->assertNotSame($previousCursorId, $changeStream->getCursorId());
...@@ -1543,7 +1464,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -1543,7 +1464,7 @@ class WatchFunctionalTest extends FunctionalTestCase
$operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options); $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
$changeStream = $operation->execute($this->getPrimaryServer()); $changeStream = $operation->execute($this->getPrimaryServer());
$changeStream->rewind(); $changeStream->rewind();
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$aggregateCommand = null; $aggregateCommand = null;
...@@ -1594,7 +1515,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -1594,7 +1515,7 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->advanceCursorUntilValid($changeStream); $this->advanceCursorUntilValid($changeStream);
$this->assertTrue($changeStream->valid()); $this->assertTrue($changeStream->valid());
$this->killChangeStreamCursor($changeStream); $this->forceChangeStreamResume();
$aggregateCommand = null; $aggregateCommand = null;
...@@ -1630,6 +1551,15 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -1630,6 +1551,15 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->assertEmpty($commands); $this->assertEmpty($commands);
} }
private function forceChangeStreamResume(array $commands = ['getMore'], int $errorCode = self::NOT_MASTER)
{
$this->configureFailPoint([
'configureFailPoint' => 'failCommand',
'mode' => ['times' => 1],
'data' => ['failCommands' => $commands, 'errorCode' => $errorCode],
]);
}
private function getPostBatchResumeTokenFromReply(stdClass $reply) private function getPostBatchResumeTokenFromReply(stdClass $reply)
{ {
$this->assertObjectHasAttribute('cursor', $reply); $this->assertObjectHasAttribute('cursor', $reply);
...@@ -1662,17 +1592,6 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -1662,17 +1592,6 @@ class WatchFunctionalTest extends FunctionalTestCase
return server_supports_feature($this->getPrimaryServer(), self::$wireVersionForStartAtOperationTime); return server_supports_feature($this->getPrimaryServer(), self::$wireVersionForStartAtOperationTime);
} }
private function killChangeStreamCursor(ChangeStream $changeStream)
{
$command = [
'killCursors' => $this->getCollectionName(),
'cursors' => [ $changeStream->getCursorId() ],
];
$operation = new DatabaseCommand($this->getDatabaseName(), $command);
$operation->execute($this->getPrimaryServer());
}
private function advanceCursorUntilValid(Iterator $iterator, $limitOnShardedClusters = 5) private function advanceCursorUntilValid(Iterator $iterator, $limitOnShardedClusters = 5)
{ {
if (! $this->isShardedCluster()) { if (! $this->isShardedCluster()) {
......
...@@ -4,6 +4,7 @@ namespace MongoDB\Tests\SpecTests; ...@@ -4,6 +4,7 @@ namespace MongoDB\Tests\SpecTests;
use ArrayIterator; use ArrayIterator;
use LogicException; use LogicException;
use MongoDB\BSON\Int64;
use MongoDB\ChangeStream; use MongoDB\ChangeStream;
use MongoDB\Driver\Exception\Exception; use MongoDB\Driver\Exception\Exception;
use MongoDB\Model\BSONDocument; use MongoDB\Model\BSONDocument;
...@@ -22,16 +23,27 @@ use function glob; ...@@ -22,16 +23,27 @@ use function glob;
class ChangeStreamsSpecTest extends FunctionalTestCase class ChangeStreamsSpecTest extends FunctionalTestCase
{ {
/** @var array */ /** @var array */
private static $incompleteTests = ['change-streams-errors: Change Stream should error when _id is projected out' => 'PHPC-1419']; private static $incompleteTests = [];
/** /**
* Assert that the expected and actual command documents match. * Assert that the expected and actual command documents match.
* *
* Note: this method may modify the $expected object.
*
* @param stdClass $expected Expected command document * @param stdClass $expected Expected command document
* @param stdClass $actual Actual command document * @param stdClass $actual Actual command document
*/ */
public static function assertCommandMatches(stdClass $expected, stdClass $actual) public static function assertCommandMatches(stdClass $expected, stdClass $actual)
{ {
if (isset($expected->getMore) && $expected->getMore === 42) {
static::assertObjectHasAttribute('getMore', $actual);
static::assertThat($actual->getMore, static::logicalOr(
static::isInstanceOf(Int64::class),
static::isType('integer')
));
unset($expected->getMore);
}
static::assertDocumentsMatch($expected, $actual); static::assertDocumentsMatch($expected, $actual);
} }
...@@ -74,9 +86,13 @@ class ChangeStreamsSpecTest extends FunctionalTestCase ...@@ -74,9 +86,13 @@ class ChangeStreamsSpecTest extends FunctionalTestCase
$this->markTestIncomplete(self::$incompleteTests[$this->dataDescription()]); $this->markTestIncomplete(self::$incompleteTests[$this->dataDescription()]);
} }
if ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets()) {
$this->markTestSkipped('$changeStream is only supported with replicasets');
}
$this->checkServerRequirements($this->createRunOn($test)); $this->checkServerRequirements($this->createRunOn($test));
if (! isset($databaseName, $collectionName, $database2Name, $collection2Name)) { if (! isset($databaseName, $collectionName)) {
$this->fail('Required database and collection names are unset'); $this->fail('Required database and collection names are unset');
} }
...@@ -84,7 +100,10 @@ class ChangeStreamsSpecTest extends FunctionalTestCase ...@@ -84,7 +100,10 @@ class ChangeStreamsSpecTest extends FunctionalTestCase
$this->setContext($context); $this->setContext($context);
$this->dropDatabasesAndCreateCollection($databaseName, $collectionName); $this->dropDatabasesAndCreateCollection($databaseName, $collectionName);
$this->dropDatabasesAndCreateCollection($database2Name, $collection2Name);
if (isset($database2Name, $collection2Name)) {
$this->dropDatabasesAndCreateCollection($database2Name, $collection2Name);
}
if (isset($test->failPoint)) { if (isset($test->failPoint)) {
$this->configureFailPoint($test->failPoint); $this->configureFailPoint($test->failPoint);
...@@ -248,6 +267,13 @@ class ChangeStreamsSpecTest extends FunctionalTestCase ...@@ -248,6 +267,13 @@ class ChangeStreamsSpecTest extends FunctionalTestCase
* to return as many results as are expected. Require at least one * to return as many results as are expected. Require at least one
* iteration to allow next() a chance to throw for error tests. */ * iteration to allow next() a chance to throw for error tests. */
$maxIterations = $limit + 1; $maxIterations = $limit + 1;
/* On sharded clusters, allow for empty getMore calls due to sharding
* architecture */
if ($this->isShardedCluster()) {
$maxIterations *= 5;
}
$events = []; $events = [];
for ($i = 0, $changeStream->rewind(); $i < $maxIterations; $i++, $changeStream->next()) { for ($i = 0, $changeStream->rewind(); $i < $maxIterations; $i++, $changeStream->next()) {
......
...@@ -54,9 +54,7 @@ ...@@ -54,9 +54,7 @@
"cursor": {}, "cursor": {},
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {}
"fullDocument": "default"
}
}, },
{ {
"$unsupported": "foo" "$unsupported": "foo"
...@@ -104,10 +102,54 @@ ...@@ -104,10 +102,54 @@
], ],
"result": { "result": {
"error": { "error": {
"code": 280, "code": 280
"errorLabels": [ }
"NonResumableChangeStreamError" }
] },
{
"description": "change stream errors on MaxTimeMSExpired",
"minServerVersion": "4.2",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 50,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [
{
"$project": {
"_id": 0
}
}
],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"z": 3
}
}
}
],
"result": {
"error": {
"code": 50
} }
} }
} }
......
collection_name: &collection_name "test"
database_name: &database_name "change-stream-tests"
collection2_name: &collection2_name "test2"
database2_name: &database2_name "change-stream-tests-2"
tests:
-
description: The watch helper must not throw a custom exception when executed against a single server topology, but instead depend on a server error
minServerVersion: "3.6.0"
target: collection
topology:
- single
changeStreamPipeline: []
changeStreamOptions: {}
operations: []
expectations: []
result:
error:
code: 40573
-
description: Change Stream should error when an invalid aggregation stage is passed in
minServerVersion: "3.6.0"
target: collection
topology:
- replicaset
changeStreamPipeline:
-
$unsupported: foo
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
z: 3
expectations:
-
command_started_event:
command:
aggregate: *collection_name
cursor: {}
pipeline:
-
$changeStream:
fullDocument: default
-
$unsupported: foo
command_name: aggregate
database_name: *database_name
result:
error:
code: 40324
-
description: Change Stream should error when _id is projected out
minServerVersion: "4.1.11"
target: collection
topology:
- replicaset
- sharded
changeStreamPipeline:
-
$project: { _id: 0 }
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
z: 3
result:
error:
code: 280
errorLabels: [ "NonResumableChangeStreamError" ]
{
"collection_name": "test",
"database_name": "change-stream-tests",
"tests": [
{
"description": "change stream resumes after HostUnreachable",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 6,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after HostNotFound",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 7,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after NetworkTimeout",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 89,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after ShutdownInProgress",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 91,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after PrimarySteppedDown",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 189,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after ExceededTimeLimit",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 262,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after SocketException",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 9001,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after NotMaster",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 10107,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after InterruptedAtShutdown",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 11600,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after InterruptedDueToReplStateChange",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 11602,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after NotMasterNoSlaveOk",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 13435,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after NotMasterOrSecondary",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 13436,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after StaleShardVersion",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 63,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after StaleEpoch",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 150,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after RetryChangeStream",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 234,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after FailedToSatisfyReadPreference",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failGetMoreAfterCursorCheckout",
"mode": {
"times": 1
},
"data": {
"errorCode": 133,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes if error contains ResumableChangeStreamError",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 50,
"closeConnection": false,
"errorLabels": [
"ResumableChangeStreamError"
]
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream does not resume if error does not contain ResumableChangeStreamError",
"minServerVersion": "4.3.1",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 6,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"result": {
"error": {
"code": 6
}
}
}
]
}
{
"collection_name": "test",
"database_name": "change-stream-tests",
"tests": [
{
"description": "change stream resumes after a network error",
"minServerVersion": "4.2",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"closeConnection": true
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after HostUnreachable",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 6,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after HostNotFound",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 7,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after NetworkTimeout",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 89,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after ShutdownInProgress",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 91,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after PrimarySteppedDown",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 189,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after ExceededTimeLimit",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 262,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after SocketException",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 9001,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after NotMaster",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 10107,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after InterruptedAtShutdown",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 11600,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after InterruptedDueToReplStateChange",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 11602,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after NotMasterNoSlaveOk",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 13435,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after NotMasterOrSecondary",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 13436,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after StaleShardVersion",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 63,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after StaleEpoch",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 150,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after RetryChangeStream",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 234,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
},
{
"description": "change stream resumes after FailedToSatisfyReadPreference",
"minServerVersion": "4.2",
"maxServerVersion": "4.2.99",
"failPoint": {
"configureFailPoint": "failCommand",
"mode": {
"times": 1
},
"data": {
"failCommands": [
"getMore"
],
"errorCode": 133,
"closeConnection": false
}
},
"target": "collection",
"topology": [
"replicaset",
"sharded"
],
"changeStreamPipeline": [],
"changeStreamOptions": {},
"operations": [
{
"database": "change-stream-tests",
"collection": "test",
"name": "insertOne",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"getMore": 42,
"collection": "test"
},
"command_name": "getMore",
"database_name": "change-stream-tests"
}
},
{
"command_started_event": {
"command": {
"aggregate": "test",
"cursor": {},
"pipeline": [
{
"$changeStream": {}
}
]
},
"command_name": "aggregate",
"database_name": "change-stream-tests"
}
}
],
"result": {
"success": [
{
"_id": "42",
"documentKey": "42",
"operationType": "insert",
"ns": {
"db": "change-stream-tests",
"coll": "test"
},
"fullDocument": {
"x": {
"$numberInt": "1"
}
}
}
]
}
}
]
}
...@@ -33,9 +33,7 @@ ...@@ -33,9 +33,7 @@
"cursor": {}, "cursor": {},
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {}
"fullDocument": "default"
}
} }
] ]
}, },
...@@ -153,9 +151,7 @@ ...@@ -153,9 +151,7 @@
"cursor": {}, "cursor": {},
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {}
"fullDocument": "default"
}
} }
] ]
}, },
...@@ -226,9 +222,7 @@ ...@@ -226,9 +222,7 @@
"cursor": {}, "cursor": {},
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {}
"fullDocument": "default"
}
}, },
{ {
"$match": { "$match": {
...@@ -312,9 +306,7 @@ ...@@ -312,9 +306,7 @@
"cursor": {}, "cursor": {},
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {}
"fullDocument": "default"
}
} }
] ]
}, },
...@@ -404,7 +396,6 @@ ...@@ -404,7 +396,6 @@
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {
"fullDocument": "default",
"allChangesForCluster": true "allChangesForCluster": true
} }
} }
...@@ -523,9 +514,7 @@ ...@@ -523,9 +514,7 @@
"cursor": {}, "cursor": {},
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {}
"fullDocument": "default"
}
} }
] ]
}, },
...@@ -611,9 +600,7 @@ ...@@ -611,9 +600,7 @@
"cursor": {}, "cursor": {},
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {}
"fullDocument": "default"
}
} }
] ]
}, },
...@@ -665,9 +652,7 @@ ...@@ -665,9 +652,7 @@
"cursor": {}, "cursor": {},
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {}
"fullDocument": "default"
}
} }
] ]
}, },
...@@ -756,9 +741,7 @@ ...@@ -756,9 +741,7 @@
}, },
"pipeline": [ "pipeline": [
{ {
"$changeStream": { "$changeStream": {}
"fullDocument": "default"
}
} }
] ]
}, },
......
collection_name: &collection_name "test"
database_name: &database_name "change-stream-tests"
collection2_name: &collection2_name "test2"
database2_name: &database2_name "change-stream-tests-2"
tests:
-
description: "$changeStream must be the first stage in a change stream pipeline sent to the server"
minServerVersion: "3.6.0"
target: collection
topology:
- replicaset
changeStreamPipeline: []
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
x: 1
expectations:
-
command_started_event:
command:
aggregate: *collection_name
cursor: {}
pipeline:
-
$changeStream:
fullDocument: default
command_name: aggregate
database_name: *database_name
result:
success:
-
_id: "42"
documentKey: "42"
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
x:
$numberInt: "1"
-
description: The server returns change stream responses in the specified server response format
minServerVersion: "3.6.0"
target: collection
topology:
- replicaset
changeStreamPipeline: []
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
x: 1
expectations: []
result:
success:
-
_id: "42"
documentKey: "42"
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
x:
$numberInt: "1"
-
description: Executing a watch helper on a Collection results in notifications for changes to the specified collection
minServerVersion: "3.6.0"
target: collection
topology:
- replicaset
changeStreamPipeline: []
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection2_name
name: insertOne
arguments:
document:
x: 1
-
database: *database2_name
collection: *collection_name
name: insertOne
arguments:
document:
y: 2
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
z: 3
expectations:
-
command_started_event:
command:
aggregate: *collection_name
cursor: {}
pipeline:
-
$changeStream:
fullDocument: default
command_name: aggregate
database_name: *database_name
result:
success:
-
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
z:
$numberInt: "3"
-
description: Change Stream should allow valid aggregate pipeline stages
minServerVersion: "3.6.0"
target: collection
topology:
- replicaset
changeStreamPipeline:
-
$match:
"fullDocument.z": 3
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
y: 2
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
z: 3
expectations:
-
command_started_event:
command:
aggregate: *collection_name
cursor: {}
pipeline:
-
$changeStream:
fullDocument: default
-
$match:
"fullDocument.z":
$numberInt: "3"
command_name: aggregate
database_name: *database_name
result:
success:
-
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
z:
$numberInt: "3"
-
description: Executing a watch helper on a Database results in notifications for changes to all collections in the specified database.
minServerVersion: "3.8.0"
target: database
topology:
- replicaset
changeStreamPipeline: []
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection2_name
name: insertOne
arguments:
document:
x: 1
-
database: *database2_name
collection: *collection_name
name: insertOne
arguments:
document:
y: 2
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
z: 3
expectations:
-
command_started_event:
command:
aggregate:
$numberInt: "1"
cursor: {}
pipeline:
-
$changeStream:
fullDocument: default
command_name: aggregate
database_name: *database_name
result:
success:
-
operationType: insert
ns:
db: *database_name
coll: *collection2_name
fullDocument:
x:
$numberInt: "1"
-
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
z:
$numberInt: "3"
-
description: Executing a watch helper on a MongoClient results in notifications for changes to all collections in all databases in the cluster.
minServerVersion: "3.8.0"
target: client
topology:
- replicaset
changeStreamPipeline: []
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection2_name
name: insertOne
arguments:
document:
x: 1
-
database: *database2_name
collection: *collection_name
name: insertOne
arguments:
document:
y: 2
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
z: 3
expectations:
-
command_started_event:
command:
aggregate:
$numberInt: "1"
cursor: {}
pipeline:
-
$changeStream:
fullDocument: default
allChangesForCluster: true
command_name: aggregate
database_name: admin
result:
success:
-
operationType: insert
ns:
db: *database_name
coll: *collection2_name
fullDocument:
x:
$numberInt: "1"
-
operationType: insert
ns:
db: *database2_name
coll: *collection_name
fullDocument:
y:
$numberInt: "2"
-
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
z:
$numberInt: "3"
-
description: Test insert, update, replace, and delete event types
minServerVersion: "3.6.0"
target: collection
topology:
- replicaset
changeStreamPipeline: []
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
x: 1
-
database: *database_name
collection: *collection_name
name: updateOne
arguments:
filter:
x: 1
update:
$set:
x: 2
-
database: *database_name
collection: *collection_name
name: replaceOne
arguments:
filter:
x: 2
replacement:
x: 3
-
database: *database_name
collection: *collection_name
name: deleteOne
arguments:
filter:
x: 3
expectations:
-
command_started_event:
command:
aggregate: *collection_name
cursor: {}
pipeline:
-
$changeStream:
fullDocument: default
command_name: aggregate
database_name: *database_name
result:
success:
-
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
x:
$numberInt: "1"
-
operationType: update
ns:
db: *database_name
coll: *collection_name
updateDescription:
updatedFields:
x:
$numberInt: "2"
-
operationType: replace
ns:
db: *database_name
coll: *collection_name
fullDocument:
x:
$numberInt: "3"
-
operationType: delete
ns:
db: *database_name
coll: *collection_name
-
description: Test rename and invalidate event types
minServerVersion: "4.0.1"
target: collection
topology:
- replicaset
changeStreamPipeline: []
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection_name
name: rename
arguments:
to: *collection2_name
expectations:
-
command_started_event:
command:
aggregate: *collection_name
cursor: {}
pipeline:
-
$changeStream:
fullDocument: default
command_name: aggregate
database_name: *database_name
result:
success:
-
operationType: rename
ns:
db: *database_name
coll: *collection_name
to:
db: *database_name
coll: *collection2_name
-
operationType: invalidate
-
description: Test drop and invalidate event types
minServerVersion: "4.0.1"
target: collection
topology:
- replicaset
changeStreamPipeline: []
changeStreamOptions: {}
operations:
-
database: *database_name
collection: *collection_name
name: drop
expectations:
-
command_started_event:
command:
aggregate: *collection_name
cursor: {}
pipeline:
-
$changeStream:
fullDocument: default
command_name: aggregate
database_name: *database_name
result:
success:
-
operationType: drop
ns:
db: *database_name
coll: *collection_name
-
operationType: invalidate
# Test that resume logic works correctly even after consecutive retryable failures of a getMore command,
# with no intervening events. This is ensured by setting the batch size of the change stream to 1,
-
description: Test consecutive resume
minServerVersion: "4.1.7"
target: collection
topology:
- replicaset
changeStreamPipeline: []
changeStreamOptions: { batchSize: 1}
failPoint:
configureFailPoint: failCommand
mode: {times: 2}
data:
failCommands: ["getMore"]
closeConnection: true
operations:
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
x: 1
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
x: 2
-
database: *database_name
collection: *collection_name
name: insertOne
arguments:
document:
x: 3
expectations:
-
command_started_event:
command:
aggregate: *collection_name
cursor: {batchSize: 1}
pipeline:
-
$changeStream:
fullDocument: default
command_name: aggregate
database_name: *database_name
result:
success:
-
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
x:
$numberInt: "1"
-
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
x:
$numberInt: "2"
-
operationType: insert
ns:
db: *database_name
coll: *collection_name
fullDocument:
x:
$numberInt: "3"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment