@@ -18,17 +18,60 @@ jobs:
1818 shell : bash
1919 run : |
2020 mkdir -p "$RUNNER_TEMP/v3-cleanup-contracts"
21- python3 - <<'PYTHON'
22- import hashlib, json, os, subprocess, sys
21+ cat > "$RUNNER_TEMP/v3-cleanup-command-contracts.py" <<'PYTHON'
22+ import hashlib, importlib.util, json, os, subprocess, sys, unittest
2323 from pathlib import Path
2424 source = Path.cwd()
25+ output = Path(os.environ['RUNNER_TEMP'], 'v3-cleanup-contracts')
2526 paths = ('scripts/lib/package_commands.py', 'scripts/test-v3-installed-consumer.py')
2627 receipt = dict(source_sha=subprocess.check_output(['git', 'rev-parse', 'HEAD'], text=True).strip(),
2728 python=sys.version, hashes={p: hashlib.sha256((source / p).read_bytes()).hexdigest() for p in paths})
28- Path(os.environ['RUNNER_TEMP'], 'v3-cleanup-contracts/source.json').write_text(json.dumps(receipt, indent=2) + '\n')
29+ (output / 'source.json').write_text(json.dumps(receipt, indent=2) + '\n')
30+ spec = importlib.util.spec_from_file_location('native_contracts', source / paths[1])
31+ contracts = importlib.util.module_from_spec(spec)
32+ spec.loader.exec_module(contracts)
33+ snapshot = contracts.commands._process_snapshot
34+ failures = []
35+ current_test = None
36+ def observed_snapshot(deadline):
37+ try:
38+ return snapshot(deadline)
39+ except Exception as error:
40+ item = dict(test=current_test, error=str(error))
41+ frame = error.__traceback__
42+ while frame:
43+ if frame.tb_frame.f_code.co_name == '_process_snapshot':
44+ values = frame.tb_frame.f_locals
45+ item.update(line=values.get('line'), fields=values.get('fields'))
46+ buffer = values.get('output')
47+ if buffer is not None:
48+ data = buffer.getvalue()
49+ path = output / ('snapshot-%04d.log' % len(failures))
50+ path.write_bytes(data)
51+ item.update(log=path.name, bytes=len(data), sha256=hashlib.sha256(data).hexdigest())
52+ frame = frame.tb_next
53+ failures.append(item)
54+ (output / 'snapshot-failures.json').write_text(json.dumps(failures, indent=2) + '\n')
55+ raise
56+ # Retain parser evidence without replacing discovery, signals, or errors.
57+ contracts.commands._process_snapshot = observed_snapshot
58+ class Result(unittest.TextTestResult):
59+ def startTest(self, test):
60+ global current_test
61+ current_test = test.id()
62+ super().startTest(test)
63+ suite = unittest.defaultTestLoader.loadTestsFromTestCase(contracts.CommandsTest)
64+ expected = [test.id() for test in suite]
65+ result = unittest.TextTestRunner(verbosity=2, resultclass=Result).run(suite)
66+ report = dict(expected=expected, tests_run=result.testsRun, successful=result.wasSuccessful(),
67+ failures=[test.id() for test, _ in result.failures],
68+ errors=[test.id() for test, _ in result.errors],
69+ skipped=[dict(test=test.id(), reason=reason) for test, reason in result.skipped])
70+ (output / 'result.json').write_text(json.dumps(report, indent=2) + '\n')
71+ raise SystemExit(not result.wasSuccessful())
2972 PYTHON
3073 set +e
31- python3 scripts/test- v3-installed-consumer .py CommandsTest 2>&1 | tee "$RUNNER_TEMP/v3-cleanup-contracts/commands-test.log"
74+ python3 "$RUNNER_TEMP/ v3-cleanup-command-contracts .py" 2>&1 | tee "$RUNNER_TEMP/v3-cleanup-contracts/commands-test.log"
3275 status=${PIPESTATUS[0]}
3376 printf '%s\n' "$status" > "$RUNNER_TEMP/v3-cleanup-contracts/exit-status"
3477 exit "$status"
@@ -166,7 +209,16 @@ jobs:
166209 assert receipt['hashes'] == binding['hashes'] == hashes
167210 assert receipt['python'] == binding['python']
168211 assert (contracts / 'exit-status').read_text().strip() == '0'
169- assert '\nOK\n' in (contracts / 'commands-test.log').read_text()
212+ result = json.loads((contracts / 'result.json').read_text())
213+ assert result['successful'] and not result['failures'] and not result['errors']
214+ assert result['tests_run'] == len(result['expected']) == 22
215+ assert len(set(result['expected'])) == 22
216+ expected_skips = {
217+ 'native_contracts.CommandsTest.test_cleanup_discovery_failure_retains_original_error',
218+ 'native_contracts.CommandsTest.test_new_live_member_delays_retirement_and_zombies_do_not',
219+ 'native_contracts.CommandsTest.test_discovery_consumes_cleanup_deadline_without_restarting_wait'}
220+ assert len(result['skipped']) == 3
221+ assert {item['test'] for item in result['skipped']} == expected_skips
170222 assert receipt['uname'][0] == 'Darwin'
171223 assert len(receipt['commands']) == 3
172224 assert all(item['result'] == 'success' for item in receipt['commands'])
0 commit comments