nx_jam_response_test.nx source
↩ module page · 63 lines · 3023 B
1// nx_jam_response_test.nx -- KAT: the FULL jam->action loop on a simulated
2// telemetry sequence: detect (jam_step) + respond (jr_step) -> CONTINUE/ALERT/PAUSE.
3// Proves a developing jam auto-pauses, and a transient does NOT. expect_exit: 0.
4
5import "nx_syscalls.nx"
6import "nx_jam_detect.nx"
7import "nx_jam_response.nx"
8
9func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
10func wn(v: i64) -> i64 {
11 let b: *u8 = sys_mmap(28); var m: i64 = v
12 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) }
13 let t: *u8 = sys_mmap(28); var k: i64 = 0
14 if m == 0 { t[0] = 48 as u8; k = 1 }
15 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
16 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
17 sys_write(1, b, k); return 0
18}
19func chk(cond: i64, pass: *i64, fail: *i64, label: *u8) -> i64 {
20 if cond == 1 { pass[0] = pass[0] + 1; w(" ok " as *u8); w(label); w("\n" as *u8) }
21 else { fail[0] = fail[0] + 1; w(" XX " as *u8); w(label); w("\n" as *u8) }
22 return 0
23}
24
25// one full window: commanded e + measured feed -> detect -> respond
26func window(eq: i64, fq: i64, consec: *i64, pass: *i64, fail: *i64) -> i64 {
27 let TH: i64 = NX_JAM_Q14
28 let v: i64 = jam_step(eq, fq, TH, 70)
29 return jr_step(v, consec, 2, 4) // alert at 2 consecutive, pause at 4
30}
31
32func main() -> i64 {
33 let pass: *i64 = (sys_mmap(8)) as *i64
34 let fail: *i64 = (sys_mmap(8)) as *i64
35 pass[0] = 0
36 fail[0] = 0
37 let Q: i64 = NX_JAM_Q14
38 let consec: *i64 = (sys_mmap(8)) as *i64
39 consec[0] = 0
40 w("=== nx_jam_response KAT (detect + auto-pause loop) ===\n" as *u8)
41
42 // healthy printing -> CONTINUE
43 chk(window(10 * Q, 10 * Q, consec, pass, fail) == JR_CONTINUE, pass, fail, "healthy -> CONTINUE" as *u8)
44 // jam develops: window1 grind -> CONTINUE (debounce)
45 chk(window(10 * Q, 2 * Q, consec, pass, fail) == JR_CONTINUE, pass, fail, "1 jam window -> CONTINUE (debounced)" as *u8)
46 // window2 -> ALERT
47 chk(window(10 * Q, 1 * Q, consec, pass, fail) == JR_ALERT, pass, fail, "2 consecutive -> ALERT" as *u8)
48 // window3 -> still CONTINUE (below pause)
49 chk(window(10 * Q, 0, consec, pass, fail) == JR_ALERT, pass, fail, "3 consecutive -> still ALERT (escalating)" as *u8)
50 // window4 -> PAUSE (auto-pause the print)
51 chk(window(10 * Q, 0, consec, pass, fail) == JR_PAUSE, pass, fail, "4 consecutive -> AUTO-PAUSE" as *u8)
52
53 // transient must NOT pause: reset, one jam, then healthy
54 consec[0] = 0
55 window(10 * Q, 1 * Q, consec, pass, fail) // 1 jam
56 let a: i64 = window(10 * Q, 10 * Q, consec, pass, fail) // healthy clears it
57 chk(a == JR_CONTINUE, pass, fail, "transient cleared by a healthy window" as *u8)
58 chk(consec[0] == 0, pass, fail, "streak reset (no false pause)" as *u8)
59
60 w("=== VERDICT pass=" as *u8); wn(pass[0]); w(" fail=" as *u8); wn(fail[0]); w(" ===\n" as *u8)
61 if fail[0] == 0 { return 0 }
62 return 1
63}