mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-06 12:33:51 +08:00
72 lines
3.6 KiB
Python
72 lines
3.6 KiB
Python
"""Keep custom pytest-function tests in the hosted shard selection and completion gate."""
|
|
|
|
import ast
|
|
from pathlib import Path
|
|
import re
|
|
import unittest
|
|
|
|
from tools.ci.run_host_tests import UI_PYTEST_FILES, pytest_files
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[3]
|
|
|
|
|
|
class TestFeatureTestDiscovery(unittest.TestCase):
|
|
def assert_hosted_pytest_contract(self, workflow):
|
|
jobs = dict(re.findall(r'^ ([a-z_]+):\n(.*?)(?=^ [a-z_]+:|\Z)', workflow, re.M | re.S))
|
|
shards = jobs['custom_pytest']
|
|
complete = jobs['custom_pytest_complete']
|
|
matrix = re.search(r'^ shard: (\[.*\])$', shards, re.M)
|
|
self.assertIsNotNone(matrix)
|
|
self.assertEqual(ast.literal_eval(matrix[1]), list(range(24)))
|
|
self.assertIn(' fail-fast: false\n', shards)
|
|
self.assertNotIn('continue-on-error:', shards + complete)
|
|
self.assertIn(' run: .venv/bin/python -m tools.ci.custom_pytest_shards run '
|
|
+ '--index "${{ matrix.shard }}" --count 24 --output "ci-results/custom-pytest-${{ matrix.shard }}"\n', shards)
|
|
self.assertIn(' name: custom-pytest-${{ matrix.shard }}\n', shards)
|
|
self.assertIn(' path: ci-results/custom-pytest-${{ matrix.shard }}/\n', shards)
|
|
self.assertIn(' if-no-files-found: error\n', shards)
|
|
self.assertIn(' needs: custom_pytest\n', complete)
|
|
self.assertIn(' if: always()\n', complete)
|
|
self.assertIn(' pattern: custom-pytest-*\n', complete)
|
|
self.assertIn(' path: ci-results/custom-pytest-shards\n', complete)
|
|
self.assertIn(' run: python3 -m tools.ci.custom_pytest_shards aggregate '
|
|
+ '--directory ci-results/custom-pytest-shards --count 24 --output ci-results/custom-pytest-complete.json\n', complete)
|
|
|
|
def test_hosted_pytest_selection_covers_all_custom_function_tests(self):
|
|
workflow = (ROOT / '.github/workflows/tests.yaml').read_text()
|
|
self.assert_hosted_pytest_contract(workflow)
|
|
selected = pytest_files()
|
|
self.assertIn('openpilot/system/tests/test_sentry.py', selected)
|
|
self.assertIn('openpilot/system/tests/test_sentry.py', UI_PYTEST_FILES)
|
|
self.assertTrue(selected)
|
|
for package in ('flm', 'spot_monitor', 'sentry_mode', 'galaxy', 'ui'):
|
|
self.assertTrue(any(path.startswith(f'openpilot/starpilot/{package}/') for path in selected), package)
|
|
|
|
def test_missing_duplicate_or_mismatched_shards_are_rejected(self):
|
|
workflow = (ROOT / '.github/workflows/tests.yaml').read_text()
|
|
matrix = 'shard: [' + ', '.join(map(str, range(24))) + ']'
|
|
for replacement in (list(range(23)), list(range(23)) + [22], list(range(25))):
|
|
with self.subTest(matrix=replacement), self.assertRaises(AssertionError):
|
|
self.assert_hosted_pytest_contract(workflow.replace(matrix, 'shard: ' + str(replacement)))
|
|
with self.assertRaises(AssertionError):
|
|
self.assert_hosted_pytest_contract(workflow.replace('--count 24', '--count 23'))
|
|
|
|
def test_completion_and_full_runner_cannot_be_bypassed(self):
|
|
workflow = (ROOT / '.github/workflows/tests.yaml').read_text()
|
|
for old, new in (
|
|
('fail-fast: false', 'fail-fast: true'),
|
|
('needs: custom_pytest', 'needs: unit_tests'),
|
|
(' if: always()\n', ' if: success()\n'),
|
|
('pattern: custom-pytest-*', 'pattern: custom-pytest-0'),
|
|
('if-no-files-found: error', 'if-no-files-found: ignore'),
|
|
('--count 24 --output', '--count 24 -k selected --output'),
|
|
(' needs: custom_pytest', ' continue-on-error: true\n needs: custom_pytest'),
|
|
):
|
|
with self.subTest(change=old), self.assertRaises(AssertionError):
|
|
self.assert_hosted_pytest_contract(workflow.replace(old, new))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|