code wiki / _hdl_build / nx_gatelib_test.nx
nx_gatelib_test.nx source
↩ module page · 170 lines · 9270 B
1// nx_gatelib_test.nx -- the gate the extracted library needed immediately.
2//
3// ★DE-DUPLICATING CREATED A NEW UNGATED LOAD-BEARING ORGAN. Folding nine
4// duplicated functions into one library gave that library two consumers and
5// no test of its own -- precisely the class the consumers exist to find. A
6// refactor that removes duplication while adding unverified code has moved
7// the debt, not paid it.
8//
9// ⚠AND MY OWN SCANNER DID NOT SURFACE IT. With two consumers the library
10// scores severity 2, which ranks BELOW the fixed floor of 3 given to organs
11// nothing calls at all, so it sat under 5020 dead files in the ranking. A
12// load-bearing organ with two consumers matters MORE than a dead one with
13// none, and the ranking said the opposite. Filed against nx_gatescan and
14// noted here because the tool found nothing while the defect was real.
15//
16// This gate calls the library DIRECTLY. The two consumer gates keep their
17// own independent re-derivations of the same rules, and that is deliberate:
18// a direct unit test proves the library does what it says, while a separate
19// implementation agreeing proves the rule itself is right. They answer
20// different questions and neither replaces the other.
21// expect_exit: 0 license_tier: ORIGINAL
22import "nx_syscalls.nx"
23import "nx_gatelib.nx"
24import "nx_gate.nx"
25
26func tw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
27func 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 }
28
29func main() -> i64 {
30 var pass: i64 = 0
31 var total: i64 = 0
32
33 // --- T1 The .nx and gate-name predicates, both directions. These
34 // decide which files are organs at all, so a wrong answer here
35 // shifts every downstream count. ---
36 total = total + 1
37 var ok1: i64 = 1
38 if gl_is_nx("nx_foo.nx" as *u8, 9) != 1 { ok1 = 0 }
39 if gl_is_nx("nx_foo.txt" as *u8, 10) != 0 { ok1 = 0 }
40 if gl_is_nx("nx" as *u8, 2) != 0 { ok1 = 0 }
41 if gl_is_gate_name("nx_foo_test.nx" as *u8, 14) != 1 { ok1 = 0 }
42 if gl_is_gate_name("nx_foo_gate.nx" as *u8, 14) != 1 { ok1 = 0 }
43 if gl_is_gate_name("nx_foo.nx" as *u8, 9) != 0 { ok1 = 0 }
44 tw("T1 .nx and gate-name predicates correct in both directions: " as *u8)
45 if ok1 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
46
47 // --- T2 gl_ends must not read before the start of a string when the
48 // suffix is longer than the name. An out-of-bounds compare here
49 // would be a silent memory read, not a wrong answer. ---
50 total = total + 1
51 var ok2: i64 = 1
52 if gl_ends("a.nx" as *u8, 4, "_test.nx" as *u8) != 0 { ok2 = 0 }
53 if gl_ends("" as *u8, 0, "_test.nx" as *u8) != 0 { ok2 = 0 }
54 if gl_ends("nx_x_test.nx" as *u8, 12, "_test.nx" as *u8) != 1 { ok2 = 0 }
55 tw("T2 ends-with refuses a suffix longer than the name (no under-read): " as *u8)
56 if ok2 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
57
58 // --- T3 ***THE ATTRIBUTION RULE -- the reason this library exists.***
59 // Both tools must agree on it, and the underscore is the whole
60 // rule: it credits the aspect-named gate to its organ while
61 // refusing to credit a different organ with a shorter name. ---
62 total = total + 1
63 let g: *EcoGraph = eg_new(64, 128, 8192, 256)
64 let sha: i64 = eg_intern(g, "nx_sha256.nx" as *u8, 12)
65 let str: i64 = eg_intern(g, "nx_str.nx" as *u8, 9)
66 eg_intern(g, "nx_strategy.nx" as *u8, 14)
67 eg_finalize(g)
68 let buf: *u8 = sys_mmap(512)
69 let a1: i64 = gl_attribute(g, "nx_sha256_kat_test.nx" as *u8, 21, buf)
70 let a2: i64 = gl_attribute(g, "nx_strategy_test.nx" as *u8, 19, buf)
71 let a3: i64 = gl_attribute(g, "nx_sha256_test.nx" as *u8, 17, buf)
72 tw("T3 aspect gate -> organ=" as *u8); tn(a1); tw(" (want " as *u8); tn(sha)
73 tw("), nx_strategy_test -> " as *u8); tn(a2); tw(" (must NOT be nx_str=" as *u8); tn(str)
74 tw("), exact gate -> " as *u8); tn(a3); tw(": " as *u8)
75 var ok3: i64 = 1
76 if a1 != sha { ok3 = 0 }
77 if a2 == str { ok3 = 0 }
78 if a3 != sha { ok3 = 0 }
79 if ok3 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
80
81 // --- T4 Attribution refuses a non-gate outright, rather than guessing
82 // at an organ from a file that is not a gate at all. ---
83 total = total + 1
84 var ok4: i64 = 1
85 if gl_attribute(g, "nx_sha256.nx" as *u8, 12, buf) != 0 - 1 { ok4 = 0 }
86 if gl_attribute(g, "_test.nx" as *u8, 8, buf) != 0 - 1 { ok4 = 0 }
87 tw("T4 a non-gate file attributes to nothing: " as *u8)
88 if ok4 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
89
90 // --- T5 Token matching, both over-report directions. A longer name
91 // must not cover a shorter one and a prefix must not cover a
92 // suffix -- each is a separate way to report false coverage. ---
93 total = total + 1
94 var ok5: i64 = 1
95 if gl_has_token("call si_class_of(1)" as *u8, 19, "si_class" as *u8, 8) != 0 { ok5 = 0 }
96 if gl_has_token("call xsi_class(1)" as *u8, 17, "si_class" as *u8, 8) != 0 { ok5 = 0 }
97 if gl_has_token("call si_class(1)" as *u8, 16, "si_class" as *u8, 8) != 1 { ok5 = 0 }
98 if gl_has_token("si_class" as *u8, 8, "si_class" as *u8, 8) != 1 { ok5 = 0 }
99 if gl_has_token("anything" as *u8, 8, "" as *u8, 0) != 0 { ok5 = 0 }
100 tw("T5 token match: exact hits, longer/prefixed names and empty needle all refused: " as *u8)
101 if ok5 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
102
103 // --- T6 ***THE WALK'S TWO MODES ARE INDEPENDENT.*** The library folds
104 // edge-building and path-recording into one traversal so callers
105 // need only one; each mode must work with the other switched
106 // off, or a caller pays for work it did not ask for -- or worse,
107 // silently gets nothing. Run over this tree's own directory. ---
108 total = total + 1
109 let g2: *EcoGraph = eg_new(24000, 300000, 4194304, 65536)
110 let path: *u8 = sys_mmap(4096)
111 let fb: *u8 = sys_mmap(GL_FILECAP)
112 let ao: *i64 = sys_mmap(1024 * 8) as *i64
113 let al: *i64 = sys_mmap(1024 * 8) as *i64
114 let st: *i64 = sys_mmap(16)
115 st[0] = 0
116 var rn: i64 = 0
117 let root: *u8 = "runtime/_hdl_build" as *u8
118 while root[rn] != (0 as u8) { path[rn] = root[rn]; rn = rn + 1 }
119 gl_walk(g2, path, rn, fb, ao, al, st, 1, 0 as *u8, 0 as *i64, 0 as *i64, 0)
120 eg_finalize(g2)
121 tw("T6 edges-only walk: files=" as *u8); tn(st[0])
122 tw(" nodes=" as *u8); tn(g2.node_count); tw(" edges=" as *u8); tn(g2.edge_count); tw(": " as *u8)
123 var ok6: i64 = 1
124 if st[0] <= 0 { ok6 = 0 }
125 if g2.node_count <= 0 { ok6 = 0 }
126 if g2.edge_count <= 0 { ok6 = 0 }
127 if ok6 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
128
129 // --- T7 Paths-only mode records a location for every file it counts,
130 // and builds NO edges. If it built edges anyway the caller
131 // would pay a full file read per node for nothing. ---
132 total = total + 1
133 let g3: *EcoGraph = eg_new(24000, 8, 4194304, 65536)
134 let arena: *u8 = sys_mmap(4194304)
135 let poff: *i64 = sys_mmap(24000 * 8) as *i64
136 let used: *i64 = sys_mmap(16)
137 let st3: *i64 = sys_mmap(16)
138 used[0] = 0
139 st3[0] = 0
140 var z: i64 = 0
141 while z < 24000 { poff[z] = 0; z = z + 1 }
142 var rn3: i64 = 0
143 while root[rn3] != (0 as u8) { path[rn3] = root[rn3]; rn3 = rn3 + 1 }
144 gl_walk(g3, path, rn3, 0 as *u8, 0 as *i64, 0 as *i64, st3, 0, arena, poff, used, 4194304)
145 var withpath: i64 = 0
146 var q: i64 = 0
147 while q < g3.node_count { if poff[q] > 0 { withpath = withpath + 1 } q = q + 1 }
148 tw("T7 paths-only walk: files=" as *u8); tn(st3[0])
149 tw(" nodes-with-path=" as *u8); tn(withpath)
150 tw(" edges=" as *u8); tn(g3.edge_count); tw(" (want 0 edges): " as *u8)
151 var ok7: i64 = 1
152 if st3[0] <= 0 { ok7 = 0 }
153 if withpath != g3.node_count { ok7 = 0 }
154 if g3.edge_count != 0 { ok7 = 0 }
155 if ok7 == 1 { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
156
157 // --- T8 ***THE TWO MODES SEE THE SAME TREE.*** Both walks over the
158 // same directory must find the same number of .nx files. If they
159 // disagreed, the two tools built on them would silently be
160 // measuring different populations -- which is exactly the drift
161 // that having two copies of the walk invited. ---
162 total = total + 1
163 tw("T8 edges-mode files=" as *u8); tn(st[0])
164 tw(" vs paths-mode files=" as *u8); tn(st3[0]); tw(": " as *u8)
165 if st[0] == st3[0] { pass = pass + 1; tw("PASS\n" as *u8) } else { tw("FAIL\n" as *u8) }
166
167 tw("GATELIB-GATE passed " as *u8); tn(pass); tw("/" as *u8); tn(total)
168 if pass == total { tw(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
169 tw(" verdict=RED\n" as *u8); sys_exit(1); return 1
170}