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}