code wiki / (root) / nx_actor_role_image_grader_test.nx

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}