Skip to content

Commit cade386

Browse files
henryiiiCopilotmayeutjoerick
authored
ci: rework tests to break out ios/android tests (#2519)
* ci: rework tests to break out ios/android tests Signed-off-by: Henry Schreiner <[email protected]> * Apply suggestions from code review Co-authored-by: Copilot <[email protected]> * Apply suggestions from code review * ci: fix check for wheels Signed-off-by: Henry Schreiner <[email protected]> * Update .github/workflows/test.yml * tests: pass via flag instead of envvar Signed-off-by: Henry Schreiner <[email protected]> * tests: apply to serial/parallel Signed-off-by: Henry Schreiner <[email protected]> * tests: join together marks Signed-off-by: Henry Schreiner <[email protected]> * tests: join together marks Signed-off-by: Henry Schreiner <[email protected]> * ci: break up azure job Signed-off-by: Henry Schreiner <[email protected]> * ci: use matrix for azure pipelines Signed-off-by: Henry Schreiner <[email protected]> * Try installing Java on macos as well * Revert "Try installing Java on macos as well" This reverts commit aedf0f5. * Try to get the most basic android test running first * Rename platform to test_select, move headers in run_tests Maybe it's a personal thing, but the header location was really making me have to think more than I needed to look at that file! * Only run docker unit tests on machines that are testing linux * Update the flag name in azure-pipelines too * Update azure-pipelines.yml --------- Signed-off-by: Henry Schreiner <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: Matthieu Darbois <[email protected]> Co-authored-by: Joe Rickerby <[email protected]>
1 parent 63bdd4f commit cade386

File tree

4 files changed

+128
-75
lines changed

4 files changed

+128
-75
lines changed

.github/workflows/test.yml

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,44 @@ jobs:
4747
run: pipx run --python "${{ steps.python.outputs.python-path }}" nox -s pylint -- --output-format=github
4848

4949
test:
50-
name: Test on ${{ matrix.os }} (${{ matrix.python_version }})
50+
name: Test on ${{ matrix.os }} (${{ matrix.python_version }}) ${{ matrix.test_select }}
5151
needs: lint
5252
runs-on: ${{ matrix.os }}
5353
strategy:
5454
fail-fast: false
5555
matrix:
56-
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-13, macos-15]
57-
python_version: ['3.13']
5856
include:
57+
# Min Python
5958
- os: ubuntu-latest
6059
python_version: '3.11'
60+
# Max Python
6161
- os: ubuntu-latest
6262
python_version: '3.14'
63+
- os: ubuntu-latest
64+
python_version: '3.13'
65+
test_select: android
66+
- os: ubuntu-24.04-arm
67+
python_version: '3.13'
68+
- os: windows-latest
69+
python_version: '3.13'
70+
- os: windows-11-arm
71+
python_version: '3.13'
72+
- os: macos-13
73+
python_version: '3.13'
74+
- os: macos-15
75+
python_version: '3.13'
76+
- os: macos-13
77+
python_version: '3.13'
78+
test_select: ios
79+
- os: macos-15
80+
python_version: '3.13'
81+
test_select: ios
82+
- os: macos-13
83+
python_version: '3.13'
84+
test_select: android
85+
- os: macos-15
86+
python_version: '3.13'
87+
test_select: android
6388
timeout-minutes: 180
6489
steps:
6590
- uses: actions/checkout@v5
@@ -129,10 +154,12 @@ jobs:
129154
output-dir: wheelhouse
130155
env:
131156
CIBW_ARCHS_MACOS: x86_64 universal2 arm64
132-
CIBW_BUILD_FRONTEND: 'build[uv]'
157+
CIBW_BUILD_FRONTEND: ${{ matrix.test_select && 'build' || 'build[uv]' }}
158+
CIBW_PLATFORM: ${{ matrix.test_select }}
133159

134160
- name: Run a sample build (GitHub Action, only)
135161
uses: ./
162+
if: matrix.test_select == ''
136163
with:
137164
package-dir: sample_proj
138165
output-dir: wheelhouse_only
@@ -152,6 +179,8 @@ jobs:
152179
153180
- name: Run a sample build (GitHub Action, config-file)
154181
uses: ./
182+
env:
183+
CIBW_PLATFORM: ${{ matrix.test_select }}
155184
with:
156185
package-dir: sample_proj
157186
output-dir: wheelhouse_config_file
@@ -161,17 +190,22 @@ jobs:
161190
shell: bash
162191
run: |
163192
test $(find wheelhouse -name '*.whl' | wc -l) -ge 1
164-
test $(find wheelhouse_only -name '*.whl' | wc -l) -eq 1
165193
test $(find wheelhouse_config_file -name '*.whl' | wc -l) -eq 1
166194
195+
- name: Check Action artifacts (native build only)
196+
if: matrix.test_select == ''
197+
shell: bash
198+
run: |
199+
test $(find wheelhouse_only -name '*.whl' | wc -l) -eq 1
200+
167201
- uses: actions/upload-artifact@v4
168202
with:
169203
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
170204
path: wheelhouse/*.whl
171205

172206
- name: Test cibuildwheel
173207
run: |
174-
uv run --no-sync bin/run_tests.py ${{ (runner.os == 'Linux' && runner.arch == 'X64') && '--run-podman' || '' }}
208+
uv run --no-sync bin/run_tests.py --test-select=${{ matrix.test_select || 'native' }} ${{ (runner.os == 'Linux' && runner.arch == 'X64') && '--run-podman' || '' }}
175209
176210
emulated-archs:
177211
name: Get qemu emulated architectures

azure-pipelines.yml

Lines changed: 46 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,62 +16,61 @@ pr:
1616
- noxfile.py
1717

1818
jobs:
19-
- job: linux_311
19+
- job: tests
20+
strategy:
21+
matrix:
22+
linux_311:
23+
imageName: "ubuntu-latest"
24+
pythonVersion: "3.11"
25+
testSelect: "native"
26+
android_311:
27+
imageName: "ubuntu-latest"
28+
pythonVersion: "3.11"
29+
testSelect: "android"
30+
macos_311:
31+
imageName: "macos-latest"
32+
pythonVersion: "3.11"
33+
testSelect: "native"
34+
ios_311:
35+
imageName: "macos-latest"
36+
pythonVersion: "3.11"
37+
testSelect: "ios"
38+
android_macos_311:
39+
imageName: "macos-latest"
40+
pythonVersion: "3.11"
41+
testSelect: "android"
42+
windows_311:
43+
imageName: "windows-latest"
44+
pythonVersion: "3.11"
45+
testSelect: "native"
2046
timeoutInMinutes: 180
21-
pool: {vmImage: 'ubuntu-latest'}
47+
pool:
48+
vmImage: $(imageName)
49+
2250
steps:
2351
- task: UsePythonVersion@0
2452
inputs:
25-
versionSpec: '3.11'
53+
versionSpec: $(pythonVersion)
54+
2655
- task: JavaToolInstaller@0
56+
condition: and(eq(variables['testSelect'], 'android'), eq(variables['Agent.OS'], 'Linux'))
2757
inputs:
2858
versionSpec: '17'
2959
jdkArchitectureOption: 'x64'
3060
jdkSourceOption: 'PreInstalled'
31-
- bash: |
32-
docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all
33-
python -m pip install -U pip
34-
python -m pip install -e. --group test
35-
if [ "$(Build.SourceBranch)" = "refs/heads/main" ]; then
36-
echo "INFO: Exporting CIBW_ENABLE=all for main branch test run."
37-
export CIBW_ENABLE=all
38-
else
39-
echo "INFO: CIBW_ENABLE not set for this branch ($(Build.SourceBranch))."
40-
fi
41-
python ./bin/run_tests.py
4261

43-
- job: macos_311
44-
pool: {vmImage: 'macOS-latest'}
45-
timeoutInMinutes: 120
46-
steps:
47-
- task: UsePythonVersion@0
48-
inputs:
49-
versionSpec: '3.11'
50-
- bash: |
51-
python -m pip install -U pip
52-
python -m pip install -e. --group test
53-
if [ "$(Build.SourceBranch)" = "refs/heads/main" ]; then
54-
echo "INFO: Exporting CIBW_ENABLE=all for main branch test run."
55-
export CIBW_ENABLE=all
56-
else
57-
echo "INFO: CIBW_ENABLE not set for this branch ($(Build.SourceBranch))."
58-
fi
59-
python ./bin/run_tests.py
62+
- bash: docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all
63+
condition: and(eq(variables['imageName'], 'ubuntu-latest'), eq(variables['testSelect'], 'native'))
64+
displayName: 'Install binfmt on Linux'
65+
66+
- bash: python -m pip install -U pip && python -m pip install -e. --group test
67+
displayName: 'Update pip and install cibuildwheel --group test'
68+
69+
- bash: echo "##vso[task.setvariable variable=CIBW_ENABLE;]all"
70+
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
71+
displayName: Set CIBW_ENABLE to all (main branch)
6072

61-
- job: windows_311
62-
pool: {vmImage: 'windows-latest'}
63-
timeoutInMinutes: 180
64-
steps:
65-
- task: UsePythonVersion@0
66-
inputs:
67-
versionSpec: '3.11'
6873
- bash: |
69-
python -m pip install -U pip
70-
python -m pip install -e. --group test
71-
if [ "$(Build.SourceBranch)" = "refs/heads/main" ]; then
72-
echo "INFO: Exporting CIBW_ENABLE=all for main branch test run."
73-
export CIBW_ENABLE=all
74-
else
75-
echo "INFO: CIBW_ENABLE not set for this branch ($(Build.SourceBranch))."
76-
fi
77-
python ./bin/run_tests.py
74+
echo "CIBW_ENABLE = $CIBW_ENABLE"
75+
python ./bin/run_tests.py --test-select $(testSelect)
76+
displayName: 'Run tests'

bin/run_tests.py

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
default=default_cpu_count,
2828
help="number of processes to use for testing",
2929
)
30+
parser.add_argument(
31+
"--test-select",
32+
choices={"all", "native", "android", "ios", "pyodide"},
33+
default="all",
34+
help="Either 'native' or 'android'/'ios'/'pyodide'",
35+
)
3036
args = parser.parse_args()
3137

3238
# move cwd to the project root
@@ -50,48 +56,65 @@
5056
)
5157

5258
# unit tests
59+
print(
60+
"\n\n================================== UNIT TESTS ==================================",
61+
flush=True,
62+
)
5363
unit_test_args = [sys.executable, "-m", "pytest", "unit_test"]
5464

55-
if sys.platform.startswith("linux") and os.environ.get("CIBW_PLATFORM", "linux") == "linux":
65+
if (
66+
sys.platform.startswith("linux")
67+
and os.environ.get("CIBW_PLATFORM", "linux") == "linux"
68+
and args.test_select in ["all", "native"]
69+
):
5670
# run the docker unit tests only on Linux
5771
unit_test_args += ["--run-docker"]
5872

5973
if args.run_podman:
6074
unit_test_args += ["--run-podman"]
6175

76+
subprocess.run(unit_test_args, check=True)
77+
6278
print(
63-
"\n\n================================== UNIT TESTS ==================================",
79+
"\n\n=========================== SERIAL INTEGRATION TESTS ===========================",
6480
flush=True,
6581
)
66-
subprocess.run(unit_test_args, check=True)
82+
83+
match args.test_select:
84+
case "all":
85+
marks = []
86+
case "native":
87+
marks = ["not pyodide", "not android", "not ios"]
88+
case mark:
89+
marks = [f"{mark}"]
6790

6891
# Run the serial integration tests without multiple processes
6992
serial_integration_test_args = [
7093
sys.executable,
7194
"-m",
7295
"pytest",
7396
"-m",
74-
"serial",
97+
f"{' and '.join(['serial', *marks])}",
7598
"-x",
7699
"--durations",
77100
"0",
78101
"--timeout=2400",
79102
"test",
80103
"-vv",
81104
]
105+
106+
subprocess.run(serial_integration_test_args, check=True)
107+
82108
print(
83-
"\n\n=========================== SERIAL INTEGRATION TESTS ===========================",
109+
"\n\n========================= NON-SERIAL INTEGRATION TESTS =========================",
84110
flush=True,
85111
)
86-
subprocess.run(serial_integration_test_args, check=True)
87-
88-
# Non-serial integration tests
89112
integration_test_args = [
90113
sys.executable,
91114
"-m",
92115
"pytest",
93116
"-m",
94-
"not serial",
117+
f"{' and '.join(['not serial', *marks])}",
95118
f"--numprocesses={args.num_processes}",
96119
"-x",
97120
"--durations",
@@ -104,8 +127,4 @@
104127
if sys.platform.startswith("linux") and args.run_podman:
105128
integration_test_args += ["--run-podman"]
106129

107-
print(
108-
"\n\n========================= NON-SERIAL INTEGRATION TESTS =========================",
109-
flush=True,
110-
)
111130
subprocess.run(integration_test_args, check=True)

test/test_android.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,17 @@ def test_android_home(tmp_path, capfd):
9090
assert "ANDROID_HOME environment variable is not set" in capfd.readouterr().err
9191

9292

93-
# Can fail to setup
93+
# the first build can fail to setup - mark as flaky, and serial to make sure it runs first
94+
@pytest.mark.serial
9495
@pytest.mark.flaky(reruns=2)
96+
def test_expected_wheels(tmp_path):
97+
new_c_project().generate(tmp_path)
98+
wheels = cibuildwheel_run(tmp_path, add_env={"CIBW_PLATFORM": "android"})
99+
assert wheels == expected_wheels(
100+
"spam", "0.1.0", platform="android", machine_arch=native_arch.android_abi
101+
)
102+
103+
95104
def test_frontend_good(tmp_path):
96105
new_c_project().generate(tmp_path)
97106
wheels = cibuildwheel_run(
@@ -112,14 +121,6 @@ def test_frontend_bad(frontend, tmp_path, capfd):
112121
assert "Android requires the build frontend to be 'build'" in capfd.readouterr().err
113122

114123

115-
def test_expected_wheels(tmp_path):
116-
new_c_project().generate(tmp_path)
117-
wheels = cibuildwheel_run(tmp_path, add_env={"CIBW_PLATFORM": "android"})
118-
assert wheels == expected_wheels(
119-
"spam", "0.1.0", platform="android", machine_arch=native_arch.android_abi
120-
)
121-
122-
123124
@needs_emulator
124125
def test_archs(tmp_path, capfd):
125126
new_c_project().generate(tmp_path)

0 commit comments

Comments
 (0)