nx_render_sweep.nx source
↩ module page · 159 lines · 6492 B
1// nx_render_sweep.nx -- RENDER EVERY PUBLISHED /compare BOARD, not a sample of them.
2//
3// Two pages rendered is a SPOT CHECK: it proves the pipeline CAN draw a page, never that it draws the
4// pages we actually publish. This walks the estate's own SSOT (buildroot/knowledge/compare/regen.list)
5// and renders every domain on it through nx_pagerender_lib -- the SAME code the single-page CLI runs,
6// so the two can never disagree about what "rendered" means.
7//
8// THE PARTITION MUST SUM AND THE SUM IS PRINTED. domains_listed = passed + skipped + failed. A sweep
9// that quietly drops a row reports coverage it does not have, and a residual nobody can reconcile is a
10// leak, not a rounding error.
11//
12// The marker check is DELIBERATELY SKIPPED here and that choice is REPORTED per row rather than being
13// silently absent: every board has a different h1, so one marker cannot be right for all of them, and
14// inventing per-domain markers would be asserting page content this organ has not read. What the sweep
15// proves is the RENDER -- text extracted and a non-blank framebuffer painted. The marker assertion
16// stays available for targeted single-page checks, where it is meaningful.
17// license_tier: ORIGINAL
18import "nx_syscalls.nx"
19import "nx_pagerender_lib.nx"
20
21const RS_NL: i64 = 10
22const RS_HASH: i64 = 35
23const RS_CR: i64 = 13
24const RS_PATHCAP: i64 = 512
25const RS_NUMCAP: i64 = 32
26
27func rs_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
28
29func rs_num(v: i64) -> i64 {
30 let t: *u8 = sys_mmap(RS_NUMCAP)
31 var m: i64 = v
32 var k: i64 = 0
33 if m < 0 { rs_puts("-" as *u8); m = 0 - m }
34 if m == 0 { t[0] = 48 as u8; k = 1 }
35 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
36 let o: *u8 = sys_mmap(RS_NUMCAP)
37 var i: i64 = 0
38 while i < k { o[i] = t[k - 1 - i]; i = i + 1 }
39 sys_write(1, o, k)
40 return 0
41}
42
43func rs_cat(d: *u8, at: i64, s: *u8) -> i64 {
44 var p: i64 = at
45 var i: i64 = 0
46 while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 }
47 return p
48}
49
50func rs_pad(s: *u8, width: i64) -> i64 {
51 rs_puts(s)
52 var n: i64 = 0
53 while s[n] != (0 as u8) { n = n + 1 }
54 while n < width { rs_puts(" " as *u8); n = n + 1 }
55 return 0
56}
57
58func main(argc: i64, argv: *i64) -> i64 {
59 var listpath: *u8 = "buildroot/knowledge/compare/regen.list" as *u8
60 if argc > 1 { listpath = argv[1] as *u8 }
61
62 let lp: *i64 = sys_mmap(16) as *i64
63 let buf: *u8 = sys_read_file(listpath, lp)
64 if (buf as i64) == 0 {
65 rs_puts("REFUSED cannot-read domain list: " as *u8)
66 rs_puts(listpath)
67 rs_puts(" -- no sweep is reported for a population we cannot enumerate\n" as *u8)
68 return 4
69 }
70 let n: i64 = lp[0]
71
72 rs_puts("=== NX-RENDER-SWEEP -- every published /compare board through our own paint substrate ===\n" as *u8)
73 rs_puts(" list=" as *u8); rs_puts(listpath); rs_puts("\n" as *u8)
74 rs_puts(" proves: HTML on disk -> nx_html_to_text -> 5x7 bitmap paint -> NON-BLANK RGBA framebuffer\n" as *u8)
75 rs_puts(" marker check SKIPPED per row (every board has a different h1); the RENDER is what is asserted\n\n" as *u8)
76
77 let path: *u8 = sys_mmap(RS_PATHCAP)
78 let dom: *u8 = sys_mmap(RS_PATHCAP)
79
80 var listed: i64 = 0
81 var passed: i64 = 0
82 var skipped: i64 = 0
83 var failed: i64 = 0
84 var sum_html: i64 = 0
85 var sum_text: i64 = 0
86 var min_lit: i64 = 0 - 1
87
88 var p: i64 = 0
89 while p < n {
90 var q: i64 = p
91 var scan: i64 = 1
92 while scan == 1 {
93 if q >= n { scan = 0 }
94 else { if buf[q] == (RS_NL as u8) { scan = 0 } else { q = q + 1 } }
95 }
96 // copy the line, trimming CR so a CRLF list cannot produce a path with an invisible byte in it
97 var d: i64 = 0
98 var i: i64 = p
99 while i < q {
100 if buf[i] != (RS_CR as u8) { if d < RS_PATHCAP - 1 { dom[d] = buf[i]; d = d + 1 } }
101 i = i + 1
102 }
103 dom[d] = 0 as u8
104
105 var usable: i64 = 1
106 if d == 0 { usable = 0 }
107 if d > 0 { if dom[0] == (RS_HASH as u8) { usable = 0 } }
108
109 if usable == 1 {
110 listed = listed + 1
111 var o: i64 = rs_cat(path, 0, "sites/nishifamily/compare/" as *u8)
112 o = rs_cat(path, o, dom)
113 o = rs_cat(path, o, "/index.html" as *u8)
114 path[o] = 0 as u8
115
116 let st: *i64 = pr_stats()
117 let rc: i64 = pr_render(path, "-" as *u8, "-" as *u8, st)
118
119 rs_puts(" " as *u8)
120 rs_pad(dom, 18)
121 rs_pad(pr_code_name(rc), 24)
122 rs_puts("html=" as *u8); rs_num(st[PR_ST_HTML])
123 rs_puts(" text=" as *u8); rs_num(st[PR_ST_TEXT])
124 rs_puts(" lit=" as *u8); rs_num(st[PR_ST_LIT])
125 rs_puts("/" as *u8); rs_num(st[PR_ST_TOTALPX])
126 if st[PR_ST_MARKED] == 0 { rs_puts(" marker=SKIPPED" as *u8) }
127 rs_puts("\n" as *u8)
128
129 if rc == PR_OK {
130 passed = passed + 1
131 sum_html = sum_html + st[PR_ST_HTML]
132 sum_text = sum_text + st[PR_ST_TEXT]
133 if min_lit < 0 { min_lit = st[PR_ST_LIT] }
134 if st[PR_ST_LIT] < min_lit { min_lit = st[PR_ST_LIT] }
135 }
136 // SKIP and FAIL are counted apart on purpose: "the board is not published yet" and "the
137 // renderer could not draw it" take OPPOSITE remedies, and one counter cannot say which.
138 if rc == PR_SKIP_ABSENT { skipped = skipped + 1 }
139 if rc == PR_SKIP_TINY { skipped = skipped + 1 }
140 if rc >= PR_FAIL_TEXT { failed = failed + 1 }
141 }
142 p = q + 1
143 }
144
145 let total: i64 = passed + skipped + failed
146 rs_puts("\ndomains_listed=" as *u8); rs_num(listed)
147 rs_puts(" passed=" as *u8); rs_num(passed)
148 rs_puts(" skipped=" as *u8); rs_num(skipped)
149 rs_puts(" failed=" as *u8); rs_num(failed)
150 rs_puts(" sum=" as *u8); rs_num(total)
151 if total == listed { rs_puts(" partition=RECONCILES" as *u8) } else { rs_puts(" partition=LEAK" as *u8) }
152 rs_puts("\nrendered_html_bytes=" as *u8); rs_num(sum_html)
153 rs_puts(" extracted_text_bytes=" as *u8); rs_num(sum_text)
154 rs_puts(" worst_lit_subpixels=" as *u8); rs_num(min_lit)
155 rs_puts("\n\nWORST-CASE IS PRINTED, NOT THE AVERAGE: a mean hides the one board that nearly went blank.\n" as *u8)
156 if total != listed { return 1 }
157 if failed > 0 { return 1 }
158 return 0
159}