nx_bench_companion_tsv_parse_test.nx source
↩ module page · 180 lines · 7701 B
1// nx_bench_companion_tsv_parse_test.nx -- roundtrip smoke for TSV parser.
2//
3// Emit a row -> parse it back -> assert every counter matches. This
4// is the substrate-honest proof that bench reports persist correctly
5// across disk: any analysis that reads saved TSVs gets the same data
6// the substrate originally captured.
7
8import "nx_syscalls.nx"
9import "nx_tier.nx"
10import "nx_bench_companion.nx"
11import "nx_bench_companion_tsv.nx"
12import "nx_bench_companion_tsv_parse.nx"
13
14func main() -> i64 {
15 // 1: verdict enum validity
16 if nx_bctp_v_is_valid(NX_BCTP_OK) != 1 { return 1 }
17 if nx_bctp_v_is_valid(NX_BCTP_BAD_DECIMAL) != 1 { return 2 }
18 if nx_bctp_v_is_valid(NX_BCTP_N) != 0 { return 3 }
19 if nx_bctp_v_is_valid(-1) != 0 { return 4 }
20
21 // 2: build a report with distinct non-trivial values
22 let r: *NxBenchReport = nx_bc_report_new()
23 r.n_actors = 4
24 r.actors_completed = 2
25 r.actors_failed = 1
26 r.actors_running = 1
27 r.actors_waiting = 0
28 r.total_actor_steps = 87
29 r.cumulative_runtime_us = 87000
30 r.n_subscriptions = 5
31 r.mux_pending = 3
32 r.arb_grants_full = 12
33 r.arb_grants_partial = 4
34 r.arb_denials = 2
35 r.arb_preemptions = 1
36 r.broker_grants = 7
37 r.broker_refusals = 1
38 r.broker_deadline_misses = 0
39 r.epoch_count = 3
40 r.captured_at_us = 1234567890
41 r.verdict = NX_BC_V_OK
42
43 // 3: emit -> bytes
44 let buf: *u8 = sys_mmap(512)
45 let label: *u8 = sys_mmap(6)
46 label[0]=0x76 as u8; label[1]=0x31 as u8; label[2]=0x5F as u8
47 label[3]=0x61 as u8; label[4]=0x72 as u8; label[5]=0x6D as u8
48 let n_row: nx_int = nx_bc_emit_tsv_row(buf, 512, r, label, 6)
49 if n_row <= 0 { return 5 }
50
51 // 4: parse it back
52 let r2: *NxBenchReport = nx_bc_report_new()
53 let out_label: *u8 = sys_mmap(32)
54 let out_label_len_buf: *u8 = sys_mmap(8)
55 let out_label_len: *i64 = out_label_len_buf as *i64
56 let consumed: nx_int = nx_bc_parse_tsv_row(buf, n_row,
57 out_label, 32, out_label_len,
58 r2)
59 if consumed < 0 { return 6 }
60 if consumed != n_row { return 7 }
61
62 // 5: label roundtrip
63 if out_label_len[0] != 6 { return 8 }
64 if out_label[0] != (0x76 as u8) { return 9 }
65 if out_label[5] != (0x6D as u8) { return 10 }
66
67 // 6: every counter matches the original
68 if r2.n_actors != r.n_actors { return 11 }
69 if r2.actors_completed != r.actors_completed { return 12 }
70 if r2.actors_failed != r.actors_failed { return 13 }
71 if r2.actors_running != r.actors_running { return 14 }
72 if r2.actors_waiting != r.actors_waiting { return 15 }
73 if r2.total_actor_steps != r.total_actor_steps { return 16 }
74 if r2.cumulative_runtime_us != r.cumulative_runtime_us { return 17 }
75 if r2.n_subscriptions != r.n_subscriptions { return 18 }
76 if r2.mux_pending != r.mux_pending { return 19 }
77 if r2.arb_grants_full != r.arb_grants_full { return 20 }
78 if r2.arb_grants_partial != r.arb_grants_partial { return 21 }
79 if r2.arb_denials != r.arb_denials { return 22 }
80 if r2.arb_preemptions != r.arb_preemptions { return 23 }
81 if r2.broker_grants != r.broker_grants { return 24 }
82 if r2.broker_refusals != r.broker_refusals { return 25 }
83 if r2.broker_deadline_misses != r.broker_deadline_misses { return 26 }
84 if r2.epoch_count != r.epoch_count { return 27 }
85 if r2.captured_at_us != r.captured_at_us { return 28 }
86 if r2.verdict != r.verdict { return 29 }
87
88 // 7: parse with no out_label (just want the report)
89 let r3: *NxBenchReport = nx_bc_report_new()
90 let null_label: *u8 = (0 as i64) as *u8
91 let null_len: *i64 = (0 as i64) as *i64
92 let consumed3: nx_int = nx_bc_parse_tsv_row(buf, n_row,
93 null_label, 0, null_len,
94 r3)
95 if consumed3 != n_row { return 30 }
96 if r3.total_actor_steps != r.total_actor_steps { return 31 }
97
98 // 8: negative counter roundtrip
99 let r_neg: *NxBenchReport = nx_bc_report_new()
100 r_neg.n_actors = -5
101 r_neg.cumulative_runtime_us = -1000
102 let buf2: *u8 = sys_mmap(512)
103 let n_row2: nx_int = nx_bc_emit_tsv_row(buf2, 512, r_neg, label, 6)
104 if n_row2 <= 0 { return 32 }
105
106 let r_neg_back: *NxBenchReport = nx_bc_report_new()
107 let consumed4: nx_int = nx_bc_parse_tsv_row(buf2, n_row2,
108 null_label, 0, null_len,
109 r_neg_back)
110 if consumed4 != n_row2 { return 33 }
111 if r_neg_back.n_actors != -5 { return 34 }
112 if r_neg_back.cumulative_runtime_us != -1000 { return 35 }
113
114 // 9: parse same buffer twice (chained-rows pattern: second
115 // parse starts at the offset the first returned)
116 let buf3: *u8 = sys_mmap(1024)
117 let n_first: nx_int = nx_bc_emit_tsv_row(buf3, 1024, r, label, 6)
118 if n_first <= 0 { return 36 }
119 let n_second: nx_int = nx_bc_emit_tsv_row((buf3 + n_first), 1024 - n_first, r_neg, label, 6)
120 if n_second <= 0 { return 37 }
121 let total: nx_int = n_first + n_second
122
123 let r_a: *NxBenchReport = nx_bc_report_new()
124 let c1: nx_int = nx_bc_parse_tsv_row(buf3, total, null_label, 0, null_len, r_a)
125 if c1 != n_first { return 38 }
126 if r_a.total_actor_steps != 87 { return 39 }
127 let r_b: *NxBenchReport = nx_bc_report_new()
128 let c2: nx_int = nx_bc_parse_tsv_row((buf3 + c1), total - c1, null_label, 0, null_len, r_b)
129 if c2 != n_second { return 40 }
130 if r_b.n_actors != -5 { return 41 }
131
132 // 10: malformed input - no LF terminator
133 let bad_buf: *u8 = sys_mmap(8)
134 bad_buf[0] = 0x6C as u8 // 'l'
135 bad_buf[1] = 0x09 as u8 // \t
136 bad_buf[2] = 0x31 as u8 // '1'
137 let r_bad: *NxBenchReport = nx_bc_report_new()
138 let v_bad: nx_int = nx_bc_parse_tsv_row(bad_buf, 3, null_label, 0, null_len, r_bad)
139 if v_bad >= 0 { return 42 } // must be negative verdict
140
141 // 11: malformed input - non-decimal character in field
142 let bad2: *u8 = sys_mmap(32)
143 bad2[0]=0x61 as u8; bad2[1]=0x09 as u8 // "a\t"
144 bad2[2]=0x58 as u8; bad2[3]=0x09 as u8 // "X\t" (X not decimal)
145 let r_bad2: *NxBenchReport = nx_bc_report_new()
146 if nx_bc_parse_tsv_row(bad2, 4, null_label, 0, null_len, r_bad2) >= 0 { return 43 }
147
148 // 12: null buf rejected
149 let null_buf: *u8 = (0 as i64) as *u8
150 if nx_bc_parse_tsv_row(null_buf, 10, null_label, 0, null_len, r_bad) >= 0 { return 44 }
151
152 // 13: null report rejected
153 let null_r: *NxBenchReport = (0 as i64) as *NxBenchReport
154 if nx_bc_parse_tsv_row(buf, n_row, null_label, 0, null_len, null_r) >= 0 { return 45 }
155
156 // 14: too-short buf rejected
157 if nx_bc_parse_tsv_row(buf, 0, null_label, 0, null_len, r_bad) >= 0 { return 46 }
158 if nx_bc_parse_tsv_row(buf, -1, null_label, 0, null_len, r_bad) >= 0 { return 47 }
159
160 // 15: label overflow rejected
161 let small_label: *u8 = sys_mmap(4)
162 let r_lo: *NxBenchReport = nx_bc_report_new()
163 if nx_bc_parse_tsv_row(buf, n_row, small_label, 3, null_len, r_lo) >= 0 { return 48 }
164
165 // 16: round-tripped report works with nx_bc_diff
166 let r4: *NxBenchReport = nx_bc_report_new()
167 nx_bc_parse_tsv_row(buf, n_row, null_label, 0, null_len, r4)
168 let r_orig_2: *NxBenchReport = nx_bc_report_new()
169 r_orig_2.n_actors = 4
170 r_orig_2.total_actor_steps = 87
171 r_orig_2.cumulative_runtime_us = 87000
172 r_orig_2.verdict = NX_BC_V_OK
173 let diff: *NxBenchReport = nx_bc_report_new()
174 nx_bc_diff(r_orig_2, r4, diff)
175 if diff.n_actors != 0 { return 49 }
176 if diff.total_actor_steps != 0 { return 50 }
177 if diff.cumulative_runtime_us != 0 { return 51 }
178
179 return 0
180}