nx_actor_role_image_grader_test.nx source
↩ module page · 122 lines · 5129 B
1// nx_actor_role_image_grader_test.nx -- smoke for nx_actor_role_image_grader.
2
3import "nx_syscalls.nx"
4import "nx_tier.nx"
5import "nx_actor.nx"
6import "nx_message.nx"
7import "nx_actor_role_image_grader.nx"
8
9func main() -> i64 {
10 let now: nx_size = 1000000
11
12 // 1: enum validity
13 if nx_im_phase_is_valid(NX_IM_PHASE_INIT) != 1 { return 1 }
14 if nx_im_phase_is_valid(NX_IM_PHASE_DONE) != 1 { return 2 }
15 if nx_im_phase_is_valid(-1) != 0 { return 3 }
16 if nx_im_phase_is_valid(4) != 0 { return 4 }
17 if NX_IM_PHASE_N != 4 { return 5 }
18
19 if nx_im_v_is_valid(NX_IM_V_STEPPED) != 1 { return 6 }
20 if nx_im_v_is_valid(NX_IM_V_NULL) != 1 { return 7 }
21
22 // 2: build a 4-byte non-PNG/JPEG buffer. Format detect will return
23 // UNKNOWN_FORMAT; grader will set error_code = UNKNOWN_FORMAT.
24 // This is honest: we're testing the actor INVOKES the grader,
25 // not that the grader handles real PNGs (the grader has its own
26 // real-PNG smokes).
27 let buf: *u8 = sys_mmap(8)
28 buf[0] = 0xDE as u8
29 buf[1] = 0xAD as u8
30 buf[2] = 0xBE as u8
31 buf[3] = 0xEF as u8
32
33 // 3: construct ctx
34 let ctx: *NxImageGraderCtx = nx_im_actor_new(buf, 4)
35 if (ctx as i64) == 0 { return 8 }
36 if ctx.input_size != 4 { return 9 }
37 if ctx.current_phase != NX_IM_PHASE_INIT { return 10 }
38 if ctx.last_error_code != -1 { return 11 }
39
40 // 4: invalid construction
41 if nx_im_actor_new(buf, 0) != (0 as *NxImageGraderCtx) { return 12 }
42 if nx_im_actor_new(buf, -1) != (0 as *NxImageGraderCtx) { return 13 }
43 let null_buf: *u8 = (0 as i64) as *u8
44 if nx_im_actor_new(null_buf, 4) != (0 as *NxImageGraderCtx) { return 14 }
45
46 // 5: supporting scheduler + bus
47 let sched: *NxActorScheduler = nx_ac_sched_new(4, 1000000, 4, now)
48 nx_ac_spawn(sched, 5001, 2, 60, 0, now)
49 let bus: *NxMessageBus = nx_ms_bus_new(4, 4, 4)
50 nx_ms_register(bus, 5001)
51 nx_ms_register(bus, 5002)
52 nx_ms_subscribe(bus, 5002, NX_MS_KIND_IMAGE_TILE)
53
54 // 6: drive phases INIT -> GRADE -> EMIT -> DONE
55 if nx_im_actor_step(ctx, sched, bus, 5001, now + 100) != NX_IM_V_STEPPED { return 15 }
56 if ctx.current_phase != NX_IM_PHASE_GRADE { return 16 }
57
58 if nx_im_actor_step(ctx, sched, bus, 5001, now + 200) != NX_IM_V_STEPPED { return 17 }
59 if ctx.current_phase != NX_IM_PHASE_EMIT { return 18 }
60 // After GRADE, grader returned a report. 4-byte non-PNG -> too-short -> ERR_TOO_SHORT.
61 // Actually input_size = 4 and grader requires >= 8 so error is TOO_SHORT.
62 if nx_im_actor_error_code(ctx) != NX_IGV2_ERR_TOO_SHORT { return 19 }
63 if nx_im_actor_format(ctx) != NX_IGV2_FORMAT_UNKNOWN { return 20 }
64
65 // 7: EMIT pushes message + completes
66 if nx_im_actor_step(ctx, sched, bus, 5001, now + 300) != NX_IM_V_COMPLETED { return 21 }
67 if ctx.current_phase != NX_IM_PHASE_DONE { return 22 }
68 if nx_im_actor_is_done(ctx) != 1 { return 23 }
69
70 // 8: listener received IMAGE_TILE with error code payload
71 if nx_ms_pending(bus, 5002) != 1 { return 24 }
72 let m: *NxMessage = nx_ms_receive(bus, 5002)
73 if m.kind != NX_MS_KIND_IMAGE_TILE { return 25 }
74 if m.sender_actor_id != 5001 { return 26 }
75 if (m.payload_handle as nx_int) != NX_IGV2_ERR_TOO_SHORT { return 27 }
76
77 // 9: scheduler marks COMPLETED
78 let a: *NxActor = nx_ac_find(sched, 5001)
79 if a.state != NX_AC_STATE_COMPLETED { return 28 }
80
81 // 10: try with 16-byte non-PNG -> error_code = UNKNOWN_FORMAT, not TOO_SHORT
82 let buf2: *u8 = sys_mmap(16)
83 var i: nx_int = 0
84 while i < 16 {
85 buf2[i] = ((i + 1) as u8)
86 i = i + 1
87 }
88 let ctx2: *NxImageGraderCtx = nx_im_actor_new(buf2, 16)
89 nx_im_actor_step(ctx2, sched, bus, 5001, now) // INIT
90 nx_im_actor_step(ctx2, sched, bus, 5001, now) // GRADE
91 if nx_im_actor_error_code(ctx2) != NX_IGV2_ERR_UNKNOWN_FORMAT { return 29 }
92 if nx_im_actor_format(ctx2) != NX_IGV2_FORMAT_UNKNOWN { return 30 }
93
94 // 11: try with PNG signature (137 80 78 71) + 12 garbage bytes -> format=PNG
95 // but decoder fails -> error_code = ERR_DECODER
96 let buf3: *u8 = sys_mmap(16)
97 buf3[0] = 137 as u8
98 buf3[1] = 80 as u8
99 buf3[2] = 78 as u8
100 buf3[3] = 71 as u8
101 var j: nx_int = 4
102 while j < 16 {
103 buf3[j] = 0 as u8
104 j = j + 1
105 }
106 let ctx3: *NxImageGraderCtx = nx_im_actor_new(buf3, 16)
107 nx_im_actor_step(ctx3, sched, bus, 5001, now)
108 nx_im_actor_step(ctx3, sched, bus, 5001, now)
109 if nx_im_actor_format(ctx3) != NX_IGV2_FORMAT_PNG { return 31 }
110 // decoder fails on garbage PNG body -> error_code set to ERR_DECODER
111 if nx_im_actor_error_code(ctx3) != NX_IGV2_ERR_DECODER { return 32 }
112
113 // 12: null guards
114 let null_ctx: *NxImageGraderCtx = (0 as i64) as *NxImageGraderCtx
115 if nx_im_actor_step(null_ctx, sched, bus, 5001, now) != NX_IM_V_NULL { return 33 }
116 if nx_im_actor_phase(null_ctx) != NX_IM_PHASE_DONE { return 34 }
117 if nx_im_actor_error_code(null_ctx) != -1 { return 35 }
118 if nx_im_actor_format(null_ctx) != NX_IGV2_FORMAT_UNKNOWN { return 36 }
119 if nx_im_actor_is_done(null_ctx) != 0 { return 37 }
120
121 return 0
122}