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.
This commit is contained in:
@@ -36,7 +36,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-14]
|
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-15]
|
||||||
python_version: ['3.13']
|
python_version: ['3.13']
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
|
|||||||
+31
-3
@@ -34,15 +34,39 @@ if __name__ == "__main__":
|
|||||||
if args.run_podman:
|
if args.run_podman:
|
||||||
unit_test_args += ["--run-podman"]
|
unit_test_args += ["--run-podman"]
|
||||||
|
|
||||||
|
print(
|
||||||
|
"\n\n================================== UNIT TESTS ==================================",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
subprocess.run(unit_test_args, check=True)
|
subprocess.run(unit_test_args, check=True)
|
||||||
|
|
||||||
# integration tests
|
# Run the serial integration tests without multiple processes
|
||||||
|
serial_integration_test_args = [
|
||||||
|
sys.executable,
|
||||||
|
"-m",
|
||||||
|
"pytest",
|
||||||
|
"-m",
|
||||||
|
"serial",
|
||||||
|
"-x",
|
||||||
|
"--durations",
|
||||||
|
"0",
|
||||||
|
"--timeout=2400",
|
||||||
|
"test",
|
||||||
|
"-vv",
|
||||||
|
]
|
||||||
|
print(
|
||||||
|
"\n\n=========================== SERIAL INTEGRATION TESTS ===========================",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
subprocess.run(serial_integration_test_args, check=True)
|
||||||
|
|
||||||
|
# Non-serial integration tests
|
||||||
integration_test_args = [
|
integration_test_args = [
|
||||||
sys.executable,
|
sys.executable,
|
||||||
"-m",
|
"-m",
|
||||||
"pytest",
|
"pytest",
|
||||||
"--dist",
|
"-m",
|
||||||
"loadgroup",
|
"not serial",
|
||||||
f"--numprocesses={args.num_processes}",
|
f"--numprocesses={args.num_processes}",
|
||||||
"-x",
|
"-x",
|
||||||
"--durations",
|
"--durations",
|
||||||
@@ -55,4 +79,8 @@ if __name__ == "__main__":
|
|||||||
if sys.platform.startswith("linux") and args.run_podman:
|
if sys.platform.startswith("linux") and args.run_podman:
|
||||||
integration_test_args += ["--run-podman"]
|
integration_test_args += ["--run-podman"]
|
||||||
|
|
||||||
|
print(
|
||||||
|
"\n\n========================= NON-SERIAL INTEGRATION TESTS =========================",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
subprocess.run(integration_test_args, check=True)
|
subprocess.run(integration_test_args, check=True)
|
||||||
|
|||||||
+3
-1
@@ -102,7 +102,9 @@ junit_family = "xunit2"
|
|||||||
xfail_strict = true
|
xfail_strict = true
|
||||||
filterwarnings = ["error"]
|
filterwarnings = ["error"]
|
||||||
log_cli_level = "info"
|
log_cli_level = "info"
|
||||||
|
markers = [
|
||||||
|
"serial: tests that must *not* be run in parallel (deselect with '-m \"not serial\"')",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
python_version = "3.11"
|
python_version = "3.11"
|
||||||
|
|||||||
@@ -18,6 +18,15 @@ basic_project = test_projects.new_c_project(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.serial
|
||||||
|
def test_dummy_serial():
|
||||||
|
"""A no-op test to ensure that at least one serial test is always found.
|
||||||
|
|
||||||
|
Without this no-op test, CI fails on CircleCI because no serial tests are
|
||||||
|
found, and pytest errors if a test suite finds no tests.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test(tmp_path, build_frontend_env, capfd):
|
def test(tmp_path, build_frontend_env, capfd):
|
||||||
project_dir = tmp_path / "project"
|
project_dir = tmp_path / "project"
|
||||||
basic_project.generate(project_dir)
|
basic_project.generate(project_dir)
|
||||||
|
|||||||
+8
-5
@@ -20,10 +20,12 @@ class TestPlatform(TestCase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# iOS tests shouldn't be run in parallel, because they're dependent on starting
|
# iOS tests shouldn't be run in parallel, because they're dependent on calling
|
||||||
# a simulator. It's *possible* to start multiple simulators, but not advisable
|
# Xcode, and starting a simulator. These are both multi-threaded operations, and
|
||||||
# to start as many simulators as there are CPUs on the test machine.
|
# it's easy to overload the CI machine if there are multiple test processes
|
||||||
@pytest.mark.xdist_group(name="ios")
|
# running multithreaded processes. Therefore, they're put in the serial group,
|
||||||
|
# which is guaranteed to run single-process.
|
||||||
|
@pytest.mark.serial
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"build_config",
|
"build_config",
|
||||||
[
|
[
|
||||||
@@ -48,6 +50,7 @@ def test_ios_platforms(tmp_path, build_config):
|
|||||||
"CIBW_BUILD": "cp313-*",
|
"CIBW_BUILD": "cp313-*",
|
||||||
"CIBW_TEST_SOURCES": "tests",
|
"CIBW_TEST_SOURCES": "tests",
|
||||||
"CIBW_TEST_COMMAND": "unittest discover tests test_platform.py",
|
"CIBW_TEST_COMMAND": "unittest discover tests test_platform.py",
|
||||||
|
"CIBW_BUILD_VERBOSITY": "1",
|
||||||
**build_config,
|
**build_config,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -71,7 +74,7 @@ def test_ios_platforms(tmp_path, build_config):
|
|||||||
assert set(actual_wheels) == expected_wheels
|
assert set(actual_wheels) == expected_wheels
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xdist_group(name="ios")
|
@pytest.mark.serial
|
||||||
def test_no_test_sources(tmp_path, capfd):
|
def test_no_test_sources(tmp_path, capfd):
|
||||||
if utils.platform != "macos":
|
if utils.platform != "macos":
|
||||||
pytest.skip("this test can only run on macOS")
|
pytest.skip("this test can only run on macOS")
|
||||||
|
|||||||
Reference in New Issue
Block a user