9
9
# Note: Run this file with `hatch run`, `pipx run`, or `uv run`.
10
10
from __future__ import annotations
11
11
12
- from itertools import product
12
+ from dataclasses import dataclass
13
+ from itertools import product , zip_longest
14
+ from typing import Any
13
15
14
16
from shrub .v3 .evg_build_variant import BuildVariant
15
17
from shrub .v3 .evg_project import EvgProject
18
20
19
21
# Top level variables.
20
22
ALL_VERSIONS = ["4.0" , "4.4" , "5.0" , "6.0" , "7.0" , "8.0" , "rapid" , "latest" ]
21
- CPYTHONS = ["py3 .9" , "py3 .10" , "py3 .11" , "py3 .12" , "py3 .13" ]
23
+ CPYTHONS = ["3 .9" , "3 .10" , "3 .11" , "3 .12" , "3 .13" ]
22
24
PYPYS = ["pypy3.9" , "pypy3.10" ]
23
25
ALL_PYTHONS = CPYTHONS + PYPYS
24
26
ALL_WIN_PYTHONS = CPYTHONS .copy ()
29
31
TOPOLOGIES = ["standalone" , "replica_set" , "sharded_cluster" ]
30
32
C_EXTS = ["without c extensions" , "with c extensions" ]
31
33
BATCHTIME_WEEK = 10080
32
- HOSTS = dict (rhel8 = "rhel87-small" , Win64 = "windows-64-vsMulti-small" , macOS = "macos-14" )
34
+ HOSTS = dict ()
35
+
36
+
37
+ @dataclass
38
+ class Host :
39
+ name : str
40
+ run_on : str
41
+ display_name : str
42
+
43
+
44
+ HOSTS ["rhel8" ] = Host ("rhel8" , "rhel87-small" , "RHEL8" )
45
+ HOSTS ["win64" ] = Host ("win64" , "windows-64-vsMulti-small" , "Win64" )
46
+ HOSTS ["macos" ] = Host ("macos" , "macos-14" , "MacOS" )
33
47
34
48
35
49
# Helper functions.
36
- def create_variant (task_names , display_name , * , python = None , host = None , ** kwargs ):
50
+ def create_variant (
51
+ task_names : list [str ],
52
+ display_name : str ,
53
+ * ,
54
+ python : str | None = None ,
55
+ host : str | None = None ,
56
+ ** kwargs : Any ,
57
+ ) -> BuildVariant :
37
58
task_refs = [EvgTaskRef (name = n ) for n in task_names ]
38
59
kwargs .setdefault ("expansions" , dict ())
39
60
expansions = kwargs .pop ("expansions" )
40
61
host = host or "rhel8"
41
- run_on = [HOSTS [host ]]
62
+ run_on = [HOSTS [host ]. run_on ]
42
63
name = display_name .replace (" " , "-" ).lower ()
43
64
if python :
44
65
expansions ["PYTHON_BINARY" ] = get_python_binary (python , host )
@@ -53,81 +74,100 @@ def create_variant(task_names, display_name, *, python=None, host=None, **kwargs
53
74
)
54
75
55
76
56
- def get_python_binary (python , host ) :
57
- if host . lower () == "win64" :
77
+ def get_python_binary (python : str , host : str ) -> str :
78
+ if host == "win64" :
58
79
is_32 = python .startswith ("32-bit" )
59
80
if is_32 :
60
81
_ , python = python .split ()
61
- base = "C:/python/32/ "
82
+ base = "C:/python/32"
62
83
else :
63
- base = "C:/python/"
64
- middle = python .replace ("py" , "Python" ).replace ("." , "" )
65
- return base + middle + "/python.exe"
84
+ base = "C:/python"
85
+ python = python .replace ("." , "" )
86
+ return f"{ base } /Python{ python } /python.exe"
87
+
88
+ if host == "rhel8" :
89
+ return f"/opt/python/{ python } /bin/python3"
66
90
67
- if host .lower () == "rhel8" :
68
- if python .startswith ("pypy" ):
69
- return f"/opt/python/{ python } /bin/python3"
70
- return f"/opt/python/{ python [2 :]} /bin/python3"
91
+ if host == "macos" :
92
+ return f"/Library/Frameworks/Python.Framework/Versions/{ python } /bin/python3"
71
93
72
- if host .lower () == "macos" :
73
- ver = python .replace ("py" , "" )
74
- return f"/Library/Frameworks/Python.Framework/Versions/{ ver } /bin/python3"
94
+ raise ValueError (f"no match found for python { python } on { host } " )
75
95
76
- raise ValueError (f"no match found for { python } on { host } " )
96
+
97
+ def get_display (base : str , host : str , version : str , python : str ) -> str :
98
+ if version not in ["rapid" , "latest" ]:
99
+ version = f"v{ version } "
100
+ if not python .startswith ("pypy" ):
101
+ python = f"py{ python } "
102
+ return f"{ base } { HOSTS [host ].display_name } { version } { python } "
103
+
104
+
105
+ def get_pairs (versions : list [str ], pythons : list [str ]) -> str :
106
+ values = []
107
+ for version , python in zip_longest (versions , pythons ):
108
+ if version is None :
109
+ values .append ((versions [0 ], python ))
110
+ elif python is None :
111
+ values .append ((version , pythons [0 ]))
112
+ else :
113
+ values .append ((version , python ))
114
+ return values
77
115
78
116
79
117
##############
80
118
# OCSP
81
119
##############
82
120
121
+
83
122
# Create OCSP build variants.
84
- variants = []
85
-
86
- # OCSP tests on rhel8 with rotating CPython versions.
87
- for version in ALL_VERSIONS :
88
- # OCSP is not supported until v4.4.
89
- if version == "4.0" :
90
- continue
91
- task_refs = [EvgTaskRef (name = ".ocsp" )]
92
- expansions = dict (VERSION = version , AUTH = "noauth" , SSL = "ssl" , TOPOLOGY = "server" )
123
+ def create_ocsp_variants () -> list [BuildVariant ]:
124
+ variants = []
93
125
batchtime = BATCHTIME_WEEK * 2
94
- python = ALL_PYTHONS [len (variants ) % len (ALL_PYTHONS )]
95
- host = "rhel8"
96
- if version in ["rapid" , "latest" ]:
97
- display_name = f"OCSP test RHEL8 { version } { python } "
98
- else :
99
- display_name = f"OCSP test RHEL8 v{ version } { python } "
100
- variant = create_variant (
101
- [".ocsp" ],
102
- display_name ,
103
- python = python ,
104
- batchtime = batchtime ,
105
- host = host ,
106
- expansions = expansions ,
107
- )
108
- variants .append (variant )
126
+ base_expansions = dict (AUTH = "noauth" , SSL = "ssl" , TOPOLOGY = "server" )
127
+ base_display = "OCSP test"
128
+
129
+ # OCSP tests on rhel8 with all server and python versions.
130
+ versions = [v for v in ALL_VERSIONS if v != "4.4" ]
131
+ for version , python in get_pairs (versions , ALL_PYTHONS ):
132
+ # OCSP is not supported until v4.4.
133
+ if version == "4.0" :
134
+ continue
135
+ expansions = base_expansions .copy ()
136
+ expansions ["VERSION" ] = version
137
+ host = "rhel8"
138
+ variant = create_variant (
139
+ [".ocsp" ],
140
+ get_display (base_display , host , version , python ),
141
+ python = python ,
142
+ batchtime = batchtime ,
143
+ host = host ,
144
+ expansions = expansions ,
145
+ )
146
+ variants .append (variant )
147
+
148
+ # OCSP tests on Windows and MacOS.
149
+ for host , version in product (["win64" , "macos" ], ["4.4" , "8.0" ]):
150
+ # MongoDB servers do not staple OCSP responses and only support RSA.
151
+ task_names = [".ocsp-rsa !.ocsp-staple" ]
152
+ expansions = base_expansions .copy ()
153
+ expansions ["VERSION" ] = version
154
+ if version == "4.4" :
155
+ python = CPYTHONS [0 ]
156
+ else :
157
+ python = CPYTHONS [- 1 ]
158
+ variant = create_variant (
159
+ task_names ,
160
+ get_display (base_display , host , version , python ),
161
+ python = python ,
162
+ host = host ,
163
+ expansions = expansions ,
164
+ batchtime = batchtime ,
165
+ )
166
+ variants .append (variant )
167
+
168
+ return variants
109
169
110
- # OCSP tests on Windows and MacOS.
111
- for host , version in product (["Win64" , "macOS" ], ["4.4" , "8.0" ]):
112
- # MongoDB servers do not staple OCSP responses and only support RSA.
113
- task_names = [".ocsp-rsa !.ocsp-staple" ]
114
- expansions = dict (VERSION = version , AUTH = "noauth" , SSL = "ssl" , TOPOLOGY = "server" )
115
- batchtime = BATCHTIME_WEEK * 2
116
- if version == "4.4" :
117
- python = CPYTHONS [0 ]
118
- else :
119
- python = CPYTHONS [- 1 ]
120
- display_name = f"OCSP test { host } v{ version } { python } "
121
- variant = create_variant (
122
- task_names ,
123
- display_name ,
124
- python = python ,
125
- host = host ,
126
- expansions = expansions ,
127
- batchtime = batchtime ,
128
- )
129
- variants .append (variant )
130
170
131
171
# Generate OCSP config.
132
- project = EvgProject (tasks = None , buildvariants = variants )
172
+ project = EvgProject (tasks = None , buildvariants = create_ocsp_variants () )
133
173
print (ShrubService .generate_yaml (project )) # noqa: T201
0 commit comments