code wiki / _hdl_build / nx_site_search_gate.nx

nx_site_search_gate.nx source

↩ module page · 105 lines · 7222 B

1// nx_site_search_gate.nx -- MEASURED gate for the live /search endpoint handler (nx_site_search). Self-contained: 2// builds a small PERSISTED onsite index + manifest (the 4 andelinwest practice areas) in-process, then drives the 3// pure handler sr_handle with crafted GET /search?q=... requests and asserts the rendered results page: 4// T1 q=divorce -> 200, links /practice/family-law ("Family Law"), 1 result 5// T2 q=will -> Estate Planning (/practice/estate-planning) 6// T3 q=zzznomatch-> 0 results (graceful) 7// T4 q=divorce+injury -> 2 results (family-law + personal-injury), multi-term union 8// T5 the search form echoes the query back (sticky input) 9// GREEN iff 5/5. Appends knowledge/status/site_search_gate.log. license_tier: ORIGINAL 10import "nx_site_search.nx" 11 12func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 13func g_num(v: i64) -> i64 { 14 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 15 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 16 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 17 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 18} 19func g_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 20func g_wn(fd: i64, v: i64) -> i64 { 21 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m } 22 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 23 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 24 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(fd, bb, k); return 0 25} 26func g_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 27func g_contains(hay: *u8, n: i64, ndl: *u8) -> i64 { 28 let nl: i64 = g_slen(ndl); if nl == 0 { return 0 } 29 var i: i64 = 0 30 while i + nl <= n { var j: i64 = 0; var hit: i64 = 1; while j < nl { if hay[i + j] != ndl[j] { hit = 0; j = nl } else { j = j + 1 } } if hit == 1 { return 1 } i = i + 1 } 31 return 0 32} 33func g_mkreq(out: *u8, s: *u8) -> i64 { var o: i64 = 0; while s[o] != (0 as u8) { out[o] = s[o]; o = o + 1 } return o } 34 35func main() -> i64 { 36 g_puts("=== SITE SEARCH GATE (live /search endpoint: query -> branded results over the real index) ===\n" as *u8) 37 let idxp: *u8 = "knowledge/index/srtest.idx" as *u8 38 let manp: *u8 = "knowledge/index/srtest.manifest" as *u8 39 40 // build the 4-practice index (docid = line) + the aligned manifest 41 let t0: *u8 = "divorce custody support family law" as *u8 42 let t1: *u8 = "will testament probate trust estate" as *u8 43 let t2: *u8 = "contract formation dispute business" as *u8 44 let t3: *u8 = "injury accident insurance personal" as *u8 45 let idx: *NxInvIndex = nx_inv_new_sized(2048) 46 nx_inv_index_row(idx, t0, g_slen(t0), 0); nx_inv_index_row(idx, t1, g_slen(t1), 1); nx_inv_index_row(idx, t2, g_slen(t2), 2); nx_inv_index_row(idx, t3, g_slen(t3), 3) 47 idx.n_rows = 4 48 nx_inv_finalize_offsets(idx) 49 nx_inv_emit_row(idx, t0, g_slen(t0), 0); nx_inv_emit_row(idx, t1, g_slen(t1), 1); nx_inv_emit_row(idx, t2, g_slen(t2), 2); nx_inv_emit_row(idx, t3, g_slen(t3), 3) 50 if nx_inv_save(idx, idxp) != NX_INV_OK { g_puts("GATE-FAIL: index save\n" as *u8); sys_exit(1); return 1 } 51 let mfd: i64 = sys_openat_wr(manp, 0x1a4) 52 if mfd < 0 { g_puts("GATE-FAIL: manifest open\n" as *u8); sys_exit(1); return 1 } 53 g_w(mfd, "/practice/family-law\tFamily Law\t" as *u8); g_w(mfd, t0); g_w(mfd, "\n" as *u8) 54 g_w(mfd, "/practice/estate-planning\tEstate Planning\t" as *u8); g_w(mfd, t1); g_w(mfd, "\n" as *u8) 55 g_w(mfd, "/practice/business-law\tBusiness Law\t" as *u8); g_w(mfd, t2); g_w(mfd, "\n" as *u8) 56 g_w(mfd, "/practice/personal-injury\tPersonal Injury\t" as *u8); g_w(mfd, t3); g_w(mfd, "\n" as *u8) 57 sys_close(mfd) 58 59 let base: *u8 = "https://andelinwest.com" as *u8 60 let firm: *u8 = "Andelin West" as *u8 61 let req: *u8 = sys_mmap(4096) 62 let out: *u8 = sys_mmap(262144) 63 var pass: i64 = 0 64 65 let n1: i64 = g_mkreq(req, "GET /search?q=divorce HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 66 let o1: i64 = sr_handle(req, n1, idxp, manp, base, firm, out) 67 var c1: i64 = 0 68 if g_contains(out, o1, "200 OK" as *u8) == 1 { if g_contains(out, o1, "/practice/family-law" as *u8) == 1 { if g_contains(out, o1, "1 result" as *u8) == 1 { c1 = 1 } } } 69 pass = pass + c1; g_puts(" T1 q=divorce -> family-law, 1 result: "); if c1 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 70 71 let n2: i64 = g_mkreq(req, "GET /search?q=will HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 72 let o2: i64 = sr_handle(req, n2, idxp, manp, base, firm, out) 73 var c2: i64 = 0 74 if g_contains(out, o2, "/practice/estate-planning" as *u8) == 1 { if g_contains(out, o2, "Estate Planning" as *u8) == 1 { c2 = 1 } } 75 pass = pass + c2; g_puts(" T2 q=will -> estate-planning: "); if c2 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 76 77 let n3: i64 = g_mkreq(req, "GET /search?q=zzznomatch HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 78 let o3: i64 = sr_handle(req, n3, idxp, manp, base, firm, out) 79 var c3: i64 = 0 80 if g_contains(out, o3, "0 results" as *u8) == 1 { c3 = 1 } 81 pass = pass + c3; g_puts(" T3 q=zzznomatch -> 0 results (graceful): "); if c3 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 82 83 let n4: i64 = g_mkreq(req, "GET /search?q=divorce+injury HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 84 let o4: i64 = sr_handle(req, n4, idxp, manp, base, firm, out) 85 var c4: i64 = 0 86 if g_contains(out, o4, "2 results" as *u8) == 1 { if g_contains(out, o4, "family-law" as *u8) == 1 { if g_contains(out, o4, "personal-injury" as *u8) == 1 { c4 = 1 } } } 87 pass = pass + c4; g_puts(" T4 q=divorce+injury -> 2 results (multi-term): "); if c4 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 88 89 let n5: i64 = g_mkreq(req, "GET /search?q=divorce HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 90 let o5: i64 = sr_handle(req, n5, idxp, manp, base, firm, out) 91 var c5: i64 = 0 92 if g_contains(out, o5, "value=\"divorce\"" as *u8) == 1 { c5 = 1 } 93 pass = pass + c5; g_puts(" T5 search form echoes the query (sticky): "); if c5 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 94 95 g_puts("----\nSITE-SEARCH rows=5 pass="); g_num(pass); g_puts("\n" as *u8) 96 let lg: i64 = sys_openat_append("knowledge/status/site_search_gate.log" as *u8, 0x1a4) 97 if lg >= 0 { 98 g_w(lg, "SITE-SEARCH q_divorce="); g_wn(lg, c1); g_w(lg, " q_will="); g_wn(lg, c2); g_w(lg, " no_match="); g_wn(lg, c3) 99 g_w(lg, " multi_term="); g_wn(lg, c4); g_w(lg, " sticky="); g_wn(lg, c5); g_w(lg, " rows=5 pass="); g_wn(lg, pass) 100 if pass == 5 { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } 101 sys_close(lg) 102 } 103 if pass == 5 { g_puts("SITE-SEARCH GREEN (live /search: query->branded results over the real onsite index -- measured)\n" as *u8); sys_exit(0); return 0 } 104 g_puts("SITE-SEARCH RED\n" as *u8); sys_exit(1); return 1 105}