Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PYTHON-4838 Generate OCSP build variants using shrub.py #1910

Merged
merged 20 commits into from
Oct 14, 2024
Merged
174 changes: 141 additions & 33 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2826,42 +2826,150 @@ buildvariants:
- "test-6.0-standalone"
- "test-5.0-standalone"

- matrix_name: "ocsp-test"
matrix_spec:
platform: rhel8
python-version: ["3.9", "3.10", "pypy3.9", "pypy3.10"]
mongodb-version: ["4.4", "5.0", "6.0", "7.0", "8.0", "latest"]
auth: "noauth"
ssl: "ssl"
display_name: "OCSP test ${platform} ${python-version} ${mongodb-version}"
batchtime: 20160 # 14 days
# OCSP test matrix.
- name: ocsp-test-rhel8-v4.4-py3.9
tasks:
- name: ".ocsp"

- matrix_name: "ocsp-test-windows"
matrix_spec:
platform: windows
python-version-windows: ["3.9", "3.10"]
mongodb-version: ["4.4", "5.0", "6.0", "7.0", "8.0", "latest"]
auth: "noauth"
ssl: "ssl"
display_name: "OCSP test ${platform} ${python-version-windows} ${mongodb-version}"
batchtime: 20160 # 14 days
- name: .ocsp
display_name: OCSP test RHEL8 v4.4 py3.9
run_on:
- rhel87-small
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: "4.4"
PYTHON_BINARY: /opt/python/3.9/bin/python3
- name: ocsp-test-rhel8-v5.0-py3.10
tasks:
# Windows MongoDB servers do not staple OCSP responses and only support RSA.
- name: ".ocsp-rsa !.ocsp-staple"

- matrix_name: "ocsp-test-macos"
matrix_spec:
platform: macos
mongodb-version: ["4.4", "5.0", "6.0", "7.0", "8.0", "latest"]
auth: "noauth"
ssl: "ssl"
display_name: "OCSP test ${platform} ${mongodb-version}"
batchtime: 20160 # 14 days
- name: .ocsp
display_name: OCSP test RHEL8 v5.0 py3.10
run_on:
- rhel87-small
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: "5.0"
PYTHON_BINARY: /opt/python/3.10/bin/python3
- name: ocsp-test-rhel8-v6.0-py3.11
tasks:
# macOS MongoDB servers do not staple OCSP responses and only support RSA.
- name: ".ocsp-rsa !.ocsp-staple"
- name: .ocsp
display_name: OCSP test RHEL8 v6.0 py3.11
run_on:
- rhel87-small
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: "6.0"
PYTHON_BINARY: /opt/python/3.11/bin/python3
- name: ocsp-test-rhel8-v7.0-py3.12
tasks:
- name: .ocsp
display_name: OCSP test RHEL8 v7.0 py3.12
run_on:
- rhel87-small
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: "7.0"
PYTHON_BINARY: /opt/python/3.12/bin/python3
- name: ocsp-test-rhel8-v8.0-py3.13
tasks:
- name: .ocsp
display_name: OCSP test RHEL8 v8.0 py3.13
run_on:
- rhel87-small
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: "8.0"
PYTHON_BINARY: /opt/python/3.13/bin/python3
- name: ocsp-test-rhel8-rapid-pypy3.9
tasks:
- name: .ocsp
display_name: OCSP test RHEL8 rapid pypy3.9
run_on:
- rhel87-small
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: rapid
PYTHON_BINARY: /opt/python/pypy3.9/bin/python3
- name: ocsp-test-rhel8-latest-pypy3.10
tasks:
- name: .ocsp
display_name: OCSP test RHEL8 latest pypy3.10
run_on:
- rhel87-small
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: latest
PYTHON_BINARY: /opt/python/pypy3.10/bin/python3
- name: ocsp-test-win64-v4.4-py3.9
tasks:
- name: .ocsp-rsa !.ocsp-staple
display_name: OCSP test Win64 v4.4 py3.9
run_on:
- windows-64-vsMulti-small
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: "4.4"
PYTHON_BINARY: C:/python/Python39/python.exe
- name: ocsp-test-win64-v8.0-py3.13
tasks:
- name: .ocsp-rsa !.ocsp-staple
display_name: OCSP test Win64 v8.0 py3.13
run_on:
- windows-64-vsMulti-small
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: "8.0"
PYTHON_BINARY: C:/python/Python313/python.exe
- name: ocsp-test-macos-v4.4-py3.9
tasks:
- name: .ocsp-rsa !.ocsp-staple
display_name: OCSP test macOS v4.4 py3.9
run_on:
- macos-14
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: "4.4"
PYTHON_BINARY: /Library/Frameworks/Python.Framework/Versions/3.9/bin/python3
- name: ocsp-test-macos-v8.0-py3.13
tasks:
- name: .ocsp-rsa !.ocsp-staple
display_name: OCSP test macOS v8.0 py3.13
run_on:
- macos-14
batchtime: 20160
expansions:
AUTH: noauth
SSL: ssl
TOPOLOGY: server
VERSION: "8.0"
PYTHON_BINARY: /Library/Frameworks/Python.Framework/Versions/3.13/bin/python3

- matrix_name: "oidc-auth-test"
matrix_spec:
Expand Down
167 changes: 167 additions & 0 deletions .evergreen/scripts/generate_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# /// script
# requires-python = ">=3.9"
# dependencies = [
# "shrub.py>=3.2.0",
# "pyyaml>=6.0.2"
# ]
# ///

# Note: Run this file with `hatch run`, `pipx run`, or `uv run`.
from __future__ import annotations

from dataclasses import dataclass
from itertools import cycle, product, zip_longest
from typing import Any

from shrub.v3.evg_build_variant import BuildVariant
from shrub.v3.evg_project import EvgProject
from shrub.v3.evg_task import EvgTaskRef
from shrub.v3.shrub_service import ShrubService

##############
# Globals
##############

ALL_VERSIONS = ["4.0", "4.4", "5.0", "6.0", "7.0", "8.0", "rapid", "latest"]
CPYTHONS = ["3.9", "3.10", "3.11", "3.12", "3.13"]
PYPYS = ["pypy3.9", "pypy3.10"]
ALL_PYTHONS = CPYTHONS + PYPYS
BATCHTIME_WEEK = 10080
HOSTS = dict()


@dataclass
class Host:
name: str
run_on: str
display_name: str


HOSTS["rhel8"] = Host("rhel8", "rhel87-small", "RHEL8")
HOSTS["win64"] = Host("win64", "windows-64-vsMulti-small", "Win64")
HOSTS["macos"] = Host("macos", "macos-14", "macOS")


##############
# Helpers
##############


def create_variant(
task_names: list[str],
display_name: str,
*,
python: str | None = None,
version: str | None = None,
host: str | None = None,
**kwargs: Any,
) -> BuildVariant:
"""Create a build variant for the given inputs."""
task_refs = [EvgTaskRef(name=n) for n in task_names]
kwargs.setdefault("expansions", dict())
expansions = kwargs.pop("expansions", dict()).copy()
host = host or "rhel8"
run_on = [HOSTS[host].run_on]
name = display_name.replace(" ", "-").lower()
if python:
expansions["PYTHON_BINARY"] = get_python_binary(python, host)
if version:
expansions["VERSION"] = version
expansions = expansions or None
return BuildVariant(
name=name,
display_name=display_name,
tasks=task_refs,
expansions=expansions,
run_on=run_on,
**kwargs,
)


def get_python_binary(python: str, host: str) -> str:
"""Get the appropriate python binary given a python version and host."""
if host == "win64":
is_32 = python.startswith("32-bit")
if is_32:
_, python = python.split()
base = "C:/python/32"
else:
base = "C:/python"
python = python.replace(".", "")
return f"{base}/Python{python}/python.exe"

if host == "rhel8":
return f"/opt/python/{python}/bin/python3"

if host == "macos":
return f"/Library/Frameworks/Python.Framework/Versions/{python}/bin/python3"

raise ValueError(f"no match found for python {python} on {host}")


def get_display_name(base: str, host: str, version: str, python: str) -> str:
"""Get the display name of a variant."""
if version not in ["rapid", "latest"]:
version = f"v{version}"
if not python.startswith("pypy"):
python = f"py{python}"
return f"{base} {HOSTS[host].display_name} {version} {python}"


def zip_cycle(*iterables, empty_default=None):
"""Get all combinations of the inputs, cycling over the shorter list(s)."""
cycles = [cycle(i) for i in iterables]
for _ in zip_longest(*iterables):
yield tuple(next(i, empty_default) for i in cycles)


##############
# Variants
##############


def create_ocsp_variants() -> list[BuildVariant]:
variants = []
batchtime = BATCHTIME_WEEK * 2
expansions = dict(AUTH="noauth", SSL="ssl", TOPOLOGY="server")
base_display = "OCSP test"

# OCSP tests on rhel8 with all servers v4.4+ and all python versions.
versions = [v for v in ALL_VERSIONS if v != "4.0"]
for version, python in zip_cycle(versions, ALL_PYTHONS):
host = "rhel8"
variant = create_variant(
[".ocsp"],
get_display_name(base_display, host, version, python),
python=python,
version=version,
host=host,
expansions=expansions,
batchtime=batchtime,
)
variants.append(variant)

# OCSP tests on Windows and MacOS.
# MongoDB servers on these hosts do not staple OCSP responses and only support RSA.
for host, version in product(["win64", "macos"], ["4.4", "8.0"]):
python = CPYTHONS[0] if version == "4.4" else CPYTHONS[-1]
variant = create_variant(
[".ocsp-rsa !.ocsp-staple"],
get_display_name(base_display, host, version, python),
python=python,
version=version,
host=host,
expansions=expansions,
batchtime=batchtime,
)
variants.append(variant)

return variants


##################
# Generate Config
##################

project = EvgProject(tasks=None, buildvariants=create_ocsp_variants())
print(ShrubService.generate_yaml(project)) # noqa: T201
Loading