diff options
| -rw-r--r-- | test/hil/test/test_drivers_coverage.py | 10 | ||||
| -rw-r--r-- | tools/drivers_coverage_check.py | 11 |
2 files changed, 10 insertions, 11 deletions
diff --git a/test/hil/test/test_drivers_coverage.py b/test/hil/test/test_drivers_coverage.py index a159d2e94..eef508a46 100644 --- a/test/hil/test/test_drivers_coverage.py +++ b/test/hil/test/test_drivers_coverage.py @@ -64,16 +64,14 @@ class CheckerVerdicts(unittest.TestCase): self.addCleanup(os.unlink, tmp.name) return run_checker(tmp.name) - def test_missing_driver_becomes_a_warning_not_a_failure(self): - # drop every entry covering dcd_rp2040 and don't add it to uncovered: a - # coverage gap, not a validity error - it must not fail the run + def test_undocumented_missing_driver_fails(self): + # A new driver must be covered or carry an explicit uncovered reason. def mutate(d): for t in d['boards']: t['drivers'] = [x for x in t['drivers'] if x != 'dcd_rp2040'] r = self._mutated(mutate) - self.assertEqual(r.returncode, 0, r.stderr) - self.assertIn('WARNING: membrowse: dcd_rp2040 has no CI board', r.stdout) - self.assertEqual(r.stderr, '') + self.assertEqual(r.returncode, 1) + self.assertIn('dcd_rp2040 has no CI board and no uncovered entry', r.stderr) def test_unknown_driver_name_fails(self): r = self._mutated(lambda d: d['boards'][0]['drivers'].append('dcd_nonexistent')) diff --git a/tools/drivers_coverage_check.py b/tools/drivers_coverage_check.py index 512b991d2..8c7cd7982 100644 --- a/tools/drivers_coverage_check.py +++ b/tools/drivers_coverage_check.py @@ -7,9 +7,8 @@ board's `drivers` list, or `uncovered`, covers it) and the HIL rig rosters (test/hil/tinyusb.json, test/hil/hfp.json - which board family, if any, on the physical rig builds it). -Coverage GAPS are informational only and never fail the run: a membrowse gap -documented in `uncovered` prints INFO, an undocumented one prints WARNING, -and a driver with no rig board prints INFO. VALIDITY errors - malformed +Documented membrowse gaps and drivers with no rig board are informational. +An undocumented membrowse gap is fatal, as are validity errors: malformed json, an unknown driver/board name, a board/driver mismatch, a board whose family no CI toolchain actually builds (ci_set_matrix.family_list), a driver claimed by both `boards` and `uncovered`, or an hcd_*/ehci/ohci claim on a board that @@ -84,8 +83,7 @@ def load_boards(path): def check(path): - """Validity errors only - fatal, one line each. Coverage gaps (a driver - with no CI board) are no longer errors; see membrowse_gaps().""" + """Fatal roster validity and undocumented coverage errors, one line each.""" errors = [] data = load_boards(path) boards = data.get('boards') @@ -159,6 +157,9 @@ def check(path): if not (isinstance(reason, str) and reason.strip()): errors.append(f'uncovered "{d}": reason must be a non-empty string') + for d in sorted(drivers - covered - set(uncovered)): + errors.append(f'membrowse: {d} has no CI board and no uncovered entry') + return errors |
