reqproof:proptest Set Verifies: SYS-REQ-009 [property]
(t *testing.T)
| 508 | // reqproof:proptest Set |
| 509 | // Verifies: SYS-REQ-009 [property] |
| 510 | func TestOracleSetRoundTrip(t *testing.T) { |
| 511 | r := oracleNewRNG(oracleSeed + 1) |
| 512 | const iterations = 10000 |
| 513 | knownBugPaths := 0 |
| 514 | knownBugPanics := 0 |
| 515 | for i := 0; i < iterations; i++ { |
| 516 | raw, v := oracleRandomJSONBytes(r, 3) |
| 517 | path := pickAdversarialPath(r, v) |
| 518 | setVal := oracleSetValue(r) |
| 519 | semanticallyValid := setPathSemanticallyValid(v, path) |
| 520 | |
| 521 | var out []byte |
| 522 | var serr error |
| 523 | panicked := false |
| 524 | func() { |
| 525 | defer func() { |
| 526 | if rec := recover(); rec != nil { |
| 527 | panicked = true |
| 528 | if semanticallyValid { |
| 529 | t.Fatalf("Set panicked on semantically-valid path: "+ |
| 530 | "input=%q path=%v val=%q: %v", raw, path, setVal, rec) |
| 531 | } |
| 532 | // Adversarial path: document the open panic bug. |
| 533 | // Known reachable via parser.go:981 (Set's nested |
| 534 | // array-of-objects + empty-key path) — see divergence D9. |
| 535 | knownBugPanics++ |
| 536 | t.Logf("D9 known panic — Set on adversarial path panicked "+ |
| 537 | "(open bug at parser.go:981): input=%q path=%v val=%q: %v", |
| 538 | raw, path, setVal, rec) |
| 539 | } |
| 540 | }() |
| 541 | out, serr = Set(raw, setVal, path...) |
| 542 | }() |
| 543 | |
| 544 | if panicked { |
| 545 | continue |
| 546 | } |
| 547 | |
| 548 | if serr != nil { |
| 549 | // Set rejected the operation. The original document MUST still |
| 550 | // be valid JSON (Set must not corrupt on rejection). |
| 551 | if !json.Valid(raw) { |
| 552 | continue // generator invariant violation — skip |
| 553 | } |
| 554 | continue |
| 555 | } |
| 556 | |
| 557 | // THE BUG-CATCHING ASSERTMENT: for semantically-valid paths, the |
| 558 | // output MUST be valid JSON AND Get on the same path MUST return |
| 559 | // the set value. PR #286's bug was that Set returned `out=[9]` |
| 560 | // for `Set([1,2], 9, "[5]")` — Set "succeeded" but the original |
| 561 | // [1,2] was silently destroyed. |
| 562 | // |
| 563 | // For semantically-INVALID paths (D6/D7/D8 — array-index on object |
| 564 | // root, nested OOB index, bracket-key on object), we soft-skip |
| 565 | // both assertions because the operation is ill-defined; those |
| 566 | // cases are documented in the file header and exercised for |
| 567 | // no-panic only via the path-mutation fuzzer in path_fuzz_test.go. |
nothing calls this directly
no test coverage detected