code wiki / _hdl_build / nx_siteedit_history_gate.nx

nx_siteedit_history_gate.nx source

↩ module page · 90 lines · 5904 B

1// nx_siteedit_history_gate.nx -- proves the revision-history enumeration (nx_siteedit_history) against a REAL 2// fixture directory in /tmp: only `<basename>.v<digits>` snapshots are listed (noise .new/.vXY/other excluded), 3// newest-first ordering, dir-split + version-path building. license_tier: ORIGINAL 4import "nx_siteedit_history.nx" 5 6func gh_w(s: *u8) -> i64 { sys_write(1, s, sh_slen(s)); return 0 } 7func gh_wn(v: i64) -> i64 { let b: *u8 = sys_mmap(32); let o: i64 = sh_catn(b, 0, v); b[o] = 10 as u8; sys_write(1, b, o + 1); return 0 } 8func gh_eq(name: *u8, got: i64, want: i64) -> i64 { 9 if got == want { gh_w(" ok " as *u8); gh_w(name); gh_w("\n" as *u8); return 1 } 10 gh_w(" FAIL " as *u8); gh_w(name); gh_w(" got=" as *u8); gh_wn(got); return 0 11} 12func gh_writefile(path: *u8, content: *u8) -> i64 { 13 let fd: i64 = sys_openat_wr(path, 0x1a4) 14 if fd < 0 { return 0 - 1 } 15 sys_write(fd, content, sh_slen(content)) 16 sys_close(fd) 17 return 0 18} 19// strcmp for the dir-split assertion 20func gh_streq(a: *u8, b: *u8) -> i64 { 21 var i: i64 = 0 22 while a[i] != (0 as u8) { if (a[i] as i64) != (b[i] as i64) { return 0 } i = i + 1 } 23 if b[i] != (0 as u8) { return 0 } 24 return 1 25} 26 27func main(argc: i64, argv: *i64) -> i64 { 28 gh_w("== nx_siteedit_history_gate ==\n" as *u8) 29 var pass: i64 = 0 30 var total: i64 = 0 31 32 // ---- fixture dir + snapshot files (+ noise). Idempotent: fixed names, O_TRUNC overwrites on re-run. ---- 33 sys_mkdir("/tmp/sh_gate" as *u8, 0x1ed) 34 gh_writefile("/tmp/sh_gate/shgatecfg.site" as *u8, "current-config" as *u8) 35 gh_writefile("/tmp/sh_gate/shgatecfg.site.v1000" as *u8, "snapshot-1000" as *u8) 36 gh_writefile("/tmp/sh_gate/shgatecfg.site.v3000" as *u8, "snapshot-3000" as *u8) // out of order -> tests sort 37 gh_writefile("/tmp/sh_gate/shgatecfg.site.v2000" as *u8, "snapshot-2000" as *u8) 38 gh_writefile("/tmp/sh_gate/shgatecfg.site.new" as *u8, "staging-noise" as *u8) // must be EXCLUDED 39 gh_writefile("/tmp/sh_gate/shgatecfg.site.vXY" as *u8, "nondigit-noise" as *u8) // must be EXCLUDED 40 gh_writefile("/tmp/sh_gate/other.file" as *u8, "unrelated-noise" as *u8) // must be EXCLUDED 41 42 // ---- sh_match: accept <base>.v<digits>, reject every noise shape ---- 43 gh_w("- sh_match\n" as *u8) 44 total = total + 1; pass = pass + gh_eq("M1 base.v1000 -> 1000" as *u8, sh_match("shgatecfg.site.v1000" as *u8, "shgatecfg.site" as *u8, 14), 1000) 45 total = total + 1; pass = pass + gh_eq("M2 base.new -> 0" as *u8, sh_match("shgatecfg.site.new" as *u8, "shgatecfg.site" as *u8, 14), 0) 46 total = total + 1; pass = pass + gh_eq("M3 bare base -> 0" as *u8, sh_match("shgatecfg.site" as *u8, "shgatecfg.site" as *u8, 14), 0) 47 total = total + 1; pass = pass + gh_eq("M4 base.vXY (nondigit) -> 0" as *u8, sh_match("shgatecfg.site.vXY" as *u8, "shgatecfg.site" as *u8, 14), 0) 48 total = total + 1; pass = pass + gh_eq("M5 base.v (empty) -> 0" as *u8, sh_match("shgatecfg.site.v" as *u8, "shgatecfg.site" as *u8, 14), 0) 49 total = total + 1; pass = pass + gh_eq("M6 base.v12x (trailing nondigit) -> 0" as *u8, sh_match("shgatecfg.site.v12x" as *u8, "shgatecfg.site" as *u8, 14), 0) 50 total = total + 1; pass = pass + gh_eq("M7 other prefix -> 0" as *u8, sh_match("other.file" as *u8, "shgatecfg.site" as *u8, 14), 0) 51 52 // ---- sh_list: exactly the 3 real snapshots, noise excluded ---- 53 gh_w("- sh_list + sh_sort_desc (fixture FS)\n" as *u8) 54 let eps: *i64 = sys_mmap(8 * 64) 55 let cnt: i64 = sh_list("/tmp/sh_gate/shgatecfg.site" as *u8, eps, 64) 56 total = total + 1; pass = pass + gh_eq("L1 exactly 3 snapshots (noise excluded)" as *u8, cnt, 3) 57 sh_sort_desc(eps, cnt) 58 total = total + 1; pass = pass + gh_eq("L2 newest first [0]=3000" as *u8, eps[0], 3000) 59 total = total + 1; pass = pass + gh_eq("L3 [1]=2000" as *u8, eps[1], 2000) 60 total = total + 1; pass = pass + gh_eq("L4 oldest last [2]=1000" as *u8, eps[2], 1000) 61 62 // ---- sh_dir_of ---- 63 gh_w("- sh_dir_of + sh_version_path\n" as *u8) 64 let dbuf: *u8 = sys_mmap(256) 65 let boff: i64 = sh_dir_of("/a/b/c.site" as *u8, dbuf) 66 total = total + 1; pass = pass + gh_eq("D1 basename offset" as *u8, boff, 5) 67 total = total + 1; pass = pass + gh_eq("D2 dir == /a/b" as *u8, gh_streq(dbuf, "/a/b" as *u8), 1) 68 // basename slice 69 let bn: *u8 = (("/a/b/c.site" as i64) + boff) as *u8 70 total = total + 1; pass = pass + gh_eq("D3 basename == c.site" as *u8, gh_streq(bn, "c.site" as *u8), 1) 71 72 // ---- sh_version_path ---- 73 let vp: *u8 = sys_mmap(256) 74 let vpl: i64 = sh_version_path("/x/y.site" as *u8, 42, vp) 75 total = total + 1; pass = pass + gh_eq("V1 path len" as *u8, vpl, 13) 76 total = total + 1; pass = pass + gh_eq("V2 path == /x/y.site.v42" as *u8, gh_streq(vp, "/x/y.site.v42" as *u8), 1) 77 78 // ---- sh_qs_epoch: parse &v=<epoch> from a request path (must ignore a 'v' inside the s= token) ---- 79 gh_w("- sh_qs_epoch\n" as *u8) 80 total = total + 1; pass = pass + gh_eq("Q1 s=tok&v=42 -> 42" as *u8, sh_qs_epoch("/site/restore?s=aVbvcv-_9&v=42" as *u8, sh_slen("/site/restore?s=aVbvcv-_9&v=42" as *u8)), 42) 81 total = total + 1; pass = pass + gh_eq("Q2 no &v= -> 0" as *u8, sh_qs_epoch("/site/restore?s=aVbvcv-_9" as *u8, sh_slen("/site/restore?s=aVbvcv-_9" as *u8)), 0) 82 total = total + 1; pass = pass + gh_eq("Q3 &v= empty -> 0" as *u8, sh_qs_epoch("/site/restore?s=t&v=" as *u8, sh_slen("/site/restore?s=t&v=" as *u8)), 0) 83 total = total + 1; pass = pass + gh_eq("Q4 &v=1700000000 big epoch" as *u8, sh_qs_epoch("/site/x?s=q&v=1700000000&z=1" as *u8, sh_slen("/site/x?s=q&v=1700000000&z=1" as *u8)), 1700000000) 84 85 gh_w("== result " as *u8); gh_wn(pass) 86 gh_w(" total=" as *u8); gh_wn(total) 87 if pass == total { gh_w("SITEEDIT_HISTORY_GATE PASS\n" as *u8); return 0 } 88 gh_w("SITEEDIT_HISTORY_GATE FAIL\n" as *u8) 89 return 1 90}