[trace_replay] (P7): persist cancelled TCP attempts in results JSON

This commit is contained in:
2026-09-23 02:12:40 -04:00
parent 3ce5b9913e
commit 7ea7ce89cb
2 changed files with 31 additions and 1 deletions
+13 -1
View File
@@ -520,8 +520,20 @@ def main(argv=None):
try:
run_case(plan, args, row)
except KeyboardInterrupt:
row.update(status="cancelled", returncode=130)
# An outer timeout sends SIGTERM, which our handler turns
# into KeyboardInterrupt. Preserve a terminal row in BOTH
# ledgers; otherwise the wrapper sees rc=124 but no
# results.json and cannot distinguish cancellation from a
# driver that never wrote evidence.
row.update(status="cancelled", returncode=130,
completed_at_ns=time.time_ns())
row.setdefault("seconds", round((row["completed_at_ns"] - row["started_at_ns"]) / 1e9, 3))
atomic_json(checkpoint_path, checkpoint)
selected.append({**row, "resumed": False})
atomic_json(args.out / "results.json", selected)
print(json.dumps({k: row.get(k) for k in
("case", "backend", "status", "returncode", "seconds", "timeout_kind", "error")}),
flush=True)
return 130
except Exception as error:
row.update(status="failed", returncode=1, error=str(error))
+18
View File
@@ -10,6 +10,7 @@ import tempfile
import textwrap
import types
import unittest
from unittest import mock
sys.path.insert(0, str(Path(__file__).resolve().parent))
import run_tcp_matrix as matrix
@@ -153,6 +154,23 @@ class MatrixTests(unittest.TestCase):
self.assertEqual(len(self.checkpoint()),2)
self.assertTrue(all(row['status']=='failed' and row['returncode']==7 for row in self.checkpoint()))
def test_interrupted_run_keeps_a_terminal_result_and_reruns_on_resume(self):
with mock.patch.object(matrix, 'run_case', side_effect=KeyboardInterrupt):
self.assertEqual(self.run_main(), 130)
checkpoint = self.checkpoint()
self.assertEqual(len(checkpoint), 1)
self.assertEqual(checkpoint[0]['status'], 'cancelled')
self.assertEqual(checkpoint[0]['returncode'], 130)
self.assertGreaterEqual(checkpoint[0]['seconds'], 0)
self.assertIn('completed_at_ns', checkpoint[0])
result = matrix.read_json(self.out/'results.json')
self.assertEqual(len(result), 1)
self.assertEqual(result[0]['status'], 'cancelled')
self.assertFalse(result[0]['resumed'])
self.assertEqual(self.run_main('--resume'), 0)
self.assertEqual(len(self.checkpoint()), 2)
self.assertEqual(matrix.read_json(self.out/'results.json')[0]['status'], 'passed')
def test_timeout_with_passed_json_is_not_resumed_as_success(self):
self.write_inputs('timeout')
self.assertEqual(self.run_main('--idle-seconds','.2'),1)