Skip to content

Commit ce61fc8

Browse files
authored
PHPLIB-683 Test against Proxy as a Mongos (#854)
* Split transactions tests for more targeted execution The tests for transactions are the same for the classic and convenient APIs. Since the serverless spec excludes the convenient API from testing, we need to split this so we can only target the classic API for testing. * PHPLIB-684 Add test group annotations for serverless spec tests * PHPLIB-685 Sync tests for serverless testing * PHPLIB-688 Report serverless mode in unified test runner * Support passing authentication options to test framework * Don't run killAllSessions on serverless * PHPLIB-688 Check serverless requirement in legacy spec test runner * PHPLIB-702 Skip crud-v1 tests that use disabled serverless features * PHPLIB-686 Run serverless tests on evergreen * Package serverless for better local debugging * Add note about environment variables overriding URI credentials * PHPLIB-715 Skip failing mapReduce test * Fix wrong driver identifier for serverless tests
1 parent e787475 commit ce61fc8

File tree

94 files changed

+572
-128
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+572
-128
lines changed

.evergreen/config.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,38 @@ functions:
199199
script: |
200200
DRIVERS_TOOLS="${DRIVERS_TOOLS}" sh ${DRIVERS_TOOLS}/.evergreen/atlas_data_lake/run-mongohouse-local.sh
201201
202+
"create serverless instance":
203+
- command: shell.exec
204+
params:
205+
working_dir: "src"
206+
shell: bash
207+
script: |-
208+
${PREPARE_SHELL}
209+
export PROJECT=${PROJECT}
210+
export SERVERLESS_DRIVERS_GROUP=${SERVERLESS_DRIVERS_GROUP}
211+
export SERVERLESS_API_PUBLIC_KEY=${SERVERLESS_API_PUBLIC_KEY}
212+
export SERVERLESS_API_PRIVATE_KEY=${SERVERLESS_API_PRIVATE_KEY}
213+
export SERVERLESS_ATLAS_USER=${SERVERLESS_ATLAS_USER}
214+
export SERVERLESS_ATLAS_PASSWORD=${SERVERLESS_ATLAS_PASSWORD}
215+
sh ${PROJECT_DIRECTORY}/.evergreen/serverless/create-instance.sh
216+
- command: expansions.update
217+
params:
218+
file: src/serverless-expansion.yml
219+
220+
"delete serverless instance":
221+
- command: shell.exec
222+
params:
223+
shell: bash
224+
script: |-
225+
set -o errexit
226+
export SERVERLESS_DRIVERS_GROUP=${SERVERLESS_DRIVERS_GROUP}
227+
export SERVERLESS_API_PUBLIC_KEY=${SERVERLESS_API_PUBLIC_KEY}
228+
export SERVERLESS_API_PRIVATE_KEY=${SERVERLESS_API_PRIVATE_KEY}
229+
export SERVERLESS_ATLAS_USER=${SERVERLESS_ATLAS_USER}
230+
export SERVERLESS_ATLAS_PASSWORD=${SERVERLESS_ATLAS_PASSWORD}
231+
export SERVERLESS_INSTANCE_NAME=${SERVERLESS_INSTANCE_NAME}
232+
sh ${PROJECT_DIRECTORY}/.evergreen/serverless/delete-instance.sh
233+
202234
"run tests":
203235
- command: shell.exec
204236
type: test
@@ -226,6 +258,20 @@ functions:
226258
export PATH="${PHP_PATH}/bin:$PATH"
227259
PHP_VERSION=${PHP_VERSION} TESTS="atlas-data-lake" AUTH=${AUTH} SSL=${SSL} MONGODB_URI="${MONGODB_URI}" sh ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh
228260
261+
"run serverless tests":
262+
- command: shell.exec
263+
type: test
264+
params:
265+
working_dir: "src"
266+
shell: bash
267+
script: |-
268+
${PREPARE_SHELL}
269+
export MONGODB_IS_SERVERLESS=on
270+
export MONGODB_USERNAME=${SERVERLESS_ATLAS_USER}
271+
export MONGODB_PASSWORD=${SERVERLESS_ATLAS_PASSWORD}
272+
export PATH="${PHP_PATH}/bin:$PATH"
273+
PHP_VERSION=${PHP_VERSION} TESTS="serverless" MONGODB_URI="${MONGODB_URI}" sh ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh
274+
229275
"cleanup":
230276
- command: shell.exec
231277
params:
@@ -377,6 +423,15 @@ tasks:
377423
- func: "run tests"
378424
vars:
379425
TESTS: "versioned-api"
426+
427+
- name: "test-serverless"
428+
tags: ["serverless"]
429+
commands:
430+
- func: "create serverless instance"
431+
vars:
432+
PROJECT: "mongo-php-library"
433+
- func: "run serverless tests"
434+
- func: "delete serverless instance"
380435
# }}}
381436

382437

@@ -631,3 +686,10 @@ buildvariants:
631686
run_on: rhel70
632687
tasks:
633688
- .versioned-api
689+
690+
- matrix_name: "serverless"
691+
matrix_spec: { "php-edge-versions": "latest-stable", "driver-versions": "latest-dev" }
692+
display_name: "Serverless"
693+
run_on: rhel70
694+
tasks:
695+
- .serverless

.evergreen/run-tests.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ case "$TESTS" in
6363
php vendor/bin/simple-phpunit --configuration phpunit.evergreen.xml --group versioned-api $PHPUNIT_OPTS
6464
;;
6565

66+
serverless)
67+
php vendor/bin/simple-phpunit --configuration phpunit.evergreen.xml --group serverless $PHPUNIT_OPTS
68+
;;
69+
6670
*)
6771
php vendor/bin/simple-phpunit --configuration phpunit.evergreen.xml $PHPUNIT_OPTS
6872
;;
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set +o xtrace # disable xtrace to ensure credentials aren't leaked
5+
6+
if [ -z "$PROJECT" ]; then
7+
echo "Project name must be provided via PROJECT environment variable"
8+
exit 1
9+
fi
10+
INSTANCE_NAME="$RANDOM-$PROJECT"
11+
12+
if [ -z "$SERVERLESS_DRIVERS_GROUP" ]; then
13+
echo "Drivers Atlas group must be provided via SERVERLESS_DRIVERS_GROUP environment variable"
14+
exit 1
15+
fi
16+
17+
if [ -z "$SERVERLESS_API_PRIVATE_KEY" ]; then
18+
echo "Atlas API private key must be provided via SERVERLESS_API_PRIVATE_KEY environment variable"
19+
exit 1
20+
fi
21+
22+
if [ -z "$SERVERLESS_API_PUBLIC_KEY" ]; then
23+
echo "Atlas API public key must be provided via SERVERLESS_API_PUBLIC_KEY environment variable"
24+
exit 1
25+
fi
26+
27+
echo "creating new serverless instance \"${INSTANCE_NAME}\"..."
28+
29+
DIR=$(dirname $0)
30+
API_BASE_URL="https://account-dev.mongodb.com/api/atlas/v1.0/groups/$SERVERLESS_DRIVERS_GROUP"
31+
32+
curl \
33+
-u "$SERVERLESS_API_PUBLIC_KEY:$SERVERLESS_API_PRIVATE_KEY" \
34+
--silent \
35+
--show-error \
36+
-X POST \
37+
--digest \
38+
--header "Accept: application/json" \
39+
--header "Content-Type: application/json" \
40+
"$API_BASE_URL/serverless?pretty=true" \
41+
--data "
42+
{
43+
\"name\" : \"${INSTANCE_NAME}\",
44+
\"providerSettings\" : {
45+
\"providerName\": \"SERVERLESS\",
46+
\"backingProviderName\": \"GCP\",
47+
\"instanceSizeName\" : \"SERVERLESS_V2\",
48+
\"regionName\" : \"CENTRAL_US\"
49+
}
50+
}"
51+
52+
echo ""
53+
54+
if [ "Windows_NT" = "$OS" ]; then
55+
PYTHON_BINARY=C:/python/Python38/python.exe
56+
else
57+
PYTHON_BINARY=python
58+
fi
59+
60+
SECONDS=0
61+
while [ true ]; do
62+
API_RESPONSE=`SERVERLESS_INSTANCE_NAME=$INSTANCE_NAME bash $DIR/get-instance.sh`
63+
STATE_NAME=`echo $API_RESPONSE | $PYTHON_BINARY -c "import sys, json; print(json.load(sys.stdin)['stateName'])" | tr -d '\r\n'`
64+
65+
if [ "$STATE_NAME" = "IDLE" ]; then
66+
duration="$SECONDS"
67+
echo "setup done! ($(($duration / 60))m $(($duration % 60))s elapsed)"
68+
echo "SERVERLESS_INSTANCE_NAME=\"$INSTANCE_NAME\""
69+
SRV_ADDRESS=$(echo $API_RESPONSE | $PYTHON_BINARY -c "import sys, json; print(json.load(sys.stdin)['connectionStrings']['standardSrv'])" | tr -d '\r\n')
70+
echo "MONGODB_SRV_URI=\"$SRV_ADDRESS\""
71+
STANDARD_ADDRESS=$(echo $API_RESPONSE | $PYTHON_BINARY -c "import sys, json; print(json.load(sys.stdin)['connectionStrings']['standard'].replace('&authSource=admin', ''))" | tr -d '\r\n')
72+
echo "MONGODB_URI=\"$STANDARD_ADDRESS\""
73+
cat <<EOF > serverless-expansion.yml
74+
MONGODB_URI: "$STANDARD_ADDRESS"
75+
MONGODB_SRV_URI: "$SRV_ADDRESS"
76+
SERVERLESS_INSTANCE_NAME: "$INSTANCE_NAME"
77+
SSL: ssl
78+
AUTH: auth
79+
TOPOLOGY: sharded_cluster
80+
SERVERLESS: serverless
81+
EOF
82+
exit 0
83+
else
84+
echo "setup still in progress, status=$STATE_NAME, sleeping for 1 minute..."
85+
sleep 60
86+
fi
87+
done
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set +o xtrace
5+
6+
if [ -z "$SERVERLESS_INSTANCE_NAME" ]; then
7+
echo "Instance name must be provided via SERVERLESS_INSTANCE_NAME environment variable"
8+
exit 1
9+
fi
10+
11+
if [ -z "$SERVERLESS_DRIVERS_GROUP" ]; then
12+
echo "Drivers Atlas group must be provided via SERVERLESS_DRIVERS_GROUP environment variable"
13+
exit 1
14+
fi
15+
16+
if [ -z "$SERVERLESS_API_PRIVATE_KEY" ]; then
17+
echo "Atlas API private key must be provided via SERVERLESS_API_PRIVATE_KEY environment variable"
18+
exit 1
19+
fi
20+
21+
if [ -z "$SERVERLESS_API_PUBLIC_KEY" ]; then
22+
echo "Atlas API public key must be provided via SERVERLESS_API_PUBLIC_KEY environment variable"
23+
exit 1
24+
fi
25+
26+
echo "deleting serverless instance \"${SERVERLESS_INSTANCE_NAME}\"..."
27+
28+
API_BASE_URL="https://account-dev.mongodb.com/api/atlas/v1.0/groups/$SERVERLESS_DRIVERS_GROUP"
29+
30+
curl \
31+
--silent \
32+
--show-error \
33+
-u "$SERVERLESS_API_PUBLIC_KEY:$SERVERLESS_API_PRIVATE_KEY" \
34+
-X DELETE \
35+
--digest \
36+
--header "Accept: application/json" \
37+
--header "Content-Type: application/json" \
38+
"${API_BASE_URL}/serverless/${SERVERLESS_INSTANCE_NAME}?pretty=true"
39+
40+
echo ""

.evergreen/serverless/get-instance.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set +o xtrace
5+
6+
if [ -z "$SERVERLESS_INSTANCE_NAME" ]; then
7+
echo "Instance name must be provided via SERVERLESS_INSTANCE_NAME environment variable"
8+
exit 1
9+
fi
10+
11+
if [ -z "$SERVERLESS_DRIVERS_GROUP" ]; then
12+
echo "Drivers Atlas group must be provided via SERVERLESS_DRIVERS_GROUP environment variable"
13+
exit 1
14+
fi
15+
16+
if [ -z "$SERVERLESS_API_PRIVATE_KEY" ]; then
17+
echo "Atlas API private key must be provided via SERVERLESS_API_PRIVATE_KEY environment variable"
18+
exit 1
19+
fi
20+
21+
if [ -z "$SERVERLESS_API_PUBLIC_KEY" ]; then
22+
echo "Atlas API public key must be provided via SERVERLESS_API_PUBLIC_KEY environment variable"
23+
exit 1
24+
fi
25+
26+
API_BASE_URL="https://account-dev.mongodb.com/api/private/nds/serverless/groups/$SERVERLESS_DRIVERS_GROUP"
27+
28+
curl \
29+
--silent \
30+
--show-error \
31+
-u "$SERVERLESS_API_PUBLIC_KEY:$SERVERLESS_API_PRIVATE_KEY" \
32+
-X GET \
33+
--digest \
34+
--header "Accept: application/json" \
35+
"${API_BASE_URL}/instances/${SERVERLESS_INSTANCE_NAME}?pretty=true" \
36+
37+
echo ""

CONTRIBUTING.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ The `phpunit.xml.dist` file is used as the default configuration file for the
3434
test suite. In addition to various PHPUnit options, it defines required
3535
`MONGODB_URI` and `MONGODB_DATABASE` environment variables. You may customize
3636
this configuration by creating your own `phpunit.xml` file based on the
37-
`phpunit.xml.dist` file we provide.
37+
`phpunit.xml.dist` file we provide. To run the tests in serverless mode, set the
38+
`MONGODB_IS_SERVERLESS` environment variable to `on`.
39+
40+
To run tests against a cluster that requires authentication, either include the
41+
credentials in the connection string given in the `MONGODB_URI` environment
42+
variable, or set the `MONGODB_USERNAME` and `MONGODB_PASSWORD` environment
43+
variables accordingly. Note that values defined through the environment override
44+
credentials present in the URI.
3845

3946
By default, the `simple-phpunit` binary chooses the correct PHPUnit version for
4047
the PHP version you are running. To run tests against a specific PHPUnit version,

tests/Collection/CrudSpecFunctionalTest.php

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,15 @@
3232
*
3333
* @see https://github.com/mongodb/specifications/tree/master/source/crud/tests
3434
*
35+
* @group serverless
3536
* @group matrix-testing-exclude-server-5.0-driver-4.0
3637
*/
3738
class CrudSpecFunctionalTest extends FunctionalTestCase
3839
{
40+
public const SERVERLESS_ALLOW = 'allow';
41+
public const SERVERLESS_FORBID = 'forbid';
42+
public const SERVERLESS_REQUIRE = 'require';
43+
3944
/** @var Collection */
4045
private $expectedCollection;
4146

@@ -50,12 +55,14 @@ public function setUp(): void
5055
/**
5156
* @dataProvider provideSpecificationTests
5257
*/
53-
public function testSpecification(array $initialData, array $test, $minServerVersion, $maxServerVersion): void
58+
public function testSpecification(array $initialData, array $test, $minServerVersion, $maxServerVersion, $serverless): void
5459
{
5560
if (isset($minServerVersion) || isset($maxServerVersion)) {
5661
$this->checkServerVersion($minServerVersion, $maxServerVersion);
5762
}
5863

64+
$this->checkServerlessRequirement($serverless);
65+
5966
$expectedData = $test['outcome']['collection']['data'] ?? null;
6067
$this->initializeData($initialData, $expectedData);
6168

@@ -83,12 +90,15 @@ public function provideSpecificationTests()
8390
foreach (glob(__DIR__ . '/spec-tests/*/*.json') as $filename) {
8491
$json = json_decode(file_get_contents($filename), true);
8592

86-
$minServerVersion = $json['minServerVersion'] ?? null;
87-
$maxServerVersion = $json['maxServerVersion'] ?? null;
88-
8993
foreach ($json['tests'] as $test) {
9094
$name = str_replace(' ', '_', $test['description']);
91-
$testArgs[$name] = [$json['data'], $test, $minServerVersion, $maxServerVersion];
95+
$testArgs[$name] = [
96+
$json['data'],
97+
$test,
98+
$json['minServerVersion'] ?? null,
99+
$json['maxServerVersion'] ?? null,
100+
$json['serverless'] ?? null,
101+
];
92102
}
93103
}
94104

@@ -113,6 +123,32 @@ private function assertEquivalentCollections(Collection $expectedCollection, Col
113123
}
114124
}
115125

126+
private function checkServerlessRequirement(?string $serverless): void
127+
{
128+
switch ($serverless) {
129+
case null:
130+
case self::SERVERLESS_ALLOW:
131+
return;
132+
133+
case self::SERVERLESS_FORBID:
134+
if ($this->isServerless()) {
135+
$this->markTestSkipped('Test does not apply on serverless');
136+
}
137+
138+
return;
139+
140+
case self::SERVERLESS_REQUIRE:
141+
if (! $this->isServerless()) {
142+
$this->markTestSkipped('Test requires serverless');
143+
}
144+
145+
return;
146+
147+
default:
148+
$this->fail(sprintf('Unknown serverless requirement "%s".', $serverless));
149+
}
150+
}
151+
116152
/**
117153
* Checks that the server version is within the allowed bounds (if any).
118154
*

tests/Collection/spec-tests/read/aggregate-collation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
}
77
],
88
"minServerVersion": "3.4",
9+
"serverless": "forbid",
910
"tests": [
1011
{
1112
"description": "Aggregate with collation",

0 commit comments

Comments
 (0)