Skip to content

Commit 3d686b2

Browse files
committed
Remove legacy transaction-convenient-api spec tests
1 parent 55f9fac commit 3d686b2

11 files changed

+2
-4041
lines changed

tests/SpecTests/TransactionsSpecTest.php

Lines changed: 2 additions & 245 deletions
Original file line numberDiff line numberDiff line change
@@ -2,192 +2,18 @@
22

33
namespace MongoDB\Tests\SpecTests;
44

5-
use MongoDB\BSON\Int64;
6-
use MongoDB\BSON\Timestamp;
7-
use MongoDB\Driver\Command;
8-
use MongoDB\Driver\Exception\ServerException;
95
use MongoDB\Driver\Server;
10-
use stdClass;
116

127
use function array_unique;
13-
use function basename;
148
use function count;
15-
use function dirname;
16-
use function file_get_contents;
17-
use function get_object_vars;
18-
use function glob;
199

2010
/**
21-
* Transactions Convenient API spec tests.
11+
* Transactions spec prose tests.
2212
*
23-
* @see https://github.com/mongodb/specifications/tree/master/source/transactions-convenient-api
13+
* @see https://github.com/mongodb/specifications/blob/master/source/transactions/tests/README.rst#mongos-pinning-prose-tests
2414
*/
2515
class TransactionsSpecTest extends FunctionalTestCase
2616
{
27-
public const INTERRUPTED = 11601;
28-
29-
public function setUp(): void
30-
{
31-
parent::setUp();
32-
33-
static::killAllSessions();
34-
35-
$this->skipIfTransactionsAreNotSupported();
36-
}
37-
38-
public function tearDown(): void
39-
{
40-
if ($this->hasFailed()) {
41-
static::killAllSessions();
42-
}
43-
44-
parent::tearDown();
45-
}
46-
47-
/**
48-
* Assert that the expected and actual command documents match.
49-
*
50-
* Note: this method may modify the $expected object.
51-
*
52-
* @see https://github.com/mongodb/specifications/blob/master/source/transactions/tests/README.rst#command-started-events
53-
* @param stdClass $expected Expected command document
54-
* @param stdClass $actual Actual command document
55-
*/
56-
public static function assertCommandMatches(stdClass $expected, stdClass $actual): void
57-
{
58-
if (isset($expected->getMore) && $expected->getMore === 42) {
59-
static::assertObjectHasAttribute('getMore', $actual);
60-
static::assertThat($actual->getMore, static::logicalOr(
61-
static::isInstanceOf(Int64::class),
62-
static::isType('integer'),
63-
));
64-
unset($expected->getMore);
65-
}
66-
67-
if (isset($expected->recoveryToken) && $expected->recoveryToken === 42) {
68-
static::assertObjectHasAttribute('recoveryToken', $actual);
69-
static::assertIsObject($actual->recoveryToken);
70-
unset($expected->recoveryToken);
71-
}
72-
73-
if (isset($expected->readConcern->afterClusterTime) && $expected->readConcern->afterClusterTime === 42) {
74-
static::assertObjectHasAttribute('readConcern', $actual);
75-
static::assertIsObject($actual->readConcern);
76-
static::assertObjectHasAttribute('afterClusterTime', $actual->readConcern);
77-
static::assertInstanceOf(Timestamp::class, $actual->readConcern->afterClusterTime);
78-
unset($expected->readConcern->afterClusterTime);
79-
80-
/* If "afterClusterTime" was the only assertion for "readConcern",
81-
* unset the field to avoid expecting an empty document later. */
82-
if (get_object_vars($expected->readConcern) === []) {
83-
unset($expected->readConcern);
84-
}
85-
}
86-
87-
/* TODO: Determine if forcing a new libmongoc client in Context is
88-
* preferable to skipping the txnNumber assertion. */
89-
//unset($expected['txnNumber']);
90-
91-
static::assertCommandOmittedFields($expected, $actual);
92-
93-
static::assertDocumentsMatch($expected, $actual);
94-
}
95-
96-
/** @dataProvider provideTransactionsConvenientApiTests */
97-
public function testTransactionsConvenientApi(stdClass $test, ?array $runOn, array $data, ?string $databaseName = null, ?string $collectionName = null): void
98-
{
99-
$this->runTransactionTest($test, $runOn, $data, $databaseName, $collectionName);
100-
}
101-
102-
public function provideTransactionsConvenientApiTests(): array
103-
{
104-
return $this->provideTests('transactions-convenient-api');
105-
}
106-
107-
/**
108-
* Execute an individual test case from the specification.
109-
*
110-
* @param stdClass $test Individual "tests[]" document
111-
* @param array $runOn Top-level "runOn" array with server requirements
112-
* @param array $data Top-level "data" array to initialize collection
113-
* @param string $databaseName Name of database under test
114-
* @param string $collectionName Name of collection under test
115-
*/
116-
private function runTransactionTest(stdClass $test, ?array $runOn, array $data, ?string $databaseName = null, ?string $collectionName = null): void
117-
{
118-
if (isset($runOn)) {
119-
$this->checkServerRequirements($runOn);
120-
}
121-
122-
if (isset($test->skipReason)) {
123-
$this->markTestSkipped($test->skipReason);
124-
}
125-
126-
$databaseName ??= $this->getDatabaseName();
127-
$collectionName ??= $this->getCollectionName();
128-
129-
// Serverless uses a load balancer fronting a single proxy (PHPLIB-757)
130-
$useMultipleMongoses = $this->isMongos() || ($this->isLoadBalanced() && ! $this->isServerless())
131-
? ($test->useMultipleMongoses ?? false)
132-
: false;
133-
134-
$context = Context::fromTransactions($test, $databaseName, $collectionName, $useMultipleMongoses);
135-
$this->setContext($context);
136-
137-
$this->dropTestAndOutcomeCollections();
138-
$this->createTestCollection();
139-
$this->insertDataFixtures($data);
140-
$this->preventStaleDbVersionError($test->operations);
141-
142-
if (isset($test->failPoint)) {
143-
$this->configureFailPoint($test->failPoint);
144-
}
145-
146-
if (isset($test->expectations)) {
147-
$commandExpectations = CommandExpectations::fromTransactions($context->getClient(), $test->expectations);
148-
$commandExpectations->startMonitoring();
149-
}
150-
151-
foreach ($test->operations as $operation) {
152-
Operation::fromTransactions($operation)->assert($this, $context);
153-
}
154-
155-
$context->session0->endSession();
156-
$context->session1->endSession();
157-
158-
if (isset($commandExpectations)) {
159-
$commandExpectations->stopMonitoring();
160-
$commandExpectations->assert($this, $context);
161-
}
162-
163-
if (isset($test->outcome->collection->data)) {
164-
$this->assertOutcomeCollectionData($test->outcome->collection->data);
165-
}
166-
}
167-
168-
private function provideTests(string $dir): array
169-
{
170-
$testArgs = [];
171-
172-
foreach (glob(__DIR__ . '/' . $dir . '/*.json') as $filename) {
173-
$json = $this->decodeJson(file_get_contents($filename));
174-
$group = basename(dirname($filename)) . '/' . basename($filename, '.json');
175-
$runOn = $json->runOn ?? null;
176-
$data = $json->data ?? [];
177-
// phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
178-
$databaseName = $json->database_name ?? null;
179-
$collectionName = $json->collection_name ?? null;
180-
// phpcs:enable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
181-
182-
foreach ($json->tests as $test) {
183-
$name = $group . ': ' . $test->description;
184-
$testArgs[$name] = [$test, $runOn, $data, $databaseName, $collectionName];
185-
}
186-
}
187-
188-
return $testArgs;
189-
}
190-
19117
/**
19218
* Prose test 1: Test that starting a new transaction on a pinned
19319
* ClientSession unpins the session and normal server selection is performed
@@ -265,73 +91,4 @@ public function testRunningNonTransactionOperationOnPinnedSessionUnpinsSession()
26591

26692
$session->endSession();
26793
}
268-
269-
/**
270-
* Create the collection, since it cannot be created within a transaction.
271-
*/
272-
protected function createTestCollection(): void
273-
{
274-
$context = $this->getContext();
275-
276-
$database = $context->getDatabase();
277-
$database->createCollection($context->collectionName, $context->defaultWriteOptions);
278-
}
279-
280-
/**
281-
* Kill all sessions on the cluster.
282-
*
283-
* This will clean up any open transactions that may remain from a
284-
* previously failed test. For sharded clusters, this command will be run
285-
* on all mongos nodes.
286-
*/
287-
private static function killAllSessions(): void
288-
{
289-
// killAllSessions is not supported on serverless, see CLOUDP-84298
290-
if (static::isServerless()) {
291-
return;
292-
}
293-
294-
$manager = static::createTestManager();
295-
$primary = $manager->selectServer();
296-
297-
$servers = $primary->getType() === Server::TYPE_MONGOS
298-
? $manager->getServers()
299-
: [$primary];
300-
301-
foreach ($servers as $server) {
302-
try {
303-
// Skip servers that do not support sessions
304-
if (! isset($server->getInfo()['logicalSessionTimeoutMinutes'])) {
305-
continue;
306-
}
307-
308-
$server->executeCommand('admin', new Command(['killAllSessions' => []]));
309-
} catch (ServerException $e) {
310-
// Interrupted error is safe to ignore (see: SERVER-38335)
311-
if ($e->getCode() != self::INTERRUPTED) {
312-
throw $e;
313-
}
314-
}
315-
}
316-
}
317-
318-
/**
319-
* Work around potential error executing distinct on sharded clusters.
320-
*
321-
* @see https://github.com/mongodb/specifications/tree/master/source/transactions/tests#why-do-tests-that-run-distinct-sometimes-fail-with-staledbversion
322-
*/
323-
private function preventStaleDbVersionError(array $operations): void
324-
{
325-
if (! $this->isShardedCluster()) {
326-
return;
327-
}
328-
329-
foreach ($operations as $operation) {
330-
if ($operation->name === 'distinct') {
331-
$this->getContext()->getCollection()->distinct('foo');
332-
333-
return;
334-
}
335-
}
336-
}
33794
}

0 commit comments

Comments
 (0)