code wiki / _hdl_build / nx_aw_smoke.nx
nx_aw_smoke.nx source
↩ module page · 101 lines · 5351 B
1// nx_aw_smoke.nx -- FRONT-END smoke gate: the "verify" stage of the local->dev->live pipeline. Hits a
2// RUNNING andelinwest front-end (default 127.0.0.1:8088) over REAL HTTP via the sovereign nx_http_client
3// and asserts that each capability renders its expected live output -- this is the front-end test as a
4// repeatable GATE (not a manual curl), and the safety check every promotion must pass before pushing to
5// the next stage. Reusable against dev OR live by repointing the address. Appends "FRONTEND-SMOKE ...
6// verdict=PASS" to knowledge/status/cms_frontend.log ONLY on a full pass. Exit 0 iff all routes pass.
7// license_tier: ORIGINAL
8import "nx_http_client.nx"
9import "nx_syscalls.nx"
10const K_MAGIC_8088: i64 = 8088
11const K_MAGIC_262144: i64 = 262144
12const K_MAGIC_262143: i64 = 262143
13
14func sm_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
15func sm_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=48+(m%10);m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 }
16func sm_len(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
17func sm_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var k: i64=0; while s[k]!=(0 as u8){dst[o]=s[k];o=o+1;k=k+1} return o }
18func sm_catnum(dst: *u8, off: i64, v: i64) -> i64 {
19 var o: i64=off; let t: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; var k: i64=0
20 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}
21 var i: i64=0; while i<k {dst[o]=t[k-1-i]; o=o+1; i=i+1} return o
22}
23
24func sm_find(buf: *u8, n: i64, pat: *u8, plen: i64) -> i64 {
25 if plen==0 { return 0-1 }
26 var i: i64=0
27 while i+plen<=n {
28 var j: i64=0; var ok: i64=1
29 while j<plen { if (buf[i+j] as i64)!=(pat[j] as i64){ok=0;j=plen} else {j=j+1} }
30 if ok==1 { return i }
31 i=i+1
32 }
33 return 0-1
34}
35
36// GET path from 127.0.0.1:8088 and return 1 iff the response contains `expected`.
37func sm_get_has(path: *u8, expected: *u8) -> i64 {
38 let addr: *u8 = sys_mmap(16)
39 nx_http_client_sockaddr_ipv4(addr, 127, 0, 0, 1, K_MAGIC_8088)
40 let buf: *u8 = sys_mmap(K_MAGIC_262144)
41 let v: *i64 = sys_mmap(8) as *i64
42 let got: i64 = nx_http_client_get(addr, path, sm_len(path), "127.0.0.1" as *u8, 9, buf, K_MAGIC_262143, v)
43 if got <= 0 { return 0 }
44 if sm_find(buf, got, expected, sm_len(expected)) >= 0 { return 1 }
45 return 0
46}
47
48func sm_row(id: i64, ok: i64, route: *u8, expect: *u8) -> i64 {
49 sm_w("SMOKEROW " as *u8); sm_num(id); sm_w(" " as *u8)
50 if ok==1 { sm_w("PASS " as *u8) } else { sm_w("FAIL " as *u8) }
51 sm_w(route); sm_w(" expect~" as *u8); sm_w(expect); sm_w("\n" as *u8)
52 return ok
53}
54
55func main() -> i64 {
56 var pass: i64 = 0
57 var rows: i64 = 0
58 var ok: i64 = 0
59
60 // render-from-data (home, English)
61 ok = sm_get_has("/" as *u8, "Andelin West, PLLC" as *u8)
62 rows=rows+1; pass=pass+sm_row(0, ok, "GET /" as *u8, "Andelin West, PLLC" as *u8)
63
64 // i18n live (French)
65 ok = sm_get_has("/?lang=fr" as *u8, "Andelin West, SARL" as *u8)
66 rows=rows+1; pass=pass+sm_row(1, ok, "GET /?lang=fr" as *u8, "Andelin West, SARL" as *u8)
67
68 // comment moderation live -- spam withheld
69 ok = sm_get_has("/moderate?text=buy+casino+loan+http://x" as *u8, "SPAM - withheld" as *u8)
70 rows=rows+1; pass=pass+sm_row(2, ok, "GET /moderate (spam)" as *u8, "SPAM - withheld" as *u8)
71
72 // comment moderation live -- clean queued
73 ok = sm_get_has("/moderate?text=hello+great+article" as *u8, "PENDING - queued" as *u8)
74 rows=rows+1; pass=pass+sm_row(3, ok, "GET /moderate (clean)" as *u8, "PENDING - queued" as *u8)
75
76 // ecommerce live -- integer-exact money ($10.00 x2 @0% = $20.00)
77 ok = sm_get_has("/price?cents=1000&qty=2&tax=0" as *u8, "total with tax: $20.00" as *u8)
78 rows=rows+1; pass=pass+sm_row(4, ok, "GET /price" as *u8, "total with tax: $20.00" as *u8)
79
80 // a/b live -- deterministic arms (alice->A, bob->B per the proven hash)
81 ok = sm_get_has("/ab?visitor=alice" as *u8, "A — Get a free consultation" as *u8)
82 rows=rows+1; pass=pass+sm_row(5, ok, "GET /ab?visitor=alice" as *u8, "arm A" as *u8)
83 ok = sm_get_has("/ab?visitor=bob" as *u8, "B — Talk to an attorney" as *u8)
84 rows=rows+1; pass=pass+sm_row(6, ok, "GET /ab?visitor=bob" as *u8, "arm B" as *u8)
85
86 sm_w("CMS-FRONTEND-SMOKE rows=" as *u8); sm_num(rows); sm_w(" pass=" as *u8); sm_num(pass); sm_w("\n" as *u8)
87
88 if pass == rows {
89 let line: *u8 = sys_mmap(256)
90 var off: i64 = sm_cat(line, 0, "FRONTEND-SMOKE target=127.0.0.1:8088 routes=" as *u8)
91 off = sm_catnum(line, off, rows)
92 off = sm_cat(line, off, " pass=" as *u8); off = sm_catnum(line, off, pass)
93 off = sm_cat(line, off, " verdict=PASS\n" as *u8)
94 let gf: i64 = sys_openat_append("knowledge/status/cms_frontend.log" as *u8, 0x1a4)
95 if gf >= 0 { sys_write(gf, line, off); sys_close(gf) }
96 sm_w("CMS-FRONTEND-SMOKE verdict=PASS -- all capabilities served live (front-end verified)\n" as *u8)
97 sys_exit(0); return 0
98 }
99 sm_w("CMS-FRONTEND-SMOKE verdict=FAIL -- a route did not render (server down or regression)\n" as *u8)
100 sys_exit(1); return 1
101}