diff --git a/.evergreen/generated_configs/functions.yml b/.evergreen/generated_configs/functions.yml index e442973c30..df7393de4c 100644 --- a/.evergreen/generated_configs/functions.yml +++ b/.evergreen/generated_configs/functions.yml @@ -102,6 +102,7 @@ functions: - SSL - ORCHESTRATION_FILE - UV_PYTHON + - UV_PYTHON_PREFERENCE - STORAGE_ENGINE - REQUIRE_API_VERSION - DRIVERS_TOOLS @@ -137,6 +138,7 @@ functions: - AWS_SESSION_TOKEN - COVERAGE - UV_PYTHON + - UV_PYTHON_PREFERENCE - LIBMONGOCRYPT_URL - MONGODB_URI - DISABLE_TEST_COMMANDS diff --git a/.evergreen/generated_configs/tasks.yml b/.evergreen/generated_configs/tasks.yml index d4ff6ad5d5..169f8ce85f 100644 --- a/.evergreen/generated_configs/tasks.yml +++ b/.evergreen/generated_configs/tasks.yml @@ -2784,10 +2784,14 @@ tasks: vars: VERSION: v8.0-perf SSL: ssl + UV_PYTHON: 3.10.11 + UV_PYTHON_PREFERENCE: only-managed - func: run tests vars: TEST_NAME: perf SUB_TEST_NAME: sync + UV_PYTHON: 3.10.11 + UV_PYTHON_PREFERENCE: only-managed - func: attach benchmark test results - func: send dashboard data tags: [perf] @@ -2797,10 +2801,14 @@ tasks: vars: VERSION: v8.0-perf SSL: ssl + UV_PYTHON: 3.10.11 + UV_PYTHON_PREFERENCE: only-managed - func: run tests vars: TEST_NAME: perf SUB_TEST_NAME: async + UV_PYTHON: 3.10.11 + UV_PYTHON_PREFERENCE: only-managed - func: attach benchmark test results - func: send dashboard data tags: [perf] @@ -2810,10 +2818,14 @@ tasks: vars: VERSION: v8.0-perf SSL: nossl + UV_PYTHON: 3.10.11 + UV_PYTHON_PREFERENCE: only-managed - func: run tests vars: TEST_NAME: perf SUB_TEST_NAME: sync + UV_PYTHON: 3.10.11 + UV_PYTHON_PREFERENCE: only-managed - func: attach benchmark test results - func: send dashboard data tags: [perf] @@ -2823,10 +2835,14 @@ tasks: vars: VERSION: v8.0-perf SSL: nossl + UV_PYTHON: 3.10.11 + UV_PYTHON_PREFERENCE: only-managed - func: run tests vars: TEST_NAME: perf SUB_TEST_NAME: async + UV_PYTHON: 3.10.11 + UV_PYTHON_PREFERENCE: only-managed - func: attach benchmark test results - func: send dashboard data tags: [perf] diff --git a/.evergreen/run-tests.sh b/.evergreen/run-tests.sh index 358b3e532e..aa1fe97610 100755 --- a/.evergreen/run-tests.sh +++ b/.evergreen/run-tests.sh @@ -26,6 +26,9 @@ else exit 1 fi +# No-op on Evergreen (just.sh already ran this); needed for direct/local runs (PYTHON-6135). +. $SCRIPT_DIR/scripts/setup-uv-python.sh + # Start the test runner. echo "Running tests with UV_PYTHON=${UV_PYTHON:-} UV_PYTHON_SEARCH_PATH=${UV_PYTHON_SEARCH_PATH:-}..." echo "UV_ARGS=${UV_ARGS}" diff --git a/.evergreen/scripts/generate_config.py b/.evergreen/scripts/generate_config.py index 9b4313c423..9ec13d5037 100644 --- a/.evergreen/scripts/generate_config.py +++ b/.evergreen/scripts/generate_config.py @@ -43,6 +43,7 @@ git_get_project, ) from shrub.v3.evg_task import EvgTask, EvgTaskDependency, EvgTaskRef +from utils import PERF_PYTHON_VERSION ############## # Variants @@ -1092,9 +1093,12 @@ def create_search_index_tasks(): def create_perf_tasks(): tasks = [] for version, ssl, sync in product(["8.0"], ["ssl", "nossl"], ["sync", "async"]): - vars = dict(VERSION=f"v{version}-perf", SSL=ssl) + # The toolchain build may be this same patch version but is not + # optimized, which regressed CPU-bound benchmarks (PYTHON-6135). + perf_vars = dict(UV_PYTHON=PERF_PYTHON_VERSION, UV_PYTHON_PREFERENCE="only-managed") + vars = dict(VERSION=f"v{version}-perf", SSL=ssl, **perf_vars) server_func = FunctionCall(func="run server", vars=vars) - vars = dict(TEST_NAME="perf", SUB_TEST_NAME=sync) + vars = dict(TEST_NAME="perf", SUB_TEST_NAME=sync, **perf_vars) test_func = FunctionCall(func="run tests", vars=vars) attach_func = FunctionCall(func="attach benchmark test results") send_func = FunctionCall(func="send dashboard data") @@ -1313,6 +1317,7 @@ def create_run_server_func(): "SSL", "ORCHESTRATION_FILE", "UV_PYTHON", + "UV_PYTHON_PREFERENCE", "STORAGE_ENGINE", "REQUIRE_API_VERSION", "DRIVERS_TOOLS", @@ -1342,6 +1347,7 @@ def create_run_tests_func(): "AWS_SESSION_TOKEN", "COVERAGE", "UV_PYTHON", + "UV_PYTHON_PREFERENCE", "LIBMONGOCRYPT_URL", "MONGODB_URI", "DISABLE_TEST_COMMANDS", diff --git a/.evergreen/scripts/setup-uv-python.sh b/.evergreen/scripts/setup-uv-python.sh index 2ebfe04d9d..09397803f5 100755 --- a/.evergreen/scripts/setup-uv-python.sh +++ b/.evergreen/scripts/setup-uv-python.sh @@ -9,6 +9,7 @@ # UV_PYTHON_SEARCH_PATH - the Python toolchain bin dir for the request, so uv # uses the toolchain Python instead of downloading one. # UV_PYTHON_PREFERENCE - "system" so the toolchain wins over managed installs. +# A preference set by the task is left alone. # UV_PYTHON - the Python interpreter uv uses; defaults to CPython # 3.10 when the task does not set one. set -euo pipefail @@ -85,11 +86,11 @@ elif _dir=$(_toolchain_dir "$UV_PYTHON"); then _search_path="$_dir" fi -# Point uv at the toolchain Python when there is one. On CI the toolchain dir -# is already first on PATH (configure-env.sh), so this mainly benefits local -# hosts and later steps, keeping `uv sync` and `uv tool install` on the -# toolchain interpreter instead of downloading a managed one. -if [ -n "$_search_path" ]; then +# Point uv at the toolchain Python when there is one and the task did not set +# its own preference: a task-level UV_PYTHON_PREFERENCE wins (PYTHON-6135). +# On CI the toolchain dir is already first on PATH (configure-env.sh), so this +# mainly benefits local hosts and later steps. +if [ -n "$_search_path" ] && [ -z "${UV_PYTHON_PREFERENCE:-}" ]; then export UV_PYTHON_SEARCH_PATH="$_search_path" export UV_PYTHON_PREFERENCE="system" fi diff --git a/.evergreen/scripts/setup_tests.py b/.evergreen/scripts/setup_tests.py index b57188eee1..6c77ecabf9 100644 --- a/.evergreen/scripts/setup_tests.py +++ b/.evergreen/scripts/setup_tests.py @@ -13,6 +13,7 @@ ENV_FILE, HERE, LOGGER, + PERF_PYTHON_VERSION, PLATFORM, ROOT, TEST_SUITE_MAP, @@ -51,9 +52,6 @@ # Map the test name to test group. GROUP_MAP = dict(mockupdb="mockupdb", perf="perf") -# The python version used for perf tests. -PERF_PYTHON_VERSION = "3.10.11" - # The libmongocrypt release used when LIBMONGOCRYPT_URL is not set. Must be at # least 1.20.0 for the GA "substring" query type. LIBMONGOCRYPT_VERSION = "1.20.2" @@ -515,13 +513,12 @@ def handle_test_env() -> None: run_command("tar xf single_and_multi_document.tgz", cwd=data_dir) write_env("TEST_PATH", str(data_dir)) write_env("OUTPUT_FILE", str(ROOT / "results.json")) - # Overwrite the UV_PYTHON value from env.sh, and unset the toolchain - # search-path variables: an empty value would make uv reject the request, - # and a toolchain path would miss the exact patch version requested. - write_env("UV_PYTHON", "") + # The toolchain build may be this same patch version but is not + # optimized, which regressed CPU-bound benchmarks (PYTHON-6135). + write_env("UV_PYTHON", PERF_PYTHON_VERSION) + write_env("UV_PYTHON_PREFERENCE", "only-managed") with ENV_FILE.open("a", newline="\n") as fid: fid.write("unset UV_PYTHON_SEARCH_PATH\n") - fid.write("unset UV_PYTHON_PREFERENCE\n") UV_ARGS.append(f"--python={PERF_PYTHON_VERSION}") diff --git a/.evergreen/scripts/utils.py b/.evergreen/scripts/utils.py index 3f948dd292..75d4fc89b3 100644 --- a/.evergreen/scripts/utils.py +++ b/.evergreen/scripts/utils.py @@ -81,6 +81,9 @@ class Distro: EXTRA_TESTS = ["aws_lambda", "doctest"] +# The managed Python version used for perf tests (PYTHON-6135). +PERF_PYTHON_VERSION = "3.10.11" + # Tests that do not use run-mongodb directly. NO_RUN_ORCHESTRATION = [ "auth_oidc",