Skip to content

Commit d1b18dd

Browse files
authored
PHPLIB-622 Versioned MongoDB API for Drivers (#816)
* Support new serverParameters runOnRequirement in unified test runner * Sync unified-test-format tests * Run versioned API spec tests This syncs the versioned API spec tests to commit a49cbdf605176a7035c0343779170ce412cc3f0e * Add helper to create client and manager objects * Add build variant to test with requireApiVersion=true * Address code review feedback * Don't export API_VERSION env variable
1 parent 2c80b35 commit d1b18dd

26 files changed

+3203
-64
lines changed

.evergreen/config.yml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ functions:
176176
params:
177177
script: |
178178
${PREPARE_SHELL}
179-
MONGODB_VERSION=${VERSION} ORCHESTRATION_FILE=${ORCHESTRATION_FILE} TOPOLOGY=${TOPOLOGY} AUTH=${AUTH} SSL=${SSL} STORAGE_ENGINE=${STORAGE_ENGINE} sh ${DRIVERS_TOOLS}/.evergreen/run-orchestration.sh
179+
MONGODB_VERSION=${VERSION} ORCHESTRATION_FILE=${ORCHESTRATION_FILE} TOPOLOGY=${TOPOLOGY} AUTH=${AUTH} SSL=${SSL} STORAGE_ENGINE=${STORAGE_ENGINE} REQUIRE_API_VERSION=${REQUIRE_API_VERSION} sh ${DRIVERS_TOOLS}/.evergreen/run-orchestration.sh
180180
# run-orchestration generates expansion file with the MONGODB_URI for the cluster
181181
- command: expansions.update
182182
params:
@@ -215,7 +215,7 @@ functions:
215215
export GCP_EMAIL="${client_side_encryption_gcp_email}"
216216
export GCP_PRIVATEKEY="${client_side_encryption_gcp_privatekey}"
217217
export PATH="${PHP_PATH}/bin:$PATH"
218-
PHP_VERSION=${PHP_VERSION} AUTH=${AUTH} SSL=${SSL} MONGODB_URI="${MONGODB_URI}" sh ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh
218+
API_VERSION=${API_VERSION} PHP_VERSION=${PHP_VERSION} AUTH=${AUTH} SSL=${SSL} MONGODB_URI="${MONGODB_URI}" sh ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh
219219
220220
"run atlas data lake test":
221221
- command: shell.exec
@@ -357,6 +357,17 @@ tasks:
357357
- func: "bootstrap mongohoused"
358358
- func: "run atlas data lake test"
359359

360+
- name: "test-requireApiVersion"
361+
tags: ["versioned_api"]
362+
commands:
363+
- func: "bootstrap mongo-orchestration"
364+
vars:
365+
TOPOLOGY: "server"
366+
AUTH: "auth"
367+
REQUIRE_API_VERSION: "yes"
368+
- func: "run tests"
369+
vars:
370+
API_VERSION: "1"
360371

361372
# }}}
362373

@@ -609,3 +620,10 @@ buildvariants:
609620
run_on: rhel70
610621
tasks:
611622
- name: "test-atlas-data-lake"
623+
624+
- matrix_name: "test-requireApiVersion"
625+
matrix_spec: { "php-edge-versions": "latest-stable", "versions": "latest", "driver-versions": "latest" }
626+
display_name: "Versioned API - ${versions}"
627+
run_on: rhel70
628+
tasks:
629+
- name: "test-requireApiVersion"

.evergreen/run-tests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ AUTH=${AUTH:-noauth}
1212
SSL=${SSL:-nossl}
1313
MONGODB_URI=${MONGODB_URI:-}
1414
TESTS=${TESTS:-}
15+
API_VERSION=${API_VERSION:-}
1516
IS_MATRIX_TESTING=${IS_MATRIX_TESTING:-}
1617

1718
# For matrix testing, we have to determine the correct driver version

tests/ClientFunctionalTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ private function doSetUp()
2828
{
2929
parent::setUp();
3030

31-
$this->client = new Client(static::getUri());
31+
$this->client = static::createTestClient();
3232
$this->client->dropDatabase($this->getDatabaseName());
3333
}
3434

tests/DocumentationExamplesTest.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use MongoDB\BSON\ObjectId;
66
use MongoDB\BSON\UTCDateTime;
7-
use MongoDB\Client;
87
use MongoDB\Database;
98
use MongoDB\Driver\Cursor;
109
use MongoDB\Driver\Exception\Exception;
@@ -1270,7 +1269,7 @@ public function testTransactions_intro_example_1()
12701269

12711270
$this->assertNotNull('This test intentionally performs no assertions');
12721271

1273-
$client = new Client(static::getUri());
1272+
$client = static::createTestClient();
12741273

12751274
/* The WC is required: https://docs.mongodb.com/manual/core/transactions/#transactions-and-locks */
12761275
$client->hr->dropCollection('employees', ['writeConcern' => new WriteConcern('majority')]);
@@ -1445,7 +1444,7 @@ public function testTransactions_retry_example_3()
14451444

14461445
$this->assertNotNull('This test intentionally performs no assertions');
14471446

1448-
$client = new Client(static::getUri());
1447+
$client = static::createTestClient();
14491448

14501449
/* The WC is required: https://docs.mongodb.com/manual/core/transactions/#transactions-and-locks */
14511450
$client->hr->dropCollection('employees', ['writeConcern' => new WriteConcern('majority')]);
@@ -1470,7 +1469,7 @@ public function testCausalConsistency()
14701469
$this->assertNotNull('This test intentionally performs no assertions');
14711470

14721471
// Prep
1473-
$client = new Client(static::getUri());
1472+
$client = static::createTestClient();
14741473
$items = $client->selectDatabase(
14751474
'test',
14761475
[ 'writeConcern' => new WriteConcern(WriteConcern::MAJORITY) ]

tests/FunctionalTestCase.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55
use InvalidArgumentException;
66
use MongoDB\BSON\ObjectId;
7+
use MongoDB\Client;
78
use MongoDB\Driver\Command;
89
use MongoDB\Driver\Exception\CommandException;
910
use MongoDB\Driver\Manager;
1011
use MongoDB\Driver\Query;
1112
use MongoDB\Driver\ReadPreference;
1213
use MongoDB\Driver\Server;
14+
use MongoDB\Driver\ServerApi;
1315
use MongoDB\Driver\WriteConcern;
1416
use MongoDB\Operation\CreateCollection;
1517
use MongoDB\Operation\DatabaseCommand;
@@ -21,6 +23,7 @@
2123
use function count;
2224
use function current;
2325
use function explode;
26+
use function getenv;
2427
use function implode;
2528
use function is_array;
2629
use function is_object;
@@ -51,7 +54,7 @@ private function doSetUp()
5154
{
5255
parent::setUp();
5356

54-
$this->manager = new Manager(static::getUri());
57+
$this->manager = static::createTestManager();
5558
$this->configuredFailPoints = [];
5659
}
5760

@@ -62,6 +65,16 @@ private function doTearDown()
6265
parent::tearDown();
6366
}
6467

68+
public static function createTestClient(string $uri = null, array $options = [], array $driverOptions = []) : Client
69+
{
70+
return new Client($uri ?? static::getUri(), $options, static::appendServerApiOption($driverOptions));
71+
}
72+
73+
public static function createTestManager(string $uri = null, array $options = [], array $driverOptions = []) : Manager
74+
{
75+
return new Manager($uri ?? static::getUri(), $options, static::appendServerApiOption($driverOptions));
76+
}
77+
6578
public static function getUri($allowMultipleMongoses = false)
6679
{
6780
$uri = parent::getUri();
@@ -86,7 +99,7 @@ public static function getUri($allowMultipleMongoses = false)
8699
return $uri;
87100
}
88101

89-
$manager = new Manager($uri);
102+
$manager = static::createTestManager($uri);
90103
if ($manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY))->getType() !== Server::TYPE_MONGOS) {
91104
return $uri;
92105
}
@@ -428,6 +441,15 @@ protected function skipIfTransactionsAreNotSupported()
428441
}
429442
}
430443

444+
private static function appendServerApiOption(array $driverOptions) : array
445+
{
446+
if (getenv('API_VERSION') && ! isset($driverOptions['serverApi'])) {
447+
$driverOptions['serverApi'] = new ServerApi(getenv('API_VERSION'));
448+
}
449+
450+
return $driverOptions;
451+
}
452+
431453
/**
432454
* Disables any fail points that were configured earlier in the test.
433455
*

tests/Operation/FindAndModifyFunctionalTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace MongoDB\Tests\Operation;
44

55
use MongoDB\Driver\BulkWrite;
6-
use MongoDB\Driver\Manager;
76
use MongoDB\Driver\ReadPreference;
87
use MongoDB\Model\BSONDocument;
98
use MongoDB\Operation\FindAndModify;
@@ -17,7 +16,7 @@ class FindAndModifyFunctionalTest extends FunctionalTestCase
1716
*/
1817
public function testManagerReadConcernIsOmitted()
1918
{
20-
$manager = new Manager(static::getUri(), ['readConcernLevel' => 'majority']);
19+
$manager = static::createTestManager(null, ['readConcernLevel' => 'majority']);
2120
$server = $manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
2221

2322
(new CommandObserver())->observe(

tests/Operation/WatchFunctionalTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use MongoDB\Driver\Exception\ConnectionTimeoutException;
1212
use MongoDB\Driver\Exception\LogicException;
1313
use MongoDB\Driver\Exception\ServerException;
14-
use MongoDB\Driver\Manager;
1514
use MongoDB\Driver\Monitoring\CommandSucceededEvent;
1615
use MongoDB\Driver\ReadPreference;
1716
use MongoDB\Driver\WriteConcern;
@@ -166,7 +165,7 @@ public function testNextResumesAfterConnectionException()
166165
/* In order to trigger a dropped connection, we'll use a new client with
167166
* a socket timeout that is less than the change stream's maxAwaitTimeMS
168167
* option. */
169-
$manager = new Manager(static::getUri(), ['socketTimeoutMS' => 50]);
168+
$manager = static::createTestManager(null, ['socketTimeoutMS' => 50]);
170169
$primaryServer = $manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
171170

172171
$operation = new Watch($manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);

tests/SpecTests/AtlasDataLakeSpecTest.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace MongoDB\Tests\SpecTests;
44

5-
use MongoDB\Client;
65
use MongoDB\Driver\Command;
76
use MongoDB\Driver\Cursor;
87
use MongoDB\Tests\CommandObserver;
@@ -135,7 +134,7 @@ public function testKillCursors()
135134

136135
(new CommandObserver())->observe(
137136
function () {
138-
$client = new Client(static::getUri());
137+
$client = static::createTestClient();
139138
$client->test->driverdata->find([], ['batchSize' => 2, 'limit' => 3]);
140139
},
141140
function (array $event) use (&$cursorId, &$cursorNamespace) {
@@ -205,7 +204,7 @@ public function testConnectWithoutAuth()
205204

206205
$uri = $parts['scheme'] . '://' . $parts['host'] . $port . $path . $query;
207206

208-
$client = new Client($uri);
207+
$client = static::createTestClient($uri);
209208
$cursor = $client->selectDatabase($this->getDatabaseName())->command(['ping' => 1]);
210209

211210
$this->assertInstanceOf(Cursor::class, $cursor);
@@ -217,7 +216,7 @@ public function testConnectWithoutAuth()
217216
*/
218217
public function testConnectwithSCRAMSHA1()
219218
{
220-
$client = new Client(static::getUri(), ['authMechanism' => 'SCRAM-SHA-1']);
219+
$client = static::createTestClient(null, ['authMechanism' => 'SCRAM-SHA-1']);
221220
$cursor = $client->selectDatabase($this->getDatabaseName())->command(['ping' => 1]);
222221

223222
$this->assertInstanceOf(Cursor::class, $cursor);
@@ -229,7 +228,7 @@ public function testConnectwithSCRAMSHA1()
229228
*/
230229
public function testConnectwithSCRAMSHA256()
231230
{
232-
$client = new Client(static::getUri(), ['authMechanism' => 'SCRAM-SHA-256']);
231+
$client = static::createTestClient(null, ['authMechanism' => 'SCRAM-SHA-256']);
233232
$cursor = $client->selectDatabase($this->getDatabaseName())->command(['ping' => 1]);
234233

235234
$this->assertInstanceOf(Cursor::class, $cursor);

tests/SpecTests/ClientSideEncryptionSpecTest.php

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use Closure;
66
use MongoDB\BSON\Binary;
77
use MongoDB\BSON\Int64;
8-
use MongoDB\Client;
98
use MongoDB\Collection;
109
use MongoDB\Driver\ClientEncryption;
1110
use MongoDB\Driver\Exception\AuthenticationException;
@@ -206,7 +205,7 @@ public function testDataKeyAndDoubleEncryption(string $providerName, $masterKey)
206205
'keyVaultClient' => $client,
207206
];
208207

209-
$clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
208+
$clientEncrypted = static::createTestClient(null, [], ['autoEncryption' => $autoEncryptionOpts]);
210209
$clientEncryption = $clientEncrypted->createClientEncryption($encryptionOpts);
211210

212211
$commands = [];
@@ -323,7 +322,7 @@ public function testExternalKeyVault($withExternalKeyVault)
323322
];
324323

325324
if ($withExternalKeyVault) {
326-
$encryptionOpts['keyVaultClient'] = new Client(static::getUri(), ['username' => 'fake-user', 'password' => 'fake-pwd']);
325+
$encryptionOpts['keyVaultClient'] = static::createTestClient(null, ['username' => 'fake-user', 'password' => 'fake-pwd']);
327326
}
328327

329328
$autoEncryptionOpts = $encryptionOpts + [
@@ -332,7 +331,7 @@ public function testExternalKeyVault($withExternalKeyVault)
332331
],
333332
];
334333

335-
$clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
334+
$clientEncrypted = static::createTestClient(null, [], ['autoEncryption' => $autoEncryptionOpts]);
336335
$clientEncryption = $clientEncrypted->createClientEncryption($encryptionOpts);
337336

338337
try {
@@ -469,7 +468,7 @@ public function testBSONSizeLimitsAndBatchSplitting(Closure $test)
469468
'keyVaultClient' => $client,
470469
];
471470

472-
$clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
471+
$clientEncrypted = static::createTestClient(null, [], ['autoEncryption' => $autoEncryptionOpts]);
473472

474473
$collection = $clientEncrypted->selectCollection('db', 'coll');
475474

@@ -483,7 +482,7 @@ public function testBSONSizeLimitsAndBatchSplitting(Closure $test)
483482
*/
484483
public function testViewsAreProhibited()
485484
{
486-
$client = new Client(static::getUri());
485+
$client = static::createTestClient();
487486

488487
$client->selectCollection('db', 'view')->drop();
489488
$client->selectDatabase('db')->command(['create' => 'view', 'viewOn' => 'coll']);
@@ -495,7 +494,7 @@ public function testViewsAreProhibited()
495494
],
496495
];
497496

498-
$clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
497+
$clientEncrypted = static::createTestClient(null, [], ['autoEncryption' => $autoEncryptionOpts]);
499498

500499
try {
501500
$clientEncrypted->selectCollection('db', 'view')->insertOne(['foo' => 'bar']);
@@ -557,7 +556,7 @@ public function testCorpus($schemaMap = true)
557556
$corpus = (array) $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus.json'));
558557
$corpusCopied = [];
559558

560-
$clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
559+
$clientEncrypted = static::createTestClient(null, [], ['autoEncryption' => $autoEncryptionOpts]);
561560
$clientEncryption = $clientEncrypted->createClientEncryption($encryptionOpts);
562561

563562
$collection = $clientEncrypted->selectCollection('db', 'coll');
@@ -621,7 +620,7 @@ public function testCorpus($schemaMap = true)
621620
*/
622621
public function testCustomEndpoint(Closure $test)
623622
{
624-
$client = new Client(static::getUri());
623+
$client = static::createTestClient();
625624

626625
$clientEncryption = $client->createClientEncryption([
627626
'keyVaultNamespace' => 'keyvault.datakeys',
@@ -758,7 +757,7 @@ public function testBypassSpawningMongocryptdViaBypassSpawn()
758757
],
759758
];
760759

761-
$clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
760+
$clientEncrypted = static::createTestClient(null, [], ['autoEncryption' => $autoEncryptionOpts]);
762761

763762
try {
764763
$clientEncrypted->selectCollection('db', 'coll')->insertOne(['encrypted' => 'test']);
@@ -787,11 +786,11 @@ public function testBypassSpawningMongocryptdViaBypassAutoEncryption()
787786
],
788787
];
789788

790-
$clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
789+
$clientEncrypted = static::createTestClient(null, [], ['autoEncryption' => $autoEncryptionOpts]);
791790

792791
$clientEncrypted->selectCollection('db', 'coll')->insertOne(['encrypted' => 'test']);
793792

794-
$clientMongocryptd = new Client('mongodb://localhost:27021');
793+
$clientMongocryptd = static::createTestClient('mongodb://localhost:27021');
795794

796795
$this->expectException(ConnectionTimeoutException::class);
797796
$clientMongocryptd->selectDatabase('db')->command(['isMaster' => true]);

0 commit comments

Comments
 (0)