code wiki / (root) / nx_printer_health_test.nx

nx_printer_health_test.nx source

↩ module page · 106 lines · 6024 B

1// nx_printer_health_test.nx -- gate for the honest-status / anti-silent-failure model (R1). 2// 3// Builds real IPP responses with the codec and asserts the health verdict for each, with unique exit 4// codes per invariant. This is the proof that we surface the truth a Brother UI hides. 5// 6// 1x idle + accepting + reasons='none' -> CAN_PRINT 7// 2x STOPPED + media-jam(bare) + marker-supply-low-warning -> BLOCKED, worst=ERROR, 2 reasons 8// 3x idle + marker-supply-low-warning + toner-low-report -> DEGRADED, worst=WARNING 9// 4x idle but printer-is-accepting-jobs=false -> BLOCKED 10// 7x per-reason severity classifier (suffix rules + bare/stopped vs bare/idle) 11// 8x malformed reasons (value-length overrun) -> UNKNOWN (never a false "ready") 12// 13// expect_exit: 0 14// license_tier: ORIGINAL 15 16import "nx_syscalls.nx" 17import "nx_ipp_codec.nx" 18import "nx_printer_health.nx" 19 20func t_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 21 22func main() -> i64 { 23 let sc: *i64 = sys_mmap(64) as *i64 24 let o_state: *i64 = sys_mmap(16) as *i64 25 let o_sev: *i64 = sys_mmap(16) as *i64 26 let o_cnt: *i64 = sys_mmap(16) as *i64 27 let o_acc: *i64 = sys_mmap(16) as *i64 28 29 let n_pst: *u8 = "printer-state" 30 let n_acc: *u8 = "printer-is-accepting-jobs" 31 let n_psr: *u8 = "printer-state-reasons" 32 33 // ===== KAT 1: idle, accepting, no reasons -> CAN_PRINT ===== 34 let a: *u8 = sys_mmap(2048) 35 var pa: i64 = nx_ipp_begin(a, 1, 1, NX_IPP_STATUS_OK, 1) 36 pa = nx_ipp_group(a, pa, NX_IPP_GRP_PRINTER) 37 pa = nx_ipp_attr_int(a, pa, NX_IPP_VT_ENUM, n_pst, nx_ipp_strlen(n_pst), NX_IPP_PSTATE_IDLE) 38 pa = nx_ipp_attr_bool(a, pa, n_acc, nx_ipp_strlen(n_acc), 1) 39 pa = nx_ipp_attr(a, pa, NX_IPP_VT_KEYWORD, n_psr, nx_ipp_strlen(n_psr), "none", 4) 40 pa = nx_ipp_end(a, pa) 41 if nx_printer_diagnose(a, pa, sc, o_state, o_sev, o_cnt, o_acc) != NX_PR_CAN_PRINT { return 1 } 42 if o_state[0] != NX_IPP_PSTATE_IDLE { return 2 } 43 if o_sev[0] != NX_SEV_NONE { return 3 } 44 if o_acc[0] != 1 { return 4 } 45 46 // ===== KAT 2: STOPPED + bare media-jam + marker-supply-low-warning -> BLOCKED, worst=ERROR ===== 47 let b: *u8 = sys_mmap(2048) 48 var pb: i64 = nx_ipp_begin(b, 1, 1, NX_IPP_STATUS_OK, 1) 49 pb = nx_ipp_group(b, pb, NX_IPP_GRP_PRINTER) 50 pb = nx_ipp_attr_int(b, pb, NX_IPP_VT_ENUM, n_pst, nx_ipp_strlen(n_pst), NX_IPP_PSTATE_STOPPED) 51 pb = nx_ipp_attr_bool(b, pb, n_acc, nx_ipp_strlen(n_acc), 1) 52 pb = nx_ipp_attr(b, pb, NX_IPP_VT_KEYWORD, n_psr, nx_ipp_strlen(n_psr), "media-jam", 9) 53 pb = nx_ipp_attr_add(b, pb, NX_IPP_VT_KEYWORD, "marker-supply-low-warning", 25) 54 pb = nx_ipp_end(b, pb) 55 if nx_printer_diagnose(b, pb, sc, o_state, o_sev, o_cnt, o_acc) != NX_PR_BLOCKED { return 20 } 56 if o_state[0] != NX_IPP_PSTATE_STOPPED { return 21 } 57 if o_sev[0] != NX_SEV_ERROR { return 22 } // bare media-jam while stopped = ERROR, beats the warning 58 if o_cnt[0] != 2 { return 23 } 59 60 // ===== KAT 3: idle + marker-supply-low-warning + toner-low-report -> DEGRADED, worst=WARNING ===== 61 let c: *u8 = sys_mmap(2048) 62 var pc: i64 = nx_ipp_begin(c, 1, 1, NX_IPP_STATUS_OK, 1) 63 pc = nx_ipp_group(c, pc, NX_IPP_GRP_PRINTER) 64 pc = nx_ipp_attr_int(c, pc, NX_IPP_VT_ENUM, n_pst, nx_ipp_strlen(n_pst), NX_IPP_PSTATE_IDLE) 65 pc = nx_ipp_attr_bool(c, pc, n_acc, nx_ipp_strlen(n_acc), 1) 66 pc = nx_ipp_attr(c, pc, NX_IPP_VT_KEYWORD, n_psr, nx_ipp_strlen(n_psr), "marker-supply-low-warning", 25) 67 pc = nx_ipp_attr_add(c, pc, NX_IPP_VT_KEYWORD, "toner-low-report", 16) 68 pc = nx_ipp_end(c, pc) 69 if nx_printer_diagnose(c, pc, sc, o_state, o_sev, o_cnt, o_acc) != NX_PR_DEGRADED { return 30 } 70 if o_sev[0] != NX_SEV_WARNING { return 31 } 71 if o_cnt[0] != 2 { return 32 } 72 73 // ===== KAT 4: idle but NOT accepting jobs -> BLOCKED ===== 74 let d: *u8 = sys_mmap(2048) 75 var pd: i64 = nx_ipp_begin(d, 1, 1, NX_IPP_STATUS_OK, 1) 76 pd = nx_ipp_group(d, pd, NX_IPP_GRP_PRINTER) 77 pd = nx_ipp_attr_int(d, pd, NX_IPP_VT_ENUM, n_pst, nx_ipp_strlen(n_pst), NX_IPP_PSTATE_IDLE) 78 pd = nx_ipp_attr_bool(d, pd, n_acc, nx_ipp_strlen(n_acc), 0) 79 pd = nx_ipp_attr(d, pd, NX_IPP_VT_KEYWORD, n_psr, nx_ipp_strlen(n_psr), "none", 4) 80 pd = nx_ipp_end(d, pd) 81 if nx_printer_diagnose(d, pd, sc, o_state, o_sev, o_cnt, o_acc) != NX_PR_BLOCKED { return 40 } 82 if o_acc[0] != 0 { return 41 } 83 84 // ===== KAT 7: per-reason severity classifier (operate directly on string literals) ===== 85 if nx_ph_reason_severity("media-empty-error", 0, 17, NX_IPP_PSTATE_IDLE) != NX_SEV_ERROR { return 70 } 86 if nx_ph_reason_severity("cover-open-warning", 0, 18, NX_IPP_PSTATE_IDLE) != NX_SEV_WARNING { return 71 } 87 if nx_ph_reason_severity("toner-low-report", 0, 16, NX_IPP_PSTATE_IDLE) != NX_SEV_REPORT { return 72 } 88 if nx_ph_reason_severity("none", 0, 4, NX_IPP_PSTATE_STOPPED) != NX_SEV_NONE { return 73 } 89 if nx_ph_reason_severity("media-empty", 0, 11, NX_IPP_PSTATE_STOPPED) != NX_SEV_ERROR { return 74 } 90 if nx_ph_reason_severity("media-empty", 0, 11, NX_IPP_PSTATE_IDLE) != NX_SEV_WARNING { return 75 } 91 92 // ===== KAT 8: malformed reasons (value-length overrun) -> UNKNOWN ===== 93 let e: *u8 = sys_mmap(2048) 94 var pe: i64 = nx_ipp_begin(e, 1, 1, NX_IPP_STATUS_OK, 1) 95 pe = nx_ipp_group(e, pe, NX_IPP_GRP_PRINTER) 96 pe = nx_ipp_attr_int(e, pe, NX_IPP_VT_ENUM, n_pst, nx_ipp_strlen(n_pst), NX_IPP_PSTATE_IDLE) 97 e[pe] = NX_IPP_VT_KEYWORD as u8 98 pe = pe + 1 99 pe = nx_ipp_put_u16(e, pe, 21) 100 pe = nx_ipp_memcpy(e, pe, n_psr, 21) 101 pe = nx_ipp_put_u16(e, pe, 0x7fff) // lying value-length, no value bytes 102 if nx_printer_diagnose(e, pe, sc, o_state, o_sev, o_cnt, o_acc) != NX_PR_UNKNOWN { return 80 } 103 104 t_puts("nx_printer_health: 6/6 KAT groups PASS (can_print=ready/degraded/blocked + accepting + severity-suffix + malformed->UNKNOWN)\n") 105 return 0 106}