nx_printer_conform_test.nx source
↩ module page · 92 lines · 5418 B
1// nx_printer_conform_test.nx -- gate for the IPP conformance / capability-gap profiler (nx_printer_conform).
2// Builds real Get-Printer-Attributes responses with the codec and asserts the gap bitmask, with unique exit
3// codes per invariant:
4// 1-4 Brother-like (ipp 1.0 / no pdf / duplex-supported but default one-sided / mono) -> all 4 gaps
5// 5-6 truncated response -> UNKNOWN (-1), never confident gaps (no_silent_failure)
6// 7-8 modern HP-like (ipp 2.0 / pdf / duplex + default two-sided / color) -> ZERO gaps (negative control)
7// 9-10 modern but duplex-default-one-sided -> ONLY the duplex-waste gap (isolates that detector)
8// expect_exit: 0 ; license_tier: ORIGINAL ; genealogy_id: project-printer-management-ipp-sclass-2026-06-20
9
10import "nx_syscalls.nx"
11import "nx_ipp_codec.nx"
12import "nx_printer_conform.nx"
13
14func 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 }
15
16// Brother DCP-L2540DW profile: only IPP 1.0, no PDF, duplex-capable but defaults one-sided, monochrome.
17func build_brother(buf: *u8) -> i64 {
18 var p: i64 = nx_ipp_begin(buf, 1, 1, NX_IPP_STATUS_OK, 1)
19 p = nx_ipp_group(buf, p, NX_IPP_GRP_PRINTER)
20 p = nx_ipp_attr_int(buf, p, NX_IPP_VT_ENUM, "printer-state" as *u8, 13, NX_IPP_PSTATE_IDLE)
21 p = nx_ipp_attr(buf, p, NX_IPP_VT_KEYWORD, "ipp-versions-supported" as *u8, 22, "1.0" as *u8, 3)
22 p = nx_ipp_attr(buf, p, NX_IPP_VT_MIMETYPE, "document-format-supported" as *u8, 25, "application/octet-stream" as *u8, 24)
23 p = nx_ipp_attr_add(buf, p, NX_IPP_VT_MIMETYPE, "image/urf" as *u8, 9)
24 p = nx_ipp_attr(buf, p, NX_IPP_VT_KEYWORD, "sides-supported" as *u8, 15, "one-sided" as *u8, 9)
25 p = nx_ipp_attr_add(buf, p, NX_IPP_VT_KEYWORD, "two-sided-long-edge" as *u8, 19)
26 p = nx_ipp_attr(buf, p, NX_IPP_VT_KEYWORD, "sides-default" as *u8, 13, "one-sided" as *u8, 9)
27 p = nx_ipp_attr_bool(buf, p, "color-supported" as *u8, 15, 0)
28 return nx_ipp_end(buf, p)
29}
30
31// Modern HP-like profile: IPP 2.0, supports PDF, duplex + DEFAULT two-sided, color. Zero gaps.
32func build_hp(buf: *u8) -> i64 {
33 var p: i64 = nx_ipp_begin(buf, 1, 1, NX_IPP_STATUS_OK, 1)
34 p = nx_ipp_group(buf, p, NX_IPP_GRP_PRINTER)
35 p = nx_ipp_attr_int(buf, p, NX_IPP_VT_ENUM, "printer-state" as *u8, 13, NX_IPP_PSTATE_IDLE)
36 p = nx_ipp_attr(buf, p, NX_IPP_VT_KEYWORD, "ipp-versions-supported" as *u8, 22, "1.1" as *u8, 3)
37 p = nx_ipp_attr_add(buf, p, NX_IPP_VT_KEYWORD, "2.0" as *u8, 3)
38 p = nx_ipp_attr(buf, p, NX_IPP_VT_MIMETYPE, "document-format-supported" as *u8, 25, "application/pdf" as *u8, 15)
39 p = nx_ipp_attr_add(buf, p, NX_IPP_VT_MIMETYPE, "image/urf" as *u8, 9)
40 p = nx_ipp_attr(buf, p, NX_IPP_VT_KEYWORD, "sides-supported" as *u8, 15, "one-sided" as *u8, 9)
41 p = nx_ipp_attr_add(buf, p, NX_IPP_VT_KEYWORD, "two-sided-long-edge" as *u8, 19)
42 p = nx_ipp_attr(buf, p, NX_IPP_VT_KEYWORD, "sides-default" as *u8, 13, "two-sided-long-edge" as *u8, 19)
43 p = nx_ipp_attr_bool(buf, p, "color-supported" as *u8, 15, 1)
44 return nx_ipp_end(buf, p)
45}
46
47// Modern but misconfigured: IPP 2.0, PDF, color, duplex-capable but sides-default one-sided -> ONLY waste gap.
48func build_dupmis(buf: *u8) -> i64 {
49 var p: i64 = nx_ipp_begin(buf, 1, 1, NX_IPP_STATUS_OK, 1)
50 p = nx_ipp_group(buf, p, NX_IPP_GRP_PRINTER)
51 p = nx_ipp_attr_int(buf, p, NX_IPP_VT_ENUM, "printer-state" as *u8, 13, NX_IPP_PSTATE_IDLE)
52 p = nx_ipp_attr(buf, p, NX_IPP_VT_KEYWORD, "ipp-versions-supported" as *u8, 22, "2.0" as *u8, 3)
53 p = nx_ipp_attr(buf, p, NX_IPP_VT_MIMETYPE, "document-format-supported" as *u8, 25, "application/pdf" as *u8, 15)
54 p = nx_ipp_attr(buf, p, NX_IPP_VT_KEYWORD, "sides-supported" as *u8, 15, "one-sided" as *u8, 9)
55 p = nx_ipp_attr_add(buf, p, NX_IPP_VT_KEYWORD, "two-sided-long-edge" as *u8, 19)
56 p = nx_ipp_attr(buf, p, NX_IPP_VT_KEYWORD, "sides-default" as *u8, 13, "one-sided" as *u8, 9)
57 p = nx_ipp_attr_bool(buf, p, "color-supported" as *u8, 15, 1)
58 return nx_ipp_end(buf, p)
59}
60
61func main() -> i64 {
62 let sc3: *i64 = sys_mmap(64) as *i64
63 let buf: *u8 = sys_mmap(2048)
64
65 // ===== KAT 1: Brother -> all four gaps =====
66 let bn: i64 = build_brother(buf)
67 let bg: i64 = nx_conf_gaps(buf, bn, sc3)
68 if bg != 15 { return 1 }
69 if nx_conf_gap_count(bg) != 4 { return 2 }
70 if (bg & NX_CONF_GAP_DUPLEX_WASTE) == 0 { return 3 }
71 if (bg & NX_CONF_GAP_NO_PDF) == 0 { return 4 }
72
73 // ===== KAT 2: truncated -> UNKNOWN (never confident gaps) =====
74 let mg: i64 = nx_conf_gaps(buf, 20, sc3)
75 if mg != (0 - 1) { return 5 }
76 if nx_conf_gap_count(mg) != (0 - 1) { return 6 }
77
78 // ===== KAT 3: modern HP -> ZERO gaps (negative control) =====
79 let hn: i64 = build_hp(buf)
80 let hg: i64 = nx_conf_gaps(buf, hn, sc3)
81 if hg != 0 { return 7 }
82 if (hg & NX_CONF_GAP_DUPLEX_WASTE) != 0 { return 8 } // duplex-capable but default two-sided -> NO waste
83
84 // ===== KAT 4: modern but duplex-default-one-sided -> ONLY the waste gap =====
85 let dn: i64 = build_dupmis(buf)
86 let dg: i64 = nx_conf_gaps(buf, dn, sc3)
87 if dg != NX_CONF_GAP_DUPLEX_WASTE { return 9 }
88 if nx_conf_gap_count(dg) != 1 { return 10 }
89
90 t_puts("nx_printer_conform: PASS (Brother profile -> 4 actionable gaps [old-IPP/no-PDF/duplex-default-waste/mono]; modern -> 0; duplex-misconfig isolates the waste gap; truncated -> UNKNOWN)\n")
91 return 0
92}