1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//! Regression pin: forbid hardcoded `<fn_name>` string-literal args to
//! sidecar-path helpers in any tests/*.rs file, AND forbid raw
//! `sidecar_dir().join("<literal>.wprof.pb")`-style path-assembly
//! that bypasses the [`VmResult`] method form.
//!
//! ## The drift class
//!
//! The legacy pattern
//!
//! ```ignore
//! fn assert_wprof_pb_landed(result: &VmResult) -> Result<()> {
//! let pb = wprof_pb_path("my_test_fn_name");
//! assert_wprof_pb_shape(&pb)
//! }
//! ```
//!
//! silently drifts when `my_test_fn_name` is renamed: the macro
//! stamps the new name into the sidecar path, but the callback
//! reads the OLD literal → ENOENT → spurious "wprof chain broken"
//! diagnostic that's actually a name-drift bug. The structural fix
//! moved path derivation onto
//! [`VmResult::wprof_pb_path`](ktstr::vmm::VmResult::wprof_pb_path),
//! which reads the macro-stamped
//! [`VmResult::entry_name`](ktstr::vmm::VmResult::entry_name) at
//! call time — no literal to drift.
//!
//! ## Two vectors to defend against
//!
//! 1. **Function-arg literal**: `wprof_pb_path("foo")` /
//! `failure_dump_path("foo")` — direct literal as the path
//! helper's argument.
//! 2. **Path-assembly literal**: `sidecar_dir().join("foo.wprof.pb")`
//! — bypasses the helper entirely; the fn name lives in the
//! suffix-bearing string.
//!
//! Vector 2 is the auto-repro fault-injection pattern: a test body
//! fn that assembles `sidecar_dir().join("<fixture>.repro.wprof.pb")`
//! for an operator diagnostic string. Body fns get `&Ctx` not
//! `&VmResult`, so the method-form migration that fixes vector 1
//! doesn't apply directly to vector 2; the regression pin catches
//! both vectors so a future migration covers the body-callsite class
//! via the same enforcement.
//!
//! ## EXEMPT_FILES
//!
//! Files KNOWN to violate the patterns today and tracked under the
//! follow-up migration are listed in [`EXEMPT_FILES`] below. The
//! exempt list shrinks as the body-callsite migration lands; each
//! removal from the list is the structural pin that the migration
//! actually fixed the site rather than just suppressing the
//! regression test.
use Path;
/// File the regression pin lives in — exempted via top-level path
/// match (not bare filename) to prevent a future
/// `tests/<subdir>/no_hardcoded_dump_path_literals.rs` from also
/// being exempted by accident.
const SELF_FILE: &str = "no_hardcoded_dump_path_literals.rs";
/// Files KNOWN to contain forbidden literal patterns today, tracked
/// under follow-up migrations. Each entry is the path relative to
/// `tests/` (e.g. `foo_e2e.rs`). The exempt list
/// shrinks as migrations land; an entry that no longer contains a
/// violation can be safely removed — at which point this test
/// guards that the site stays clean.
///
/// Current entries: none.
///
/// All test-body-scope callsites have migrated to the
/// `ctx.failure_dump_path()` / `ctx.wprof_pb_path()` /
/// `ctx.repro_wprof_pb_path()` method form. The duplicate
/// `fn failure_dump_path` definitions in `cast_analysis_e2e.rs` and
/// `vm_integration.rs` and the sibling `fn watch_snapshot_dump_path`
/// in `snapshot_e2e.rs` are deleted; the `common/dump_paths.rs`
/// helper module is gone too (zero remaining consumers after the
/// callsite migration, and the format-string single-source-of-truth
/// now lives in the body of `Ctx::failure_dump_path` and
/// `VmResult::failure_dump_path`).
///
/// The empty exempt list makes the FORBIDDEN_PATTERNS sweep
/// load-bearing for every test file in the tree — a future attempt
/// to reintroduce a `failure_dump_path("literal")` callsite or
/// a `sidecar_dir().join("<fn>.failure-dump.json")` path-assembly
/// trips the meta-grep test rather than silently shipping a
/// drift-fragile literal.
const EXEMPT_FILES: & = &;
/// Forbidden literal-arg + path-assembly patterns.
const FORBIDDEN_PATTERNS: & = &;
/// Pins [`EXEMPT_FILES`] empty post-migration. A future entry
/// added without an explicit follow-up migration plan trips this
/// guard — the empty-list shape is what makes
/// [`FORBIDDEN_PATTERNS`] load-bearing for every test file in
/// the tree.
///
/// A regression that reintroduces an exempt-listed test file
/// (e.g. someone adds a literal-arg callsite back, then exempts
/// the file to silence the regression pin) flips this assertion
/// from PASS to FAIL with an actionable message naming the new
/// exemption — the only legitimate way past this gate is to
/// migrate the underlying callsite to the drift-safe form OR
/// extend the list with a focused doc-comment explaining why the
/// exemption is acceptable, both of which a reviewer would
/// see in the pull request diff for this file.