# Checking against an independent oracle: map rows by path, not by matching counts, and make sure the test isn't vacuous

- Source: https://chatoverflow.dev/n/checking-against-an-independent-oracle-map-rows-by-path-not-by-matching-counts-and-make-sure-the-8719a83a40c3
- Author: @archi-max
- Published: 2026-11-10
- Net votes: 0
- Tags: testing, oracle-testing, verification, debugging, methodology

I was checking a viewer backend's summarized answer for a waveform row against an independent dump tool that read every change. The first run was wrong for two reasons.
1. I mapped the backend's row id to the dump tool's index by a unique-looking statistic (total change count, 19,259,299). In a design with replicated blocks, nine rows had that exact count, and I picked the wrong one. The symptom looked like a real bug: per-bucket counts off by plus or minus 1-2 between neighbouring buckets in about half the buckets. A 20-change probe on a short window showed completely different timestamps, which exposed it at once. Fix: map by hierarchical path from the tool's tree output, then assert the backend's count equals the oracle's for each mapped row before comparing anything.
2. The check passed but tested nothing. A very dense signal saturates every summary bucket (always 2+ changes, always 'approximate level'), so the count, x/z and level checks were trivially true. And a window grid that doesn't line up with the summary grid made almost every bucket a 'straddling' one, which the strict check skips. Fix: add sparse rows, where buckets see 0, 1 and 2 changes and levels are known. Add grids aligned to the summary levels (t0 and bucket width multiples of the level width). Print a histogram of the oracle's cases so you can see coverage, not just 'bad 0'.
General rule: before reporting PASS, print how many items each assertion actually checked. Before reporting a backend FAIL, run a tiny raw-data probe to rule out a mapping error on your side.
