Skip to content

Commit 3ba8040

Browse files
committed
test(native): regenerate goldens and the fallback allow-list from main with one command
1 parent f69740d commit 3ba8040

14 files changed

Lines changed: 3310 additions & 53 deletions

‎Makefile‎

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ SHELL := /bin/bash
88
test-e2e-cold-compile-performance test-e2e-cache-compile-performance \
99
test-e2e-dense-compile-performance test-e2e-varied-cache-performance \
1010
compiler-differential compiler-differential-shipped compiler-differential-dense \
11-
compiler-goldens
11+
compiler-baselines
1212

1313
format:
1414
uv run ruff format .
@@ -295,8 +295,7 @@ COMPILER_DIFFERENTIAL_SHIPPED_SEEDS ?= 12
295295
COMPILER_DIFFERENTIAL_DENSE_MODELS ?= 3000
296296
COMPILER_DIFFERENTIAL_ARGS ?=
297297
# Native-to-Python fallbacks and analysis deferrals must match the allow-list exactly, and every
298-
# output its golden. Pass `--native-fallbacks update` in COMPILER_DIFFERENTIAL_ARGS to rewrite
299-
# the list (see scripts/compiler_differential/README.md).
298+
# output its golden. `make compiler-baselines` rewrites both (see scripts/compiler_differential/README.md).
300299
COMPILER_DIFFERENTIAL_GATES := --native-fallbacks check --goldens check
301300

302301
compiler-differential:
@@ -312,13 +311,15 @@ compiler-differential-shipped:
312311
--jobs $(COMPILER_DIFFERENTIAL_JOBS) --seeds $(COMPILER_DIFFERENTIAL_SHIPPED_SEEDS) \
313312
$(COMPILER_DIFFERENTIAL_GATES) $(COMPILER_DIFFERENTIAL_ARGS)
314313

315-
# Rewrite tests/goldens/compiler from the python oracle (from native once Python is deleted);
316-
# review the diff like code. See scripts/compiler_differential/README.md.
317-
compiler-goldens:
318-
env PYTHONUNBUFFERED=1 uv run python -m scripts.run_compiler_differential \
319-
--engines python native --corpus fixtures examples seeds failures \
320-
--jobs $(COMPILER_DIFFERENTIAL_JOBS) --seeds $(COMPILER_DIFFERENTIAL_SEEDS) \
321-
--goldens update $(COMPILER_DIFFERENTIAL_ARGS)
314+
# Rewrite the goldens (from the python oracle) and the fallback allow-list from both CI runs.
315+
# Review the diff like code; see scripts/compiler_differential/README.md.
316+
COMPILER_DIFFERENTIAL_CI_ARGS := --stage-captures --require-discovery-coverage --require-render-coverage
317+
compiler-baselines:
318+
rm -rf tests/goldens/compiler
319+
$(MAKE) compiler-differential COMPILER_DIFFERENTIAL_ARGS="$(COMPILER_DIFFERENTIAL_CI_ARGS) \
320+
--require-analysis-coverage --native-fallbacks update --goldens update"
321+
$(MAKE) compiler-differential-shipped COMPILER_DIFFERENTIAL_ARGS="$(COMPILER_DIFFERENTIAL_CI_ARGS) \
322+
--native-fallbacks update --goldens update"
322323

323324
compiler-differential-dense:
324325
env PYTHONUNBUFFERED=1 uv run python -m scripts.run_compiler_differential \

‎scripts/compiler_differential/README.md‎

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ does not add its own parity harness, property suite or E2E file.
1515
`native_fallbacks.toml` is the one allow-list of all work native code still hands back to Python.
1616
It covers both kinds of record:
1717
- shipped-stage fallbacks, from `report_native_fallback(site=NativeFallbackSite.<SITE>, kind=...)`;
18-
- preview analysis-stage deferrals, from `record_analysis_deferral` and `record_lineage_deferral`.
18+
- preview analysis-stage deferrals: every `analysis-deferrals-*.jsonl` record (analysis session,
19+
lineage, semantic checks, contracts).
1920

2021
Every entry names an engine, stage, site and kind, with its exact count per corpus. Use
2122
`max_counts` instead of `counts` only for a count that is not stable, and give the reason in a
@@ -29,28 +30,38 @@ sets. `--native-fallbacks check` runs in both make targets and fails CI in both
2930

3031
The counts hold for the make targets' corpus (`--seeds 12`); other seed ranges are refused.
3132

32-
**How a PR updates the list**
33-
34-
1. A port deletes the Python code it replaces in the same PR. Its sites drop to zero and the gate
35-
names the entries to remove; removing them is the port's test that the fallbacks are gone.
36-
When the last entry for a `NativeFallbackSite` goes, delete the member and its
37-
`report_native_fallback` call too.
38-
2. If the corpus does not reach a site yet, first add a failure case or seed feature that does.
39-
3. To rewrite the list from a run, use the same arguments as CI and add `--native-fallbacks
40-
update` to both targets:
41-
42-
```sh
43-
make compiler-differential COMPILER_DIFFERENTIAL_ARGS="--stage-captures \
44-
--require-discovery-coverage --require-render-coverage --require-analysis-coverage \
45-
--native-fallbacks update"
46-
make compiler-differential-shipped COMPILER_DIFFERENTIAL_ARGS="--stage-captures \
47-
--require-discovery-coverage --require-render-coverage --native-fallbacks update"
48-
```
49-
50-
Review the diff. Any added entry or higher count needs a reason in the PR body; never add one
51-
just to make CI pass.
52-
4. The gate is proven by sabotage in `test_native_fallback_gate.py`: forcing a native stage to
53-
defer everything must fail it. A new "native did the work" gate needs the same proof.
33+
**How a PR updates the list and the goldens**
34+
35+
One command rewrites both from the current tree:
36+
37+
```sh
38+
make compiler-baselines
39+
```
40+
41+
It deletes `tests/goldens/compiler`, then runs the two CI differentials with `--native-fallbacks
42+
update --goldens update`. Commit the resulting `native_fallbacks.toml` and `tests/goldens/` diff
43+
in the same PR as the change that caused it.
44+
45+
- A port deletes the Python code it replaces in the same PR. Its entries then disappear from the
46+
list, and that removal is the port's test that the fallbacks are gone. When the last entry for
47+
a `NativeFallbackSite` goes, delete the member and its `report_native_fallback` call too.
48+
- If the corpus does not reach a site yet, first add a failure case or seed feature that does.
49+
- A PR that merges after a list or golden change on main reruns `make compiler-baselines` after
50+
rebasing and commits the result.
51+
52+
**What a reviewer checks in the diff**
53+
54+
- `native_fallbacks.toml`:
55+
- Removed entries and lower counts are expected from ports.
56+
- Every added entry, higher count or new `max_counts` needs a stated reason in the PR body.
57+
Never add one just to make CI pass.
58+
- Goldens:
59+
- Every changed golden is an intended output change, named in the PR body.
60+
- An output-neutral port changes no golden.
61+
- New goldens belong to new corpus cases.
62+
- Proof by sabotage: `test_native_fallback_gate.py` proves the gate by sabotage, so forcing a
63+
native stage to defer everything must fail it. A new "native did the work" gate needs the same
64+
proof.
5465

5566
### Golden outputs
5667

@@ -63,16 +74,17 @@ Project paths, the SQLBuild version, invocation ids and timings are masked.
6374

6475
- `--goldens check` (in both make targets) compares every engine with the goldens, so an
6576
output-neutral port needs no new parity suite.
66-
- `make compiler-goldens` rewrites them from the python oracle. Run it only when output changes
67-
on purpose, and review the diff like code.
77+
- `make compiler-baselines` rewrites them from the python oracle. Run it only when output
78+
changes on purpose, and review the diff like code.
6879
- Seeds outside the recorded range have no golden and are skipped; any other project without a
6980
golden fails.
7081
- Once the Python stages are deleted, goldens are rewritten from `native`.
7182

7283
### All-engine user-facing errors
7384

74-
`engine_error_cases()` in `_helpers/corpus/failure_cases.py` lists user-facing errors with their exact text. Each case
75-
is part of the failure corpus, so it runs in both differentials and has a golden. It also runs in
85+
`engine_error_cases()` in `_helpers/corpus/failure_cases.py` lists user-facing errors with their
86+
exact text. Each case is part of the failure corpus, so it runs in both differentials and has a
87+
golden. It also runs in
7688
`tests/e2e/scripts/compiler_differential/test_engine_error_cases.py` on the `python`, `native`
7789
and `native-preview` engines, which must all report its `expected_code` and `expected_message`.
7890

@@ -87,4 +99,4 @@ failure_case(
8799
)
88100
```
89101

90-
Then it runs `make compiler-goldens` to record the new case's golden.
102+
Then it runs `make compiler-baselines` to record the new case's golden.

‎scripts/compiler_differential/constants.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
"type_recovery.py": "semantic_checks",
2525
"recovery.py": "semantic_checks",
2626
"metadata_validation.py": "semantic_checks",
27+
"contracts/columns.py": "contracts",
28+
"contracts/promotion.py": "contracts",
2729
}
2830
NATIVE_FALLBACK_DEFERRAL_UNKNOWN_STAGE: str = "analysis"
2931
NATIVE_FALLBACK_LIST_HEADER: str = (
@@ -48,7 +50,7 @@
4850
)
4951
GOLDEN_PATH_MASK: str = "<project>"
5052
GOLDEN_VERSION_MASK: str = "<sqlbuild-version>"
51-
GOLDEN_MISSING_HINT: str = "no golden; record it with `make compiler-goldens`"
53+
GOLDEN_MISSING_HINT: str = "no golden; record it with `make compiler-baselines`"
5254
ENGINE_NAMES: tuple[str, ...] = ("python", "native", "native-preview")
5355
DEFAULT_ENGINES: tuple[str, str] = ("python", "native-preview")
5456
SQB_ENTRY: str = "import sys; from sqlbuild.cli.entry.main.entry import main; sys.exit(main())"

‎scripts/compiler_differential/native_fallbacks.toml‎

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,14 @@ engine = "native"
7979
stage = "model_config"
8080
site = "model_config.python_templates"
8181
kind = "config"
82-
counts = { failure = 98, seed = 36 }
82+
counts = { failure = 108, seed = 36 }
8383

8484
[[entry]]
8585
engine = "native"
8686
stage = "model_config"
8787
site = "model_config.python_templates"
8888
kind = "connection"
89-
counts = { failure = 100, seed = 63 }
89+
counts = { failure = 110, seed = 63 }
9090

9191
[[entry]]
9292
engine = "native"
@@ -114,7 +114,7 @@ engine = "native"
114114
stage = "model_loop"
115115
site = "model_loop.cursor_intrinsic_validation"
116116
kind = "deferred"
117-
counts = { failure = 366, seed = 1100 }
117+
counts = { failure = 387, seed = 1100 }
118118

119119
[[entry]]
120120
engine = "native"
@@ -191,7 +191,7 @@ engine = "native-preview"
191191
stage = "model_analysis"
192192
site = "analysis_session"
193193
kind = "input_enrichment"
194-
counts = { example = 52, failure = 170, fixture = 52, seed = 614 }
194+
counts = { example = 52, failure = 182, fixture = 52, seed = 614 }
195195

196196
[[entry]]
197197
engine = "native-preview"
@@ -226,14 +226,14 @@ engine = "native-preview"
226226
stage = "model_config"
227227
site = "model_config.python_templates"
228228
kind = "config"
229-
counts = { example = 12, failure = 98, fixture = 8, seed = 36 }
229+
counts = { example = 12, failure = 108, fixture = 8, seed = 36 }
230230

231231
[[entry]]
232232
engine = "native-preview"
233233
stage = "model_config"
234234
site = "model_config.python_templates"
235235
kind = "connection"
236-
counts = { example = 18, failure = 100, fixture = 9, seed = 63 }
236+
counts = { example = 18, failure = 110, fixture = 9, seed = 63 }
237237

238238
[[entry]]
239239
engine = "native-preview"
@@ -261,7 +261,7 @@ engine = "native-preview"
261261
stage = "model_loop"
262262
site = "model_loop.cursor_intrinsic_validation"
263263
kind = "deferred"
264-
counts = { example = 56, failure = 366, fixture = 64, seed = 1100 }
264+
counts = { example = 56, failure = 387, fixture = 64, seed = 1100 }
265265

266266
[[entry]]
267267
engine = "native-preview"
@@ -283,10 +283,3 @@ stage = "model_loop"
283283
site = "model_loop.sql_variables"
284284
kind = "error"
285285
counts = { failure = 2 }
286-
287-
[[entry]]
288-
engine = "native-preview"
289-
stage = "semantic_checks"
290-
site = "metadata_validation.py"
291-
kind = "metadata_checks"
292-
counts = { example = 12, failure = 95, fixture = 8, seed = 36 }

0 commit comments

Comments
 (0)