Skip to content

Commit 4ef7b37

Browse files
authored
ci: correct Github Actions CI instability for iOS. (#2337)
* Correct Github Actions CI instability for iOS. * Add a dummy serial test so CircleCI passes serial test discovery.
1 parent 094782a commit 4ef7b37

File tree

5 files changed

+52
-10
lines changed

5 files changed

+52
-10
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
runs-on: ${{ matrix.os }}
3737
strategy:
3838
matrix:
39-
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-14]
39+
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-15]
4040
python_version: ['3.13']
4141
include:
4242
- os: ubuntu-latest

bin/run_tests.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,39 @@
3434
if args.run_podman:
3535
unit_test_args += ["--run-podman"]
3636

37+
print(
38+
"\n\n================================== UNIT TESTS ==================================",
39+
flush=True,
40+
)
3741
subprocess.run(unit_test_args, check=True)
3842

39-
# integration tests
43+
# Run the serial integration tests without multiple processes
44+
serial_integration_test_args = [
45+
sys.executable,
46+
"-m",
47+
"pytest",
48+
"-m",
49+
"serial",
50+
"-x",
51+
"--durations",
52+
"0",
53+
"--timeout=2400",
54+
"test",
55+
"-vv",
56+
]
57+
print(
58+
"\n\n=========================== SERIAL INTEGRATION TESTS ===========================",
59+
flush=True,
60+
)
61+
subprocess.run(serial_integration_test_args, check=True)
62+
63+
# Non-serial integration tests
4064
integration_test_args = [
4165
sys.executable,
4266
"-m",
4367
"pytest",
44-
"--dist",
45-
"loadgroup",
68+
"-m",
69+
"not serial",
4670
f"--numprocesses={args.num_processes}",
4771
"-x",
4872
"--durations",
@@ -55,4 +79,8 @@
5579
if sys.platform.startswith("linux") and args.run_podman:
5680
integration_test_args += ["--run-podman"]
5781

82+
print(
83+
"\n\n========================= NON-SERIAL INTEGRATION TESTS =========================",
84+
flush=True,
85+
)
5886
subprocess.run(integration_test_args, check=True)

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ junit_family = "xunit2"
102102
xfail_strict = true
103103
filterwarnings = ["error"]
104104
log_cli_level = "info"
105-
105+
markers = [
106+
"serial: tests that must *not* be run in parallel (deselect with '-m \"not serial\"')",
107+
]
106108

107109
[tool.mypy]
108110
python_version = "3.11"

test/test_0_basic.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@
1818
)
1919

2020

21+
@pytest.mark.serial
22+
def test_dummy_serial():
23+
"""A no-op test to ensure that at least one serial test is always found.
24+
25+
Without this no-op test, CI fails on CircleCI because no serial tests are
26+
found, and pytest errors if a test suite finds no tests.
27+
"""
28+
29+
2130
def test(tmp_path, build_frontend_env, capfd):
2231
project_dir = tmp_path / "project"
2332
basic_project.generate(project_dir)

test/test_ios.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ def test_platform(self):
2020
"""
2121

2222

23-
# iOS tests shouldn't be run in parallel, because they're dependent on starting
24-
# a simulator. It's *possible* to start multiple simulators, but not advisable
25-
# to start as many simulators as there are CPUs on the test machine.
26-
@pytest.mark.xdist_group(name="ios")
23+
# iOS tests shouldn't be run in parallel, because they're dependent on calling
24+
# Xcode, and starting a simulator. These are both multi-threaded operations, and
25+
# it's easy to overload the CI machine if there are multiple test processes
26+
# running multithreaded processes. Therefore, they're put in the serial group,
27+
# which is guaranteed to run single-process.
28+
@pytest.mark.serial
2729
@pytest.mark.parametrize(
2830
"build_config",
2931
[
@@ -48,6 +50,7 @@ def test_ios_platforms(tmp_path, build_config):
4850
"CIBW_BUILD": "cp313-*",
4951
"CIBW_TEST_SOURCES": "tests",
5052
"CIBW_TEST_COMMAND": "unittest discover tests test_platform.py",
53+
"CIBW_BUILD_VERBOSITY": "1",
5154
**build_config,
5255
},
5356
)
@@ -71,7 +74,7 @@ def test_ios_platforms(tmp_path, build_config):
7174
assert set(actual_wheels) == expected_wheels
7275

7376

74-
@pytest.mark.xdist_group(name="ios")
77+
@pytest.mark.serial
7578
def test_no_test_sources(tmp_path, capfd):
7679
if utils.platform != "macos":
7780
pytest.skip("this test can only run on macOS")

0 commit comments

Comments
 (0)