Skip to content

Commit 28554b9

Browse files
committed
PYTHON-5149 Convert run-tests.sh to a Python script
1 parent 25b2d77 commit 28554b9

File tree

5 files changed

+119
-185
lines changed

5 files changed

+119
-185
lines changed

.evergreen/run-tests.sh

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
#!/bin/bash
2-
set -eux
2+
set -eu
33

44
SCRIPT_DIR=$(dirname ${BASH_SOURCE:-$0})
55
SCRIPT_DIR="$( cd -- "$SCRIPT_DIR" > /dev/null 2>&1 && pwd )"
66
ROOT_DIR="$(dirname $SCRIPT_DIR)"
77

88
pushd $ROOT_DIR
99

10-
export PIP_QUIET=1 # Quiet by default
11-
export PIP_PREFER_BINARY=1 # Prefer binary dists by default
12-
export UV_FROZEN=1 # Do not modify lock files
13-
1410
# Try to source the env file.
1511
if [ -f $SCRIPT_DIR/scripts/env.sh ]; then
1612
echo "Sourcing env inputs"
@@ -27,72 +23,12 @@ else
2723
echo "Missing test inputs, please run 'just setup-test'"
2824
fi
2925

30-
3126
# Source the local secrets export file if available.
3227
if [ -f "./secrets-export.sh" ]; then
3328
. "./secrets-export.sh"
3429
fi
3530

36-
PYTHON_IMPL=$(uv run python -c "import platform; print(platform.python_implementation())")
37-
38-
# Ensure C extensions if applicable.
39-
if [ -z "${NO_EXT:-}" ] && [ "$PYTHON_IMPL" = "CPython" ]; then
40-
uv run --frozen tools/fail_if_no_c.py
41-
fi
42-
43-
if [ -n "${PYMONGOCRYPT_LIB:-}" ]; then
44-
# Ensure pymongocrypt is working properly.
45-
# shellcheck disable=SC2048
46-
uv run ${UV_ARGS} python -c "import pymongocrypt; print('pymongocrypt version: '+pymongocrypt.__version__)"
47-
# shellcheck disable=SC2048
48-
uv run ${UV_ARGS} python -c "import pymongocrypt; print('libmongocrypt version: '+pymongocrypt.libmongocrypt_version())"
49-
# PATH is updated by configure-env.sh for access to mongocryptd.
50-
fi
51-
52-
PYTHON_IMPL=$(uv run python -c "import platform; print(platform.python_implementation())")
53-
echo "Running ${AUTH:-noauth} tests over ${SSL:-nossl} with python $(uv python find)"
54-
uv run python -c 'import sys; print(sys.version)'
55-
56-
# Show the installed packages
57-
# shellcheck disable=SC2048
58-
PIP_QUIET=0 uv run ${UV_ARGS} --with pip pip list
59-
60-
# Record the start time for a perf test.
61-
if [ -n "${TEST_PERF:-}" ]; then
62-
start_time=$(date +%s)
63-
fi
64-
65-
# Run the tests, and store the results in Evergreen compatible XUnit XML
66-
# files in the xunit-results/ directory.
67-
TEST_ARGS=${TEST_ARGS}
68-
if [ "$#" -ne 0 ]; then
69-
TEST_ARGS="$*"
70-
fi
71-
echo "Running tests with $TEST_ARGS and uv args $UV_ARGS..."
72-
if [ -z "${GREEN_FRAMEWORK:-}" ]; then
73-
# shellcheck disable=SC2048
74-
uv run ${UV_ARGS} pytest $TEST_ARGS
75-
else
76-
# shellcheck disable=SC2048
77-
uv run ${UV_ARGS} green_framework_test.py $GREEN_FRAMEWORK -v $TEST_ARGS
78-
fi
79-
echo "Running tests with $TEST_ARGS... done."
80-
81-
# Handle perf test post actions.
82-
if [ -n "${TEST_PERF:-}" ]; then
83-
end_time=$(date +%s)
84-
elapsed_secs=$((end_time-start_time))
85-
86-
cat results.json
87-
88-
echo "{\"failures\": 0, \"results\": [{\"status\": \"pass\", \"exit_code\": 0, \"test_file\": \"BenchMarkTests\", \"start\": $start_time, \"end\": $end_time, \"elapsed\": $elapsed_secs}]}" > report.json
89-
90-
cat report.json
91-
fi
92-
93-
# Handle coverage post actions.
94-
if [ -n "${COVERAGE:-}" ]; then
95-
rm -rf .pytest_cache
96-
fi
31+
# Start the test runner.
32+
uv run ${UV_ARGS} $SCRIPT_DIR/scripts/run_tests.py
9733

9834
popd

.evergreen/scripts/run_tests.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from __future__ import annotations
2+
3+
import json
4+
import logging
5+
import os
6+
import platform
7+
import shlex
8+
import shutil
9+
import subprocess
10+
import sys
11+
from datetime import datetime
12+
from pathlib import Path
13+
14+
import pytest
15+
16+
HERE = Path(__file__).absolute().parent
17+
ROOT = HERE.parent.parent
18+
DRIVERS_TOOLS = os.environ.get("DRIVERS_TOOLS", "").replace(os.sep, "/")
19+
PLATFORM = "windows" if os.name == "nt" else sys.platform.lower()
20+
AUTH = os.environ.get("AUTH", "noauth")
21+
SSL = os.environ.get("SSL", "nossl")
22+
UV_ARGS = os.environ.get("UV_ARGS", "")
23+
TEST_PERF = os.environ.get("TEST_PERF")
24+
GREEN_FRAMEWORK = os.environ.get("GREEN_FRAMEWORK")
25+
TEST_ARGS = os.environ.get("TEST_ARGS", "").split()
26+
27+
LOGGER = logging.getLogger(__name__)
28+
logging.basicConfig(level=logging.INFO, format="%(levelname)-8s %(message)s")
29+
30+
# Ensure C extensions if applicable.
31+
if not os.environ.get("NO_EXT") and platform.python_implementation() == "CPython":
32+
import bson
33+
import pymongo
34+
35+
if not pymongo.has_c() or not bson.has_c():
36+
try:
37+
from pymongo import _cmessage # type:ignore[attr-defined] # noqa: F401
38+
except Exception as e:
39+
LOGGER.exception(e)
40+
try:
41+
from bson import _cbson # type:ignore[attr-defined] # noqa: F401
42+
except Exception as e:
43+
LOGGER.exception(e)
44+
sys.exit("could not load C extensions")
45+
46+
if os.environ.get("PYMONGOCRYPT_LIB"):
47+
# Ensure pymongocrypt is working properly.
48+
import pymongocrypt
49+
50+
LOGGER.info(f"pymongocrypt version: {pymongocrypt.__version__})")
51+
LOGGER.info(f"libmongocrypt version: {pymongocrypt.libmongocrypt_version()})")
52+
53+
LOGGER.info(f"Running {AUTH} tests over {SSL} with python {sys.executable}")
54+
55+
# Show the installed packages. Pip can only be run as a cli.
56+
env = os.environ.copy()
57+
env["PIP_QUIET"] = "0"
58+
subprocess.run(shlex.split(f"uv run {UV_ARGS} --with pip pip list"), env=env, check=True) # noqa: S603
59+
60+
# Record the start time for a perf test.
61+
if TEST_PERF:
62+
start_time = datetime.now()
63+
64+
# Handle green frameworks.
65+
if GREEN_FRAMEWORK:
66+
if GREEN_FRAMEWORK == "eventlet":
67+
import eventlet
68+
69+
# https://github.com/eventlet/eventlet/issues/401
70+
eventlet.sleep()
71+
eventlet.monkey_patch()
72+
elif GREEN_FRAMEWORK == "gevent":
73+
from gevent import monkey
74+
75+
monkey.patch_all()
76+
77+
# Never run async tests with a framework.
78+
if len(TEST_ARGS) <= 1:
79+
TEST_ARGS.extend(["-m", "not default_async and default"])
80+
else:
81+
for i in range(len(TEST_ARGS) - 1):
82+
if "-m" in TEST_ARGS[i]:
83+
TEST_ARGS[i + 1] = f"not default_async and {TEST_ARGS[i + 1]}"
84+
85+
86+
# Run the tests.
87+
pytest.main(TEST_ARGS)
88+
89+
# Handle perf test post actions.
90+
if TEST_PERF:
91+
end_time = datetime.now()
92+
elapsed_secs = (end_time - start_time).total_seconds()
93+
with open("results.json") as fid:
94+
print(json.dump(fid, indent=2)) # noqa: T201
95+
96+
results = dict(
97+
status="pass",
98+
exit_code=0,
99+
test_file="BenchMarkTests",
100+
start=start_time.timestamp(),
101+
end=end_time.timestamp(),
102+
elapsed=elapsed_secs,
103+
)
104+
report = dict(failures=0, results=results)
105+
print(json.dumps(report, indent=2)) # noqa: T201
106+
107+
with open("report.json", "w", newline="\n") as fid:
108+
json.dump(report, fid)
109+
110+
111+
# Handle coverage post actions.
112+
if os.environ.get("COVERAGE"):
113+
shutil.rmtree(".pytest_cache", ignore_errors=True)

.evergreen/scripts/setup_tests.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,9 @@ def handle_test_env() -> None:
228228

229229
write_env("AUTH", AUTH)
230230
write_env("SSL", SSL)
231+
write_env("PIP_QUIET") # Quiet by default
232+
write_env("PIP_PREFER_BINARY") # Prefer binary dists by default
233+
write_env("UV_FROZEN") # Do not modify lock files
231234

232235
# Skip CSOT tests on non-linux platforms.
233236
if PLATFORM != "linux":

green_framework_test.py

Lines changed: 0 additions & 117 deletions
This file was deleted.

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?)|dummy.*)$"
234234
"RET", "ARG", "F405", "B028", "PGH001", "B018", "F403", "RUF015", "E731", "B007",
235235
"UP031", "F401", "B023", "F811"]
236236
"tools/*.py" = ["T201"]
237-
"green_framework_test.py" = ["T201"]
238237
"hatch_build.py" = ["S"]
239238
"_setup.py" = ["SIM112"]
240239

0 commit comments

Comments
 (0)