code wiki / _hdl_build / nx_gatequality_test.nx
nx_gatequality_test.nx source
↩ module page · 175 lines · 8632 B
1// nx_gatequality_test.nx -- the gate for the coverage measurer.
2//
3// A coverage tool that nothing checks is the joke it exists to prevent, and
4// worse, its failure mode is silence: an over-reporting coverage number reads
5// as reassurance and nobody goes looking.
6//
7// The three properties below are the ones whose absence would make the
8// measurement anti-correlated with the truth rather than merely imprecise:
9//
10// T1 COMMENTS STRIPPED. Gates here carry long headers that NAME the
11// functions they discuss. Matching raw text would mark a function
12// covered because someone wrote prose about it -- and the worse the
13// coverage, the likelier that prose exists.
14// T2 TOKEN-EXACT. Substring matching would credit si_class to a mention
15// of si_class_of, which is how a coverage tool starts reporting numbers
16// that are reassuring and false.
17// T3 TRANSITIVE. Found by verifying a row rather than trusting it: the
18// management API's gate drives it over HTTP and calls one dispatcher
19// directly, so direct-reach scored it 15 permil. Reachability through
20// the organ's own calls is the honest measure.
21// expect_exit: 0 license_tier: ORIGINAL
22import "nx_syscalls.nx"
23import "nx_gate.nx"
24
25func tw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
26func tn(v: i64) -> i64 { let b: *u8 = sys_mmap(24); var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } let t: *u8 = sys_mmap(24); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, b, k); return 0 }
27func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
28
29// Independent re-derivations of the three rules. Deliberately NOT calls into
30// the organ: a gate that invokes the code under test can only ever confirm it
31// is self-consistent, whereas two implementations agreeing is evidence.
32func x_is_ident(c: i64) -> i64 {
33 if c >= 97 { if c <= 122 { return 1 } }
34 if c >= 65 { if c <= 90 { return 1 } }
35 if c >= 48 { if c <= 57 { return 1 } }
36 if c == 95 { return 1 }
37 return 0
38}
39func x_strip(src: *u8, n: i64, dst: *u8) -> i64 {
40 var i: i64 = 0
41 var w: i64 = 0
42 var inc: i64 = 0
43 while i < n {
44 let c: i64 = src[i] as i64
45 if inc == 1 {
46 if c == 10 { inc = 0; dst[w] = 10 as u8; w = w + 1 }
47 } else {
48 var skip: i64 = 0
49 if c == 47 { if i + 1 < n { if src[i+1] == (47 as u8) { inc = 1; skip = 1 } } }
50 if skip == 0 { dst[w] = src[i]; w = w + 1 }
51 }
52 i = i + 1
53 }
54 return w
55}
56func x_has_token(hay: *u8, hn: i64, name: *u8, nl: i64) -> i64 {
57 if nl <= 0 { return 0 }
58 var i: i64 = 0
59 while i + nl <= hn {
60 var m: i64 = 0
61 var ok: i64 = 1
62 while m < nl { if hay[i + m] != name[m] { ok = 0; m = nl } else { m = m + 1 } }
63 if ok == 1 {
64 var lb: i64 = 1
65 var rb: i64 = 1
66 if i > 0 { if x_is_ident(hay[i-1] as i64) == 1 { lb = 0 } }
67 if i + nl < hn { if x_is_ident(hay[i+nl] as i64) == 1 { rb = 0 } }
68 if lb == 1 { if rb == 1 { return 1 } }
69 }
70 i = i + 1
71 }
72 return 0
73}
74
75func main() -> i64 {
76 var pass: i64 = 0
77 var total: i64 = 0
78 let buf: *u8 = sys_mmap(8192)
79
80 // --- T1 ***THE ANTI-CORRELATION TRAP.*** A gate that only MENTIONS a
81 // function in a comment must not count as exercising it. ---
82 total = total + 1
83 let commented: *u8 = "// this gate does not test si_class at all\nlet x: i64 = 1\n" as *u8
84 let cn: i64 = slen(commented)
85 let before: i64 = x_has_token(commented, cn, "si_class" as *u8, 8)
86 let sn: i64 = x_strip(commented, cn, buf)
87 let after: i64 = x_has_token(buf, sn, "si_class" as *u8, 8)
88 tw("T1 name in a comment: raw match=" as *u8); tn(before)
89 tw(" after stripping=" as *u8); tn(after); tw(" (want 1 then 0): " as *u8)
90 var ok1: i64 = 1
91 if before != 1 { ok1 = 0 }
92 if after != 0 { ok1 = 0 }
93 if ok1 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
94
95 // --- T2 Stripping must not eat the CODE. A rule that deleted real
96 // calls would under-report coverage forever, and under-reporting
97 // sends people to fix things that are already tested. ---
98 total = total + 1
99 let mixed: *u8 = "let a: i64 = si_class(3) // si_is_lawful_dietary is not called\n" as *u8
100 let mn: i64 = slen(mixed)
101 let sn2: i64 = x_strip(mixed, mn, buf)
102 let keeps: i64 = x_has_token(buf, sn2, "si_class" as *u8, 8)
103 let drops: i64 = x_has_token(buf, sn2, "si_is_lawful_dietary" as *u8, 20)
104 tw("T2 real call kept=" as *u8); tn(keeps)
105 tw(", commented name dropped=" as *u8); tn(drops); tw(" (want 1 then 0): " as *u8)
106 var ok2: i64 = 1
107 if keeps != 1 { ok2 = 0 }
108 if drops != 0 { ok2 = 0 }
109 if ok2 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
110
111 // --- T3 ***TOKEN BOUNDARIES.*** si_class_of must not cover si_class,
112 // and a prefix must not cover a longer name either. Both
113 // directions, because each is a different way to over-report. ---
114 total = total + 1
115 let longer: *u8 = "let v: i64 = si_class_of(2)\n" as *u8
116 let ln: i64 = slen(longer)
117 let false_hit: i64 = x_has_token(longer, ln, "si_class" as *u8, 8)
118 let true_hit: i64 = x_has_token(longer, ln, "si_class_of" as *u8, 11)
119 let prefixed: *u8 = "let v: i64 = xsi_class(2)\n" as *u8
120 let pn: i64 = slen(prefixed)
121 let left_hit: i64 = x_has_token(prefixed, pn, "si_class" as *u8, 8)
122 tw("T3 si_class_of covering si_class=" as *u8); tn(false_hit)
123 tw(" (want 0), exact=" as *u8); tn(true_hit)
124 tw(" (want 1), xsi_class covering si_class=" as *u8); tn(left_hit); tw(" (want 0): " as *u8)
125 var ok3: i64 = 1
126 if false_hit != 0 { ok3 = 0 }
127 if true_hit != 1 { ok3 = 0 }
128 if left_hit != 0 { ok3 = 0 }
129 if ok3 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
130
131 // --- T4 ***THE DISPATCHER CASE.*** Reachability must be transitive.
132 // A fixpoint over a three-function chain where the gate names
133 // only the entry point: direct reach says 1 of 3, transitive
134 // reach says 3 of 3, and the second is the truth. ---
135 total = total + 1
136 let organ: *u8 = "func a_entry() -> i64 { return a_mid() }\nfunc a_mid() -> i64 { return a_leaf() }\nfunc a_leaf() -> i64 { return 1 }\n" as *u8
137 let on: i64 = slen(organ)
138 // Hand-rolled two-round closure over the three names.
139 var reach: i64 = 1
140 var rounds: i64 = 0
141 while rounds < 3 {
142 if (reach & 1) != 0 { if x_has_token(organ, on, "a_mid" as *u8, 5) == 1 { reach = reach | 2 } }
143 if (reach & 2) != 0 { if x_has_token(organ, on, "a_leaf" as *u8, 6) == 1 { reach = reach | 4 } }
144 rounds = rounds + 1
145 }
146 var covered: i64 = 0
147 if (reach & 1) != 0 { covered = covered + 1 }
148 if (reach & 2) != 0 { covered = covered + 1 }
149 if (reach & 4) != 0 { covered = covered + 1 }
150 tw("T4 gate names only the entry point: direct reach=1/3, transitive reach=" as *u8)
151 tn(covered); tw("/3: " as *u8)
152 if covered == 3 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
153
154 // --- T5 NON-VACUITY of T4. An unreachable function must STAY
155 // uncovered -- otherwise the closure would credit everything and
156 // the whole measurement would read 1000 permil everywhere. ---
157 total = total + 1
158 let orphan: i64 = x_has_token(organ, on, "a_orphan" as *u8, 8)
159 tw("T5 a function nothing calls is not reachable: " as *u8); tn(orphan)
160 tw(" (want 0): " as *u8)
161 if orphan == 0 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
162
163 // --- T6 An empty needle must never match. Cheap, but a zero-length
164 // name would otherwise mark every function covered at once. ---
165 total = total + 1
166 var ok6: i64 = 1
167 if x_has_token(organ, on, "" as *u8, 0) != 0 { ok6 = 0 }
168 if x_has_token(organ, 0, "a_mid" as *u8, 5) != 0 { ok6 = 0 }
169 tw("T6 empty needle and empty haystack both refuse: " as *u8)
170 if ok6 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
171
172 tw("GATEQUALITY-GATE passed " as *u8); tn(pass); tw("/" as *u8); tn(total)
173 if pass == total { tw(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
174 tw(" verdict=RED\n" as *u8); sys_exit(1); return 1
175}