Skip to content

Commit 01840e6

Browse files
authored
Classify native target failures separately (#177)
1 parent db3b2c1 commit 01840e6

5 files changed

Lines changed: 29 additions & 0 deletions

File tree

‎docs/specs/robustness-v1.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Formalize the existing canonical verification as the conformance gate and add a
3535
- Run every bounded case through a fresh Python module subprocess with no shell interpolation.
3636
- Treat CSV, object JSONL, both Parquet settings, Lance base, and both Vortex settings as core targets.
3737
- Treat TsFile and the pinned FastLanes experiment as evidence-only targets.
38+
- Classify a non-zero exit from a project-seeded native target as `TARGET_FAILED`/`FAIL`; reserve `HARNESS_FAILED`/`INCOMPLETE` for runner, setup, or contract errors.
3839
- Cover row counts 0, 1, 1023, 1024, 1025, 2048, and 2049; dictionary cardinalities 1, 2, 255, and 256; NULL positions; UTF-8 and parser-sensitive strings; numeric boundaries; column-count errors; and truncation.
3940
- Add deterministic Arrow-table generation and empty, truncate, bit-flip, zero-range, append, and region mutation recipes.
4041
- Default full bounded runs to seed 20260703, 32 generated cases, 64 mutations per target, 30 seconds per case, and a 1 GiB artifact budget.

‎src/format_bench/model.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class ObservedOutcome(StrEnum):
4646
TIMED_OUT = "TIMED_OUT"
4747
UNSUPPORTED = "UNSUPPORTED"
4848
BUDGET_EXHAUSTED = "BUDGET_EXHAUSTED"
49+
TARGET_FAILED = "TARGET_FAILED"
4950
HARNESS_FAILED = "HARNESS_FAILED"
5051

5152

‎src/format_bench/robustness/native.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ def _case(
346346
observed = ObservedOutcome.CRASHED
347347
elif process["exit_code"] == 0:
348348
observed = ObservedOutcome.ACCEPTED
349+
elif target.engine == "project-seeded":
350+
observed = ObservedOutcome.TARGET_FAILED
349351
else:
350352
observed = ObservedOutcome.HARNESS_FAILED
351353
details: dict[str, object] = {

‎tests/test_model.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def test_robustness_contract_exposes_the_public_vocabulary() -> None:
6666
("MUST_NOT_CRASH", "REJECTED", "PASS"),
6767
("MUST_NOT_CRASH", "CRASHED", "FAIL"),
6868
("MUST_NOT_CRASH", "TIMED_OUT", "FAIL"),
69+
("MUST_NOT_CRASH", "TARGET_FAILED", "FAIL"),
6970
("MUST_NOT_CRASH", "UNSUPPORTED", "INCOMPLETE"),
7071
("MUST_NOT_CRASH", "BUDGET_EXHAUSTED", "INCOMPLETE"),
7172
("MUST_NOT_CRASH", "HARNESS_FAILED", "INCOMPLETE"),

‎tests/test_robustness_native.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,30 @@ def fake_process(command, cwd, timeout, output_budget_bytes):
213213
assert all(not item.startswith("-max_total_time=") for item in command)
214214

215215

216+
def test_native_suite_classifies_project_seeded_target_failure(
217+
tmp_path: Path, monkeypatch
218+
) -> None:
219+
root = Path(__file__).parents[1]
220+
run_dir = tmp_path / "fastlanes-failed-run"
221+
work_dir = tmp_path / "fastlanes"
222+
_verified_fixture(root, run_dir)
223+
_fake_target(work_dir / "build", "quick_fuzz_test", "print('target failed')")
224+
target = replace(FASTLANES_NATIVE_TARGETS[0], work_dir=work_dir, source_commit=None)
225+
226+
def fake_process(command, cwd, timeout, output_budget_bytes):
227+
return {"timed_out": False, "signal": None, "exit_code": 1}, "", "failed"
228+
229+
monkeypatch.setattr(native, "_process", fake_process)
230+
result_path = run_native(
231+
root, run_dir, duration_seconds=1, artifact_budget_mib=4, targets=(target,)
232+
)
233+
234+
case = json.loads(result_path.read_text())["results"]["robustness_v1"]["cases"][0]
235+
assert case["observed"] == ObservedOutcome.TARGET_FAILED.value
236+
assert case["verdict"] == RobustnessVerdict.FAIL.value
237+
assert case["process"]["exit_code"] == 1
238+
239+
216240
def test_native_suite_rejects_manifest_corpus_traversal(tmp_path: Path) -> None:
217241
root = Path(__file__).parents[1]
218242
run_dir = tmp_path / "run"

0 commit comments

Comments
 (0)