Skip to content

Commit 67f8dc8

Browse files
committed
POC: Test collection/index creation within transaction
1 parent 23e32dd commit 67f8dc8

File tree

3 files changed

+605
-0
lines changed

3 files changed

+605
-0
lines changed

tests/SpecTests/Operation.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
use MongoDB\Driver\Session;
1414
use MongoDB\Driver\WriteConcern;
1515
use MongoDB\GridFS\Bucket;
16+
use MongoDB\Model\CollectionInfo;
17+
use MongoDB\Model\IndexInfo;
1618
use MongoDB\Operation\FindOneAndReplace;
1719
use MongoDB\Operation\FindOneAndUpdate;
1820
use stdClass;
1921
use function array_diff_key;
2022
use function array_map;
2123
use function fclose;
2224
use function fopen;
25+
use function iterator_to_array;
2326
use function MongoDB\is_last_pipeline_operator_write;
2427
use function MongoDB\with_transaction;
2528
use function stream_get_contents;
@@ -359,6 +362,11 @@ private function executeForCollection(Collection $collection, Context $context)
359362
array_map([$this, 'prepareBulkWriteRequest'], $args['requests']),
360363
$options
361364
);
365+
case 'createIndex':
366+
return $collection->createIndex(
367+
$args['key'],
368+
array_diff_key($args, ['key' => 1])
369+
);
362370
case 'count':
363371
case 'countDocuments':
364372
case 'find':
@@ -466,6 +474,16 @@ private function executeForDatabase(Database $database, Context $context)
466474
$args['pipeline'],
467475
array_diff_key($args, ['pipeline' => 1])
468476
);
477+
case 'createCollection':
478+
return $database->createCollection(
479+
$args['collection'],
480+
array_diff_key($args, ['collection' => 1])
481+
);
482+
case 'dropCollection':
483+
return $database->dropCollection(
484+
$args['collection'],
485+
array_diff_key($args, ['collection' => 1])
486+
);
469487
case 'listCollections':
470488
return $database->listCollections($args);
471489
case 'runCommand':
@@ -570,6 +588,36 @@ private function executeForTestRunner(FunctionalTestCase $test, Context $context
570588
$context->replaceArgumentSessionPlaceholder($args);
571589

572590
switch ($this->name) {
591+
case 'assertCollectionExists':
592+
$databaseName = $args['database'];
593+
$collectionName = $args['collection'];
594+
595+
$test->assertContains($collectionName, $this->getCollectionNames($context, $databaseName));
596+
597+
return null;
598+
case 'assertCollectionNotExists':
599+
$databaseName = $args['database'];
600+
$collectionName = $args['collection'];
601+
602+
$test->assertNotContains($collectionName, $this->getCollectionNames($context, $databaseName));
603+
604+
return null;
605+
case 'assertIndexExists':
606+
$databaseName = $args['database'];
607+
$collectionName = $args['collection'];
608+
$indexName = $args['index'];
609+
610+
$test->assertContains($indexName, $this->getIndexNames($context, $databaseName, $collectionName));
611+
612+
return null;
613+
case 'assertIndexNotExists':
614+
$databaseName = $args['database'];
615+
$collectionName = $args['collection'];
616+
$indexName = $args['index'];
617+
618+
$test->assertNotContains($indexName, $this->getIndexNames($context, $databaseName, $collectionName));
619+
620+
return null;
573621
case 'assertSessionPinned':
574622
$test->assertInstanceOf(Session::class, $args['session']);
575623
$test->assertInstanceOf(Server::class, $args['session']->getServer());
@@ -599,6 +647,37 @@ private function executeForTestRunner(FunctionalTestCase $test, Context $context
599647
}
600648
}
601649

650+
/**
651+
* @param string $databaseName
652+
*
653+
* @return array
654+
*/
655+
private function getCollectionNames(Context $context, $databaseName)
656+
{
657+
return array_map(
658+
function (CollectionInfo $collectionInfo) {
659+
return $collectionInfo->getName();
660+
},
661+
iterator_to_array($context->selectDatabase($databaseName)->listCollections())
662+
);
663+
}
664+
665+
/**
666+
* @param string $databaseName
667+
* @param string $collectionName
668+
*
669+
* @return array
670+
*/
671+
private function getIndexNames(Context $context, $databaseName, $collectionName)
672+
{
673+
return array_map(
674+
function (IndexInfo $indexInfo) {
675+
return $indexInfo->getName();
676+
},
677+
iterator_to_array($context->selectCollection($databaseName, $collectionName)->listIndexes())
678+
);
679+
}
680+
602681
/**
603682
* @throws LogicException if the operation object is unsupported
604683
*/
@@ -657,6 +736,9 @@ private function getResultAssertionTypeForCollection()
657736
return ResultExpectation::ASSERT_BULKWRITE;
658737
case 'count':
659738
case 'countDocuments':
739+
return ResultExpectation::ASSERT_SAME;
740+
case 'createIndex':
741+
return ResultExpectation::ASSERT_MATCHES_DOCUMENT;
660742
case 'distinct':
661743
case 'estimatedDocumentCount':
662744
return ResultExpectation::ASSERT_SAME;
@@ -700,6 +782,8 @@ private function getResultAssertionTypeForDatabase()
700782
case 'aggregate':
701783
case 'listCollections':
702784
return ResultExpectation::ASSERT_SAME_DOCUMENTS;
785+
case 'createCollection':
786+
case 'dropCollection':
703787
case 'runCommand':
704788
return ResultExpectation::ASSERT_MATCHES_DOCUMENT;
705789
case 'watch':
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
{
2+
"runOn": [
3+
{
4+
"minServerVersion": "4.3.4",
5+
"topology": [
6+
"replicaset",
7+
"sharded"
8+
]
9+
}
10+
],
11+
"database_name": "transaction-tests",
12+
"collection_name": "test",
13+
"data": [],
14+
"tests": [
15+
{
16+
"description": "explicitly create collection using create command",
17+
"operations": [
18+
{
19+
"name": "dropCollection",
20+
"object": "database",
21+
"arguments": {
22+
"collection": "test"
23+
}
24+
},
25+
{
26+
"name": "startTransaction",
27+
"object": "session0"
28+
},
29+
{
30+
"name": "createCollection",
31+
"object": "database",
32+
"arguments": {
33+
"session": "session0",
34+
"collection": "test"
35+
}
36+
},
37+
{
38+
"name": "assertCollectionNotExists",
39+
"object": "testRunner",
40+
"arguments": {
41+
"database": "transaction-tests",
42+
"collection": "test"
43+
}
44+
},
45+
{
46+
"name": "commitTransaction",
47+
"object": "session0"
48+
},
49+
{
50+
"name": "assertCollectionExists",
51+
"object": "testRunner",
52+
"arguments": {
53+
"database": "transaction-tests",
54+
"collection": "test"
55+
}
56+
}
57+
],
58+
"expectations": [
59+
{
60+
"command_started_event": {
61+
"command": {
62+
"drop": "test",
63+
"writeConcern": null
64+
},
65+
"command_name": "drop",
66+
"database_name": "transaction-tests"
67+
}
68+
},
69+
{
70+
"command_started_event": {
71+
"command": {
72+
"create": "test",
73+
"lsid": "session0",
74+
"txnNumber": {
75+
"$numberLong": "1"
76+
},
77+
"startTransaction": true,
78+
"autocommit": false,
79+
"writeConcern": null
80+
},
81+
"command_name": "create",
82+
"database_name": "transaction-tests"
83+
}
84+
},
85+
{
86+
"command_started_event": {
87+
"command": {
88+
"listCollections": 1,
89+
"writeConcern": null
90+
},
91+
"command_name": "listCollections",
92+
"database_name": "transaction-tests"
93+
}
94+
},
95+
{
96+
"command_started_event": {
97+
"command": {
98+
"commitTransaction": 1,
99+
"lsid": "session0",
100+
"txnNumber": {
101+
"$numberLong": "1"
102+
},
103+
"startTransaction": null,
104+
"autocommit": false,
105+
"writeConcern": null
106+
},
107+
"command_name": "commitTransaction",
108+
"database_name": "admin"
109+
}
110+
},
111+
{
112+
"command_started_event": {
113+
"command": {
114+
"listCollections": 1,
115+
"writeConcern": null
116+
},
117+
"command_name": "listCollections",
118+
"database_name": "transaction-tests"
119+
}
120+
}
121+
]
122+
},
123+
{
124+
"description": "implicitly create collection using insert",
125+
"operations": [
126+
{
127+
"name": "dropCollection",
128+
"object": "database",
129+
"arguments": {
130+
"collection": "test"
131+
}
132+
},
133+
{
134+
"name": "startTransaction",
135+
"object": "session0"
136+
},
137+
{
138+
"name": "insertOne",
139+
"object": "collection",
140+
"arguments": {
141+
"session": "session0",
142+
"document": {
143+
"_id": 1
144+
}
145+
},
146+
"result": {
147+
"insertedId": 1
148+
}
149+
},
150+
{
151+
"name": "assertCollectionNotExists",
152+
"object": "testRunner",
153+
"arguments": {
154+
"database": "transaction-tests",
155+
"collection": "test"
156+
}
157+
},
158+
{
159+
"name": "commitTransaction",
160+
"object": "session0"
161+
},
162+
{
163+
"name": "assertCollectionExists",
164+
"object": "testRunner",
165+
"arguments": {
166+
"database": "transaction-tests",
167+
"collection": "test"
168+
}
169+
}
170+
],
171+
"expectations": [
172+
{
173+
"command_started_event": {
174+
"command": {
175+
"drop": "test",
176+
"writeConcern": null
177+
},
178+
"command_name": "drop",
179+
"database_name": "transaction-tests"
180+
}
181+
},
182+
{
183+
"command_started_event": {
184+
"command": {
185+
"insert": "test",
186+
"documents": [
187+
{
188+
"_id": 1
189+
}
190+
],
191+
"ordered": true,
192+
"readConcern": null,
193+
"lsid": "session0",
194+
"txnNumber": {
195+
"$numberLong": "1"
196+
},
197+
"startTransaction": true,
198+
"autocommit": false,
199+
"writeConcern": null
200+
},
201+
"command_name": "insert",
202+
"database_name": "transaction-tests"
203+
}
204+
},
205+
{
206+
"command_started_event": {
207+
"command": {
208+
"listCollections": 1,
209+
"writeConcern": null
210+
},
211+
"command_name": "listCollections",
212+
"database_name": "transaction-tests"
213+
}
214+
},
215+
{
216+
"command_started_event": {
217+
"command": {
218+
"commitTransaction": 1,
219+
"lsid": "session0",
220+
"txnNumber": {
221+
"$numberLong": "1"
222+
},
223+
"startTransaction": null,
224+
"autocommit": false,
225+
"writeConcern": null
226+
},
227+
"command_name": "commitTransaction",
228+
"database_name": "admin"
229+
}
230+
},
231+
{
232+
"command_started_event": {
233+
"command": {
234+
"listCollections": 1,
235+
"writeConcern": null
236+
},
237+
"command_name": "listCollections",
238+
"database_name": "transaction-tests"
239+
}
240+
}
241+
]
242+
}
243+
]
244+
}

0 commit comments

Comments
 (0)