2
2
3
3
import argparse
4
4
import base64
5
+ import dataclasses
6
+ import io
5
7
import logging
6
8
import os
7
9
import platform
8
10
import shlex
11
+ import shutil
9
12
import stat
10
13
import subprocess
11
14
import sys
15
+ import tarfile
12
16
from pathlib import Path
13
17
from typing import Any
18
+ from urllib import request
14
19
15
20
HERE = Path (__file__ ).absolute ().parent
16
21
ROOT = HERE .parent .parent
17
22
ENV_FILE = HERE / "test-env.sh"
18
23
DRIVERS_TOOLS = os .environ .get ("DRIVERS_TOOLS" , "" ).replace (os .sep , "/" )
24
+ PLATFORM = "windows" if os .name == "nt" else sys .platform
19
25
20
26
LOGGER = logging .getLogger (__name__ )
21
27
logging .basicConfig (level = logging .INFO , format = "%(levelname)-8s %(message)s" )
63
69
GROUP_MAP = dict (mockupdb = "mockupdb" , perf = "perf" )
64
70
65
71
72
+ @dataclasses .dataclass
73
+ class Distro :
74
+ name : str
75
+ version_id : str
76
+ arch : str
77
+
78
+
66
79
def write_env (name : str , value : Any = "1" ) -> None :
67
80
with ENV_FILE .open ("a" , newline = "\n " ) as fid :
68
81
# Remove any existing quote chars.
@@ -118,6 +131,69 @@ def get_options():
118
131
return opts
119
132
120
133
134
+ def get_distro () -> Distro :
135
+ name = ""
136
+ version_id = ""
137
+ arch = platform .machine ()
138
+ with open ("/etc/os-release" ) as fid :
139
+ for line in fid .readlines ():
140
+ line = line .replace ('"' , "" ) # noqa: PLW2901
141
+ if line .startswith ("NAME=" ):
142
+ _ , _ , name = line .strip ().partition ("=" )
143
+ if line .startswith ("VERSION_ID=" ):
144
+ _ , _ , version_id = line .strip ().partition ("=" )
145
+ return Distro (name = name , version_id = version_id , arch = arch )
146
+
147
+
148
+ def setup_libmongocrypt ():
149
+ target = ""
150
+ if PLATFORM == "windows" :
151
+ # PYTHON-2808 Ensure this machine has the CA cert for google KMS.
152
+ if is_set ("TEST_FLE_GCP_AUTO" ):
153
+ run_command ('powershell.exe "Invoke-WebRequest -URI https://oauth2.googleapis.com/"' )
154
+ target = "windows-test"
155
+
156
+ elif PLATFORM == "darwin" :
157
+ target = "macos"
158
+
159
+ else :
160
+ distro = get_distro ()
161
+ if distro .name .startswith ("Debian" ):
162
+ target = f"debian{ distro .version_id } "
163
+ elif distro .name .startswith ("Red Hat" ):
164
+ if distro .version_id .startswith ("7" ):
165
+ target = "rhel-70-64-bit"
166
+ elif distro .version_id .startswith ("8" ):
167
+ if distro .arch == "aarch64" :
168
+ target = "rhel-82-arm64"
169
+ else :
170
+ target = "rhel-80-64-bit"
171
+
172
+ if not is_set ("LIBMONGOCRYPT_URL" ):
173
+ if not target :
174
+ raise ValueError ("Cannot find libmongocrypt target for current platform!" )
175
+ url = f"https://s3.amazonaws.com/mciuploads/libmongocrypt/{ target } /master/latest/libmongocrypt.tar.gz"
176
+ else :
177
+ url = os .environ ["LIBMONGOCRYPT_URL" ]
178
+
179
+ shutil .rmtree (HERE / "libmongocrypt" , ignore_errors = True )
180
+
181
+ LOGGER .info (f"Fetching { url } ..." )
182
+ with request .urlopen (request .Request (url ), timeout = 15.0 ) as response : # noqa: S310
183
+ if response .status == 200 :
184
+ fileobj = io .BytesIO (response .read ())
185
+ with tarfile .open ("libmongocrypt.tar.gz" , fileobj = fileobj ) as fid :
186
+ fid .extractall (Path .cwd () / "libmongocrypt" )
187
+ LOGGER .info (f"Fetching { url } ... done." )
188
+
189
+ run_command ("ls -la libmongocrypt" )
190
+ run_command ("ls -la libmongocrypt/nocrypto" )
191
+
192
+ if PLATFORM == "windows" :
193
+ # libmongocrypt's windows dll is not marked executable.
194
+ run_command ("chmod +x libmongocrypt/nocrypto/bin/mongocrypt.dll" )
195
+
196
+
121
197
def handle_test_env () -> None :
122
198
opts = get_options ()
123
199
test_name = opts .test_name
@@ -209,7 +285,7 @@ def handle_test_env() -> None:
209
285
210
286
if test_name == "enterprise_auth" :
211
287
config = read_env (f"{ ROOT } /secrets-export.sh" )
212
- if os . name == "nt " :
288
+ if PLATFORM == "windows " :
213
289
LOGGER .info ("Setting GSSAPI_PASS" )
214
290
write_env ("GSSAPI_PASS" , config ["SASL_PASS" ])
215
291
write_env ("GSSAPI_CANONICALIZE" , "true" )
@@ -266,19 +342,19 @@ def handle_test_env() -> None:
266
342
if test_name in ["encryption" , "kms" ]:
267
343
# Check for libmongocrypt download.
268
344
if not (ROOT / "libmongocrypt" ).exists ():
269
- run_command ( f"bash { HERE . as_posix () } /setup-libmongocrypt.sh" )
345
+ setup_libmongocrypt ( )
270
346
271
347
# TODO: Test with 'pip install pymongocrypt'
272
348
UV_ARGS .append ("--group pymongocrypt_source" )
273
349
274
350
# Use the nocrypto build to avoid dependency issues with older windows/python versions.
275
351
BASE = ROOT / "libmongocrypt/nocrypto"
276
- if sys . platform == "linux" :
352
+ if PLATFORM == "linux" :
277
353
if (BASE / "lib/libmongocrypt.so" ).exists ():
278
354
PYMONGOCRYPT_LIB = BASE / "lib/libmongocrypt.so"
279
355
else :
280
356
PYMONGOCRYPT_LIB = BASE / "lib64/libmongocrypt.so"
281
- elif sys . platform == "darwin" :
357
+ elif PLATFORM == "darwin" :
282
358
PYMONGOCRYPT_LIB = BASE / "lib/libmongocrypt.dylib"
283
359
else :
284
360
PYMONGOCRYPT_LIB = BASE / "bin/mongocrypt.dll"
@@ -300,7 +376,7 @@ def handle_test_env() -> None:
300
376
config = read_env (f"{ DRIVERS_TOOLS } /mo-expansion.sh" )
301
377
CRYPT_SHARED_DIR = Path (config ["CRYPT_SHARED_LIB_PATH" ]).parent .as_posix ()
302
378
LOGGER .info ("Using crypt_shared_dir %s" , CRYPT_SHARED_DIR )
303
- if os . name == "nt " :
379
+ if PLATFORM == "windows " :
304
380
write_env ("PATH" , f"{ CRYPT_SHARED_DIR } :$PATH" )
305
381
else :
306
382
write_env (
0 commit comments