Skip to content

Commit cd033e7

Browse files
PYTHON-2545 Test Atlas Serverless (#664) (#680)
(cherry picked from commit f07da34)
1 parent be131dd commit cd033e7

37 files changed

+310
-84
lines changed

.evergreen/config.yml

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,12 @@ functions:
424424
export SINGLE_MONGOS_LB_URI="${SINGLE_MONGOS_LB_URI}"
425425
export MULTI_MONGOS_LB_URI="${MULTI_MONGOS_LB_URI}"
426426
fi
427+
if [ -n "${test_serverless}" ]; then
428+
export TEST_SERVERLESS=1
429+
export MONGODB_URI="${MONGODB_URI}"
430+
export SERVERLESS_ATLAS_USER="${SERVERLESS_ATLAS_USER}"
431+
export SERVERLESS_ATLAS_PASSWORD="${SERVERLESS_ATLAS_PASSWORD}"
432+
fi
427433
428434
PYTHON_BINARY=${PYTHON_BINARY} \
429435
PYTHON3_BINARY=${python3_binary} \
@@ -846,9 +852,42 @@ post:
846852
- func: "cleanup"
847853
- func: "teardown_docker"
848854

849-
tasks:
850-
855+
task_groups:
856+
- name: serverless_task_group
857+
setup_group_can_fail_task: true
858+
setup_group_timeout_secs: 1800 # 30 minutes
859+
setup_group:
860+
- func: "fetch source"
861+
- func: "prepare resources"
862+
- command: shell.exec
863+
params:
864+
shell: "bash"
865+
script: |
866+
${PREPARE_SHELL}
867+
set +o xtrace
868+
SERVERLESS_DRIVERS_GROUP=${SERVERLESS_DRIVERS_GROUP} \
869+
SERVERLESS_API_PUBLIC_KEY=${SERVERLESS_API_PUBLIC_KEY} \
870+
SERVERLESS_API_PRIVATE_KEY=${SERVERLESS_API_PRIVATE_KEY} \
871+
PROJECT="mongo-python-driver-312" \
872+
bash ${DRIVERS_TOOLS}/.evergreen/serverless/create-instance.sh
873+
- command: expansions.update
874+
params:
875+
file: serverless-expansion.yml
876+
teardown_group:
877+
- command: shell.exec
878+
params:
879+
script: |
880+
${PREPARE_SHELL}
881+
set +o xtrace
882+
SERVERLESS_DRIVERS_GROUP=${SERVERLESS_DRIVERS_GROUP} \
883+
SERVERLESS_API_PUBLIC_KEY=${SERVERLESS_API_PUBLIC_KEY} \
884+
SERVERLESS_API_PRIVATE_KEY=${SERVERLESS_API_PRIVATE_KEY} \
885+
SERVERLESS_INSTANCE_NAME=${SERVERLESS_INSTANCE_NAME} \
886+
bash ${DRIVERS_TOOLS}/.evergreen/serverless/delete-instance.sh
887+
tasks:
888+
- ".serverless"
851889

890+
tasks:
852891
# Wildcard task. Do you need to find out what tools are available and where?
853892
# Throw it here, and execute this task on all buildvariants
854893
- name: getdata
@@ -1194,6 +1233,11 @@ tasks:
11941233
TOPOLOGY: "sharded_cluster"
11951234
- func: "run tests"
11961235

1236+
- name: "test-serverless"
1237+
tags: ["serverless"]
1238+
commands:
1239+
- func: "run tests"
1240+
11971241
- name: "test-enterprise-auth"
11981242
tags: ["enterprise-auth"]
11991243
commands:
@@ -2132,6 +2176,15 @@ axes:
21322176
test_loadbalancer: true
21332177
batchtime: 10080 # 7 days
21342178

2179+
- id: serverless
2180+
display_name: "Serverless"
2181+
values:
2182+
- id: "enabled"
2183+
display_name: "Serverless"
2184+
variables:
2185+
test_serverless: true
2186+
batchtime: 10080 # 7 days
2187+
21352188
buildvariants:
21362189
- matrix_name: "tests-all"
21372190
matrix_spec:
@@ -2646,6 +2699,21 @@ buildvariants:
26462699
tasks:
26472700
- name: "atlas-connect"
26482701

2702+
- matrix_name: "serverless"
2703+
matrix_spec:
2704+
platform: awslinux
2705+
python-version: *amazon1-pythons
2706+
auth-ssl: auth-ssl
2707+
serverless: "*"
2708+
exclude_spec:
2709+
platform: awslinux
2710+
python-version: "jython2.7"
2711+
auth-ssl: auth-ssl
2712+
serverless: "*"
2713+
display_name: "Serverless ${python-version} ${platform}"
2714+
tasks:
2715+
- "serverless_task_group"
2716+
26492717
- matrix_name: "data-lake-spec-tests"
26502718
matrix_spec:
26512719
platform: ubuntu-16.04

.evergreen/run-tests.sh

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,15 @@ fi
4646
export JAVA_HOME=/opt/java/jdk8
4747

4848
if [ "$AUTH" != "noauth" ]; then
49-
if [ -z "$DATA_LAKE" ]; then
50-
export DB_USER="bob"
51-
export DB_PASSWORD="pwd123"
52-
else
49+
if [ ! -z "$DATA_LAKE" ]; then
5350
export DB_USER="mhuser"
5451
export DB_PASSWORD="pencil"
52+
elif [ ! -z "$TEST_SERVERLESS" ]; then
53+
export DB_USER=$SERVERLESS_ATLAS_USER
54+
export DB_PASSWORD=$SERVERLESS_ATLAS_PASSWORD
55+
else
56+
export DB_USER="bob"
57+
export DB_PASSWORD="pwd123"
5558
fi
5659
fi
5760

test/__init__.py

Lines changed: 64 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
COMPRESSORS = os.environ.get("COMPRESSORS")
9696
MONGODB_API_VERSION = os.environ.get("MONGODB_API_VERSION")
9797
TEST_LOADBALANCER = bool(os.environ.get("TEST_LOADBALANCER"))
98+
TEST_SERVERLESS = bool(os.environ.get("TEST_SERVERLESS"))
9899
SINGLE_MONGOS_LB_URI = os.environ.get("SINGLE_MONGOS_LB_URI")
99100
MULTI_MONGOS_LB_URI = os.environ.get("MULTI_MONGOS_LB_URI")
100101
if TEST_LOADBALANCER:
@@ -105,6 +106,13 @@
105106
host, port = res['nodelist'][0]
106107
db_user = res['username'] or db_user
107108
db_pwd = res['password'] or db_pwd
109+
elif TEST_SERVERLESS:
110+
res = parse_uri(os.environ["MONGODB_URI"])
111+
host, port = res['nodelist'].pop(0)
112+
additional_serverless_mongoses = res['nodelist']
113+
db_user = res['username'] or db_user
114+
db_pwd = res['password'] or db_pwd
115+
TLS_OPTIONS = {'tls': True}
108116

109117

110118
def is_server_resolvable():
@@ -232,6 +240,7 @@ def __init__(self):
232240
self.conn_lock = threading.Lock()
233241
self.is_data_lake = False
234242
self.load_balancer = TEST_LOADBALANCER
243+
self.serverless = TEST_SERVERLESS
235244
if self.load_balancer:
236245
self.default_client_options["loadBalanced"] = True
237246
if COMPRESSORS:
@@ -299,22 +308,26 @@ def _init_client(self):
299308
if self.client:
300309
self.connected = True
301310

302-
try:
303-
self.cmd_line = self.client.admin.command('getCmdLineOpts')
304-
except pymongo.errors.OperationFailure as e:
305-
msg = e.details.get('errmsg', '')
306-
if e.code == 13 or 'unauthorized' in msg or 'login' in msg:
307-
# Unauthorized.
308-
self.auth_enabled = True
309-
else:
310-
raise
311+
if self.serverless:
312+
self.auth_enabled = True
311313
else:
312-
self.auth_enabled = self._server_started_with_auth()
314+
try:
315+
self.cmd_line = self.client.admin.command('getCmdLineOpts')
316+
except pymongo.errors.OperationFailure as e:
317+
msg = e.details.get('errmsg', '')
318+
if e.code == 13 or 'unauthorized' in msg or 'login' in msg:
319+
# Unauthorized.
320+
self.auth_enabled = True
321+
else:
322+
raise
323+
else:
324+
self.auth_enabled = self._server_started_with_auth()
313325

314326
if self.auth_enabled:
315-
# See if db_user already exists.
316-
if not self._check_user_provided():
317-
_create_user(self.client.admin, db_user, db_pwd)
327+
if not self.serverless:
328+
# See if db_user already exists.
329+
if not self._check_user_provided():
330+
_create_user(self.client.admin, db_user, db_pwd)
318331

319332
self.client = self._connect(
320333
host, port, username=db_user, password=db_pwd,
@@ -324,10 +337,13 @@ def _init_client(self):
324337
# May not have this if OperationFailure was raised earlier.
325338
self.cmd_line = self.client.admin.command('getCmdLineOpts')
326339

327-
self.server_status = self.client.admin.command('serverStatus')
328-
if self.storage_engine == "mmapv1":
329-
# MMAPv1 does not support retryWrites=True.
330-
self.default_client_options['retryWrites'] = False
340+
if self.serverless:
341+
self.server_status = {}
342+
else:
343+
self.server_status = self.client.admin.command('serverStatus')
344+
if self.storage_engine == "mmapv1":
345+
# MMAPv1 does not support retryWrites=True.
346+
self.default_client_options['retryWrites'] = False
331347

332348
hello = self.hello
333349
self.sessions_enabled = 'logicalSessionTimeoutMinutes' in hello
@@ -364,33 +380,41 @@ def _init_client(self):
364380
self.nodes = set([(host, port)])
365381
self.w = len(hello.get("hosts", [])) or 1
366382
self.version = Version.from_client(self.client)
367-
self.server_parameters = self.client.admin.command(
368-
'getParameter', '*')
369383

370-
if 'enableTestCommands=1' in self.cmd_line['argv']:
384+
if TEST_SERVERLESS:
371385
self.test_commands_enabled = True
372-
elif 'parsed' in self.cmd_line:
373-
params = self.cmd_line['parsed'].get('setParameter', [])
374-
if 'enableTestCommands=1' in params:
386+
self.has_ipv6 = False
387+
else:
388+
self.server_parameters = self.client.admin.command(
389+
'getParameter', '*')
390+
if 'enableTestCommands=1' in self.cmd_line['argv']:
375391
self.test_commands_enabled = True
376-
else:
377-
params = self.cmd_line['parsed'].get('setParameter', {})
378-
if params.get('enableTestCommands') == '1':
392+
elif 'parsed' in self.cmd_line:
393+
params = self.cmd_line['parsed'].get('setParameter', [])
394+
if 'enableTestCommands=1' in params:
379395
self.test_commands_enabled = True
396+
else:
397+
params = self.cmd_line['parsed'].get('setParameter', {})
398+
if params.get('enableTestCommands') == '1':
399+
self.test_commands_enabled = True
400+
self.has_ipv6 = self._server_started_with_ipv6()
380401

381402
self.is_mongos = (self.hello.get('msg') == 'isdbgrid')
382-
self.has_ipv6 = self._server_started_with_ipv6()
383403
if self.is_mongos:
384-
# Check for another mongos on the next port.
385-
address = self.client.address
386-
next_address = address[0], address[1] + 1
387-
self.mongoses.append(address)
388-
mongos_client = self._connect(*next_address,
389-
**self.default_client_options)
390-
if mongos_client:
391-
hello = mongos_client.admin.command(HelloCompat.LEGACY_CMD)
392-
if hello.get('msg') == 'isdbgrid':
393-
self.mongoses.append(next_address)
404+
if self.serverless:
405+
self.mongoses.append(self.client.address)
406+
self.mongoses.extend(additional_serverless_mongoses)
407+
else:
408+
# Check for another mongos on the next port.
409+
address = self.client.address
410+
next_address = address[0], address[1] + 1
411+
self.mongoses.append(address)
412+
mongos_client = self._connect(
413+
*next_address, **self.default_client_options)
414+
if mongos_client:
415+
hello = mongos_client.admin.command(HelloCompat.LEGACY_CMD)
416+
if hello.get('msg') == 'isdbgrid':
417+
self.mongoses.append(next_address)
394418

395419
def init(self):
396420
with self.conn_lock:
@@ -878,6 +902,9 @@ def setUpClass(cls):
878902
if (client_context.load_balancer and
879903
not getattr(cls, 'RUN_ON_LOAD_BALANCER', False)):
880904
raise SkipTest('this test does not support load balancers')
905+
if (client_context.serverless and
906+
not getattr(cls, 'RUN_ON_SERVERLESS', False)):
907+
raise SkipTest('this test does not support serverless')
881908
cls.client = client_context.client
882909
cls.db = cls.client.pymongo_test
883910
if client_context.auth_enabled:

test/crud/unified/aggregate-let.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"description": "aggregate-let",
3-
"schemaVersion": "1.0",
3+
"schemaVersion": "1.4",
44
"createEntities": [
55
{
66
"client": {
@@ -310,7 +310,8 @@
310310
"description": "Aggregate to collection with let option",
311311
"runOnRequirements": [
312312
{
313-
"minServerVersion": "5.0"
313+
"minServerVersion": "5.0",
314+
"serverless": "forbid"
314315
}
315316
],
316317
"operations": [

test/crud/unified/aggregate-out-readConcern.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"description": "aggregate-out-readConcern",
3-
"schemaVersion": "1.1",
3+
"schemaVersion": "1.4",
44
"runOnRequirements": [
55
{
66
"minServerVersion": "4.1.0",
77
"topologies": [
88
"replicaset",
99
"sharded"
10-
]
10+
],
11+
"serverless": "forbid"
1112
}
1213
],
1314
"createEntities": [

test/crud/v1/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",

test/crud/v1/read/aggregate-out.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
}
1515
],
1616
"minServerVersion": "2.6",
17+
"serverless": "forbid",
1718
"tests": [
1819
{
1920
"description": "Aggregate with $out",

test/crud/v1/read/count-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": "Count documents with collation",

test/crud/v1/read/distinct-collation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
}
1111
],
1212
"minServerVersion": "3.4",
13+
"serverless": "forbid",
1314
"tests": [
1415
{
1516
"description": "Distinct with a collation",

test/crud/v1/read/find-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": "Find with a collation",

0 commit comments

Comments
 (0)