nx_fsops_gate.nx source
↩ module page · 170 lines · 10018 B
1// nx_fsops_gate.nx -- gates the consolidated fs tool on synthetic fixtures, asserting RETURN VALUES:
2// exact byte-count read, MARKED truncation, secret DENY (compiled default), DATA-DRIVEN deny toggled
3// ON->OFF via fs_read_deny.conf (both directions = discriminating), absent-path grace, dir listing count.
4// Runner must clean /tmp/fsgate first. The conf is written in CWD (prod lookup path) and REMOVED after.
5// Exit 0 only on all-PASS. license_tier: ORIGINAL expect_exit: 0
6import "nx_fsops_lib.nx"
7import "nx_fio.nx" // fio_unlink -- conf lifecycle cleanup
8import "nx_seg_store.nx" // ss_writefile -- fixture author
9
10const GATE_CHECKS: i64 = 23
11const DIR_MODE: i64 = 0x1ed // 0755
12const FIX_BYTES: i64 = 9 // len("hello-fs\n")
13const SMALL_CAP: i64 = 4 // forces the truncation path
14const FIX_ENTRIES: i64 = 3 // files authored into the fixture dir
15const FG_RB_CAP: i64 = 256 // read-back buffer for write/edit content assertions
16
17// read path into a NUL-terminated buffer and compare to expect (1 = byte-identical)
18func fg_readback_eq(path: *u8, expect: *u8) -> i64 {
19 let b: *u8 = sys_mmap(FG_RB_CAP)
20 let n: i64 = vw_read(path, b, FG_RB_CAP - 1)
21 if n < 0 { return 0 }
22 b[n] = 0 as u8
23 return fsx_seq(b, expect)
24}
25
26func fg_check(name: *u8, ok: i64, pass: *i64) -> i64 {
27 fsx_puts("T " as *u8); fsx_puts(name); fsx_puts(" -> " as *u8)
28 if ok == 1 { fsx_puts("PASS\n" as *u8); pass[0] = pass[0] + 1 } else { fsx_puts("FAIL\n" as *u8) }
29 return 0
30}
31func fg_write(path: *u8, body: *u8) -> i64 {
32 var n: i64 = 0
33 while body[n] != (0 as u8) { n = n + 1 }
34 return ss_writefile(path, body, n)
35}
36// write via the tool-under-test with the length computed (no magic byte counts in checks)
37func fg_put(path: *u8, body: *u8) -> i64 { return fsx_write(path, body, vw_slen(body)) }
38
39func main(argc: i64, argv: *i64) -> i64 {
40 let pass: *i64 = sys_mmap(16) as *i64
41 pass[0] = 0
42 sys_mkdir("/tmp/fsgate" as *u8, DIR_MODE)
43 // IDEMPOTENCY (rule 10), fixed 2026-07-31. /tmp/fsgate PERSISTS between runs and the LATER tests
44 // author w.txt / blockw.txt / d.txt / e.txt / lines.txt into it, so ls-entry-count saw 8 entries
45 // instead of FIX_ENTRIES=3. This gate therefore PASSED EXACTLY ONCE, on a clean machine, and has
46 // FAILED EVERY RUN SINCE -- a verdict that depends on whether the gate has run before is not
47 // measuring the code under test. Reset every path this gate ever authors, not just the 3 fixtures.
48 fio_unlink("/tmp/fsgate/normal.txt" as *u8)
49 fio_unlink("/tmp/fsgate/mysecret_key.bin" as *u8)
50 fio_unlink("/tmp/fsgate/blockme.txt" as *u8)
51 fio_unlink("/tmp/fsgate/w.txt" as *u8)
52 fio_unlink("/tmp/fsgate/blockw.txt" as *u8)
53 fio_unlink("/tmp/fsgate/d.txt" as *u8)
54 fio_unlink("/tmp/fsgate/e.txt" as *u8)
55 fio_unlink("/tmp/fsgate/lines.txt" as *u8)
56 fg_write("/tmp/fsgate/normal.txt" as *u8, "hello-fs\n" as *u8)
57 fg_write("/tmp/fsgate/mysecret_key.bin" as *u8, "SHOULD-NEVER-PRINT\n" as *u8)
58 fg_write("/tmp/fsgate/blockme.txt" as *u8, "hello-fs\n" as *u8)
59
60 // T1 exact read
61 fg_check("read-exact-bytes" as *u8, (fsx_read("/tmp/fsgate/normal.txt" as *u8, 0) == FIX_BYTES) as i64, pass)
62 // T2 bounded read hits the cap (truncation path, MARKED)
63 fg_check("read-truncation-marked" as *u8, (fsx_read("/tmp/fsgate/normal.txt" as *u8, SMALL_CAP) == SMALL_CAP) as i64, pass)
64 // T3 compiled deny needle ("key") refuses secret material
65 fg_check("deny-default-key" as *u8, (fsx_read("/tmp/fsgate/mysecret_key.bin" as *u8, 0) == 0 - (2 as i64)) as i64, pass)
66 // T4 DATA-DRIVEN deny ON: conf needle blocks an otherwise-fine file
67 fg_write("fs_read_deny.conf" as *u8, "blockme\n" as *u8)
68 fg_check("deny-conf-on" as *u8, (fsx_read("/tmp/fsgate/blockme.txt" as *u8, 0) == 0 - (2 as i64)) as i64, pass)
69 // T5 DATA-DRIVEN deny OFF: removing the conf restores the read (proves the conf DRIVES the policy)
70 fio_unlink("fs_read_deny.conf" as *u8)
71 fg_check("deny-conf-off" as *u8, (fsx_read("/tmp/fsgate/blockme.txt" as *u8, 0) == FIX_BYTES) as i64, pass)
72 // T6 absent path is graceful
73 fg_check("read-absent-graceful" as *u8, (fsx_read("/tmp/fsgate/nope.txt" as *u8, 0) == (0 - 1)) as i64, pass)
74 // T7 ls counts the 3 fixture entries (. and .. skipped)
75 fg_check("ls-entry-count" as *u8, (fsx_ls("/tmp/fsgate" as *u8) == FIX_ENTRIES) as i64, pass)
76
77 // ==== write/edit half (nx_fs_write) ==== (lengths computed with vw_slen -- no magic byte counts)
78 // T8 atomic write + byte-identical read-back
79 var wr: i64 = fg_put("/tmp/fsgate/w.txt" as *u8, "alpha beta gamma\n" as *u8)
80 var ok8: i64 = 0
81 if wr == vw_slen("alpha beta gamma\n" as *u8) { ok8 = fg_readback_eq("/tmp/fsgate/w.txt" as *u8, "alpha beta gamma\n" as *u8) }
82 fg_check("write-roundtrip" as *u8, ok8, pass)
83 // T9 overwrite lands whole (atomic replace, not append/partial)
84 wr = fg_put("/tmp/fsgate/w.txt" as *u8, "second\n" as *u8)
85 var ok9: i64 = 0
86 if wr == vw_slen("second\n" as *u8) { ok9 = fg_readback_eq("/tmp/fsgate/w.txt" as *u8, "second\n" as *u8) }
87 fg_check("write-overwrite-whole" as *u8, ok9, pass)
88 // T10 write DENIED on secret-needle path AND nothing created (negative control)
89 var ok10: i64 = 0
90 if fg_put("/tmp/fsgate/deploy.pem" as *u8, "x" as *u8) == 0 - (2 as i64) {
91 let probe: *u8 = sys_mmap(FG_RB_CAP)
92 if vw_read("/tmp/fsgate/deploy.pem" as *u8, probe, FG_RB_CAP - 1) < 0 { ok10 = 1 }
93 }
94 fg_check("write-deny-secret-nocreate" as *u8, ok10, pass)
95 // T11 write DENIED in the OS device namespace (rule 26 never-brick, seam-enforced)
96 fg_check("write-deny-devns" as *u8, (fg_put("/dev/null" as *u8, "x" as *u8) == 0 - (2 as i64)) as i64, pass)
97 // T12 data-driven WRITE deny: conf ON blocks, then conf OFF restores (both directions discriminate)
98 fg_write("fs_write_deny.conf" as *u8, "blockw\n" as *u8)
99 var ok12: i64 = 0
100 if fg_put("/tmp/fsgate/blockw.txt" as *u8, "x\n" as *u8) == 0 - (2 as i64) {
101 fio_unlink("fs_write_deny.conf" as *u8)
102 if fg_put("/tmp/fsgate/blockw.txt" as *u8, "x\n" as *u8) == vw_slen("x\n" as *u8) { ok12 = 1 }
103 }
104 fg_check("write-deny-conf-both-ways" as *u8, ok12, pass)
105 // T13 edit UNIQUE match replaces and preserves the rest
106 fg_put("/tmp/fsgate/e.txt" as *u8, "alpha beta gamma\n" as *u8)
107 var ok13: i64 = 0
108 if fsx_edit("/tmp/fsgate/e.txt" as *u8, "beta" as *u8, "BETA" as *u8, 0) == vw_slen("alpha BETA gamma\n" as *u8) {
109 ok13 = fg_readback_eq("/tmp/fsgate/e.txt" as *u8, "alpha BETA gamma\n" as *u8)
110 }
111 fg_check("edit-unique-replaces" as *u8, ok13, pass)
112 // T14 edit NOMATCH leaves the file untouched
113 var ok14: i64 = 0
114 if fsx_edit("/tmp/fsgate/e.txt" as *u8, "zeta" as *u8, "x" as *u8, 0) == 0 - FSX_RC_NOMATCH {
115 ok14 = fg_readback_eq("/tmp/fsgate/e.txt" as *u8, "alpha BETA gamma\n" as *u8)
116 }
117 fg_check("edit-nomatch-unchanged" as *u8, ok14, pass)
118 // T15 edit AMBIGUOUS without `all` refuses and leaves the file untouched
119 fg_put("/tmp/fsgate/d.txt" as *u8, "dup dup\n" as *u8)
120 var ok15: i64 = 0
121 if fsx_edit("/tmp/fsgate/d.txt" as *u8, "dup" as *u8, "x" as *u8, 0) == 0 - FSX_RC_AMBIG {
122 ok15 = fg_readback_eq("/tmp/fsgate/d.txt" as *u8, "dup dup\n" as *u8)
123 }
124 fg_check("edit-ambiguous-unchanged" as *u8, ok15, pass)
125 // T16 edit `all` replaces every occurrence
126 var ok16: i64 = 0
127 if fsx_edit("/tmp/fsgate/d.txt" as *u8, "dup" as *u8, "x" as *u8, 1) == vw_slen("x x\n" as *u8) {
128 ok16 = fg_readback_eq("/tmp/fsgate/d.txt" as *u8, "x x\n" as *u8)
129 }
130 fg_check("edit-all-replaces-every" as *u8, ok16, pass)
131
132 // T17 lines returns the EXACT requested window (line-addressed read: grep's file:LINE now composes)
133 fg_write("/tmp/fsgate/lines.txt" as *u8, "L1\nL2\nL3\nL4\nL5\n" as *u8)
134 var ok17: i64 = 0
135 if fsx_read_lines("/tmp/fsgate/lines.txt" as *u8, 2, 2) == vw_slen("L2\nL3\n" as *u8) { ok17 = 1 }
136 fg_check("lines-exact-window" as *u8, ok17, pass)
137 // T18 lines BEYOND EOF fails LOUD (0 bytes + explicit banner) -- never a silent empty window
138 var ok18: i64 = 0
139 if fsx_read_lines("/tmp/fsgate/lines.txt" as *u8, 99, 5) == 0 { ok18 = 1 }
140 fg_check("lines-beyond-eof-loud" as *u8, ok18, pass)
141 // T19 lines INHERITS the secret deny-list -- a NEW read path must never become a key-theft primitive
142 var ok19: i64 = 0
143 if fsx_read_lines("/tmp/fsgate/mysecret_key.bin" as *u8, 1, 5) == 0 - (2 as i64) { ok19 = 1 }
144 fg_check("lines-inherits-secret-deny" as *u8, ok19, pass)
145
146 // T20-T23 COMPARE-AND-SWAP, and T20 is the whole point (seq1422): the CAS
147 // guard shipped REFUSING every correct expectation because only its refusal
148 // path had ever been driven. ★LAW: A GUARD'S SUCCESS PATH MUST BE TESTED,
149 // NOT JUST ITS REFUSAL PATH -- an always-refusing guard is not safety, it is
150 // a bypass generator (it drove authors to raw scp/ssh, the unguarded write
151 // path that destroyed shipped work in seq1439/seq1392).
152 var ok20: i64 = 0
153 if fsx_cas_ok(5986, "expect=5986" as *u8) == 1 { ok20 = 1 }
154 fg_check("cas-correct-expect-ALLOWS" as *u8, ok20, pass)
155 var ok21: i64 = 0
156 if fsx_cas_ok(5986, "expect=42" as *u8) == 0 { ok21 = 1 }
157 fg_check("cas-stale-expect-REFUSES" as *u8, ok21, pass)
158 var ok22: i64 = 0
159 if fsx_cas_ok(5986, "expect=any" as *u8) == 1 { ok22 = 1 }
160 fg_check("cas-any-is-the-declared-escape-hatch" as *u8, ok22, pass)
161 // a token carrying no digits must REFUSE, never silently read as 0 == size
162 var ok23: i64 = 0
163 if fsx_cas_ok(0, "expect=" as *u8) == 0 { ok23 = 1 }
164 fg_check("cas-empty-value-REFUSES-not-zero-match" as *u8, ok23, pass)
165
166 fsx_puts("FSOPS-GATE pass=" as *u8); fsx_putn(pass[0]); fsx_puts("/" as *u8); fsx_putn(GATE_CHECKS); fsx_puts(" verdict=" as *u8)
167 if pass[0] == GATE_CHECKS { fsx_puts("GREEN\n" as *u8); return 0 }
168 fsx_puts("RED\n" as *u8)
169 return 1
170}