PHPLIB-496: Test collection and index creation in multi-doc transactions

parent 3777f5ae
......@@ -130,7 +130,7 @@ class CommandExpectations implements CommandSubscriber
* configureFailPoint needs to be ignored as the targetedFailPoint
* operation will be caught by command monitoring and is also not
* present in the expected commands in spec tests. */
$o->ignoredCommandNames = ['buildInfo', 'getParameter', 'configureFailPoint'];
$o->ignoredCommandNames = ['buildInfo', 'getParameter', 'configureFailPoint', 'listCollections', 'listIndexes'];
return $o;
}
......
......@@ -13,6 +13,8 @@ use MongoDB\Driver\Server;
use MongoDB\Driver\Session;
use MongoDB\Driver\WriteConcern;
use MongoDB\GridFS\Bucket;
use MongoDB\Model\CollectionInfo;
use MongoDB\Model\IndexInfo;
use MongoDB\Operation\FindOneAndReplace;
use MongoDB\Operation\FindOneAndUpdate;
use stdClass;
......@@ -20,6 +22,7 @@ use function array_diff_key;
use function array_map;
use function fclose;
use function fopen;
use function iterator_to_array;
use function MongoDB\is_last_pipeline_operator_write;
use function MongoDB\with_transaction;
use function stream_get_contents;
......@@ -359,6 +362,11 @@ final class Operation
array_map([$this, 'prepareBulkWriteRequest'], $args['requests']),
$options
);
case 'createIndex':
return $collection->createIndex(
$args['keys'],
array_diff_key($args, ['keys' => 1])
);
case 'count':
case 'countDocuments':
case 'find':
......@@ -466,6 +474,16 @@ final class Operation
$args['pipeline'],
array_diff_key($args, ['pipeline' => 1])
);
case 'createCollection':
return $database->createCollection(
$args['collection'],
array_diff_key($args, ['collection' => 1])
);
case 'dropCollection':
return $database->dropCollection(
$args['collection'],
array_diff_key($args, ['collection' => 1])
);
case 'listCollections':
return $database->listCollections($args);
case 'runCommand':
......@@ -570,6 +588,36 @@ final class Operation
$context->replaceArgumentSessionPlaceholder($args);
switch ($this->name) {
case 'assertCollectionExists':
$databaseName = $args['database'];
$collectionName = $args['collection'];
$test->assertContains($collectionName, $this->getCollectionNames($context, $databaseName));
return null;
case 'assertCollectionNotExists':
$databaseName = $args['database'];
$collectionName = $args['collection'];
$test->assertNotContains($collectionName, $this->getCollectionNames($context, $databaseName));
return null;
case 'assertIndexExists':
$databaseName = $args['database'];
$collectionName = $args['collection'];
$indexName = $args['index'];
$test->assertContains($indexName, $this->getIndexNames($context, $databaseName, $collectionName));
return null;
case 'assertIndexNotExists':
$databaseName = $args['database'];
$collectionName = $args['collection'];
$indexName = $args['index'];
$test->assertNotContains($indexName, $this->getIndexNames($context, $databaseName, $collectionName));
return null;
case 'assertSessionPinned':
$test->assertInstanceOf(Session::class, $args['session']);
$test->assertInstanceOf(Server::class, $args['session']->getServer());
......@@ -599,6 +647,37 @@ final class Operation
}
}
/**
* @param string $databaseName
*
* @return array
*/
private function getCollectionNames(Context $context, $databaseName)
{
return array_map(
function (CollectionInfo $collectionInfo) {
return $collectionInfo->getName();
},
iterator_to_array($context->selectDatabase($databaseName)->listCollections())
);
}
/**
* @param string $databaseName
* @param string $collectionName
*
* @return array
*/
private function getIndexNames(Context $context, $databaseName, $collectionName)
{
return array_map(
function (IndexInfo $indexInfo) {
return $indexInfo->getName();
},
iterator_to_array($context->selectCollection($databaseName, $collectionName)->listIndexes())
);
}
/**
* @throws LogicException if the operation object is unsupported
*/
......@@ -657,6 +736,9 @@ final class Operation
return ResultExpectation::ASSERT_BULKWRITE;
case 'count':
case 'countDocuments':
return ResultExpectation::ASSERT_SAME;
case 'createIndex':
return ResultExpectation::ASSERT_MATCHES_DOCUMENT;
case 'distinct':
case 'estimatedDocumentCount':
return ResultExpectation::ASSERT_SAME;
......@@ -700,6 +782,8 @@ final class Operation
case 'aggregate':
case 'listCollections':
return ResultExpectation::ASSERT_SAME_DOCUMENTS;
case 'createCollection':
case 'dropCollection':
case 'runCommand':
return ResultExpectation::ASSERT_MATCHES_DOCUMENT;
case 'watch':
......
{
"runOn": [
{
"minServerVersion": "4.3.4",
"topology": [
"replicaset",
"sharded"
]
}
],
"database_name": "transaction-tests",
"collection_name": "test",
"data": [],
"tests": [
{
"description": "explicitly create collection using create command",
"operations": [
{
"name": "dropCollection",
"object": "database",
"arguments": {
"collection": "test"
}
},
{
"name": "startTransaction",
"object": "session0"
},
{
"name": "createCollection",
"object": "database",
"arguments": {
"session": "session0",
"collection": "test"
}
},
{
"name": "assertCollectionNotExists",
"object": "testRunner",
"arguments": {
"database": "transaction-tests",
"collection": "test"
}
},
{
"name": "commitTransaction",
"object": "session0"
},
{
"name": "assertCollectionExists",
"object": "testRunner",
"arguments": {
"database": "transaction-tests",
"collection": "test"
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"drop": "test",
"writeConcern": null
},
"command_name": "drop",
"database_name": "transaction-tests"
}
},
{
"command_started_event": {
"command": {
"create": "test",
"lsid": "session0",
"txnNumber": {
"$numberLong": "1"
},
"startTransaction": true,
"autocommit": false,
"writeConcern": null
},
"command_name": "create",
"database_name": "transaction-tests"
}
},
{
"command_started_event": {
"command": {
"commitTransaction": 1,
"lsid": "session0",
"txnNumber": {
"$numberLong": "1"
},
"startTransaction": null,
"autocommit": false,
"writeConcern": null
},
"command_name": "commitTransaction",
"database_name": "admin"
}
}
]
},
{
"description": "implicitly create collection using insert",
"operations": [
{
"name": "dropCollection",
"object": "database",
"arguments": {
"collection": "test"
}
},
{
"name": "startTransaction",
"object": "session0"
},
{
"name": "insertOne",
"object": "collection",
"arguments": {
"session": "session0",
"document": {
"_id": 1
}
},
"result": {
"insertedId": 1
}
},
{
"name": "assertCollectionNotExists",
"object": "testRunner",
"arguments": {
"database": "transaction-tests",
"collection": "test"
}
},
{
"name": "commitTransaction",
"object": "session0"
},
{
"name": "assertCollectionExists",
"object": "testRunner",
"arguments": {
"database": "transaction-tests",
"collection": "test"
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"drop": "test",
"writeConcern": null
},
"command_name": "drop",
"database_name": "transaction-tests"
}
},
{
"command_started_event": {
"command": {
"insert": "test",
"documents": [
{
"_id": 1
}
],
"ordered": true,
"readConcern": null,
"lsid": "session0",
"txnNumber": {
"$numberLong": "1"
},
"startTransaction": true,
"autocommit": false,
"writeConcern": null
},
"command_name": "insert",
"database_name": "transaction-tests"
}
},
{
"command_started_event": {
"command": {
"commitTransaction": 1,
"lsid": "session0",
"txnNumber": {
"$numberLong": "1"
},
"startTransaction": null,
"autocommit": false,
"writeConcern": null
},
"command_name": "commitTransaction",
"database_name": "admin"
}
}
]
}
]
}
{
"runOn": [
{
"minServerVersion": "4.3.4",
"topology": [
"replicaset",
"sharded"
]
}
],
"database_name": "transaction-tests",
"collection_name": "test",
"data": [],
"tests": [
{
"description": "create index on a non-existing collection",
"operations": [
{
"name": "dropCollection",
"object": "database",
"arguments": {
"collection": "test"
}
},
{
"name": "startTransaction",
"object": "session0"
},
{
"name": "createIndex",
"object": "collection",
"arguments": {
"session": "session0",
"name": "t_1",
"keys": {
"x": 1
}
}
},
{
"name": "assertIndexNotExists",
"object": "testRunner",
"arguments": {
"database": "transaction-tests",
"collection": "test",
"index": "t_1"
}
},
{
"name": "commitTransaction",
"object": "session0"
},
{
"name": "assertIndexExists",
"object": "testRunner",
"arguments": {
"database": "transaction-tests",
"collection": "test",
"index": "t_1"
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"drop": "test",
"writeConcern": null
},
"command_name": "drop",
"database_name": "transaction-tests"
}
},
{
"command_started_event": {
"command": {
"createIndexes": "test",
"indexes": [
{
"name": "t_1",
"key": {
"x": 1
}
}
],
"lsid": "session0",
"txnNumber": {
"$numberLong": "1"
},
"startTransaction": true,
"autocommit": false,
"writeConcern": null
},
"command_name": "createIndexes",
"database_name": "transaction-tests"
}
},
{
"command_started_event": {
"command": {
"commitTransaction": 1,
"lsid": "session0",
"txnNumber": {
"$numberLong": "1"
},
"startTransaction": null,
"autocommit": false,
"writeConcern": null
},
"command_name": "commitTransaction",
"database_name": "admin"
}
}
]
},
{
"description": "create index on a collection created within the same transaction",
"operations": [
{
"name": "dropCollection",
"object": "database",
"arguments": {
"collection": "test"
}
},
{
"name": "startTransaction",
"object": "session0"
},
{
"name": "createCollection",
"object": "database",
"arguments": {
"session": "session0",
"collection": "test"
}
},
{
"name": "createIndex",
"object": "collection",
"arguments": {
"session": "session0",
"name": "t_1",
"keys": {
"x": 1
}
}
},
{
"name": "assertIndexNotExists",
"object": "testRunner",
"arguments": {
"database": "transaction-tests",
"collection": "test",
"index": "t_1"
}
},
{
"name": "commitTransaction",
"object": "session0"
},
{
"name": "assertIndexExists",
"object": "testRunner",
"arguments": {
"database": "transaction-tests",
"collection": "test",
"index": "t_1"
}
}
],
"expectations": [
{
"command_started_event": {
"command": {
"drop": "test",
"writeConcern": null
},
"command_name": "drop",
"database_name": "transaction-tests"
}
},
{
"command_started_event": {
"command": {
"create": "test",
"lsid": "session0",
"txnNumber": {
"$numberLong": "1"
},
"startTransaction": true,
"autocommit": false,
"writeConcern": null
},
"command_name": "create",
"database_name": "transaction-tests"
}
},
{
"command_started_event": {
"command": {
"createIndexes": "test",
"indexes": [
{
"name": "t_1",
"key": {
"x": 1
}
}
],
"lsid": "session0",
"writeConcern": null
},
"command_name": "createIndexes",
"database_name": "transaction-tests"
}
},
{
"command_started_event": {
"command": {
"commitTransaction": 1,
"lsid": "session0",
"txnNumber": {
"$numberLong": "1"
},
"startTransaction": null,
"autocommit": false,
"writeConcern": null
},
"command_name": "commitTransaction",
"database_name": "admin"
}
}
]
}
]
}
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