code wiki / (root) / nx_actor_test.nx

nx_actor_test.nx source

↩ module page · 176 lines · 7910 B

1// nx_actor_test.nx -- smoke for nx_actor. 2 3import "nx_syscalls.nx" 4import "nx_actor.nx" 5 6func main() -> i64 { 7 let now: nx_size = 1000000 8 9 // 1: enum validity 10 if nx_ac_state_is_valid(NX_AC_STATE_READY) != 1 { return 1 } 11 if nx_ac_state_is_valid(NX_AC_STATE_PAUSED) != 1 { return 2 } 12 if nx_ac_state_is_valid(-1) != 0 { return 3 } 13 if nx_ac_state_is_valid(6) != 0 { return 4 } 14 if NX_AC_STATE_N != 6 { return 5 } 15 16 if nx_ac_wait_is_valid(NX_AC_WAIT_NONE) != 1 { return 6 } 17 if nx_ac_wait_is_valid(NX_AC_WAIT_OPERATOR) != 1 { return 7 } 18 if nx_ac_wait_is_valid(-1) != 0 { return 8 } 19 if nx_ac_wait_is_valid(6) != 0 { return 9 } 20 21 if nx_ac_v_is_valid(NX_AC_V_STEPPED) != 1 { return 10 } 22 if nx_ac_v_is_valid(NX_AC_V_FAILED) != 1 { return 11 } 23 24 // 2: runnable + terminal predicates 25 if nx_ac_state_is_runnable(NX_AC_STATE_READY) != 1 { return 12 } 26 if nx_ac_state_is_runnable(NX_AC_STATE_RUNNING) != 1 { return 13 } 27 if nx_ac_state_is_runnable(NX_AC_STATE_WAITING) != 0 { return 14 } 28 if nx_ac_state_is_runnable(NX_AC_STATE_COMPLETED) != 0 { return 15 } 29 30 if nx_ac_state_is_terminal(NX_AC_STATE_COMPLETED) != 1 { return 16 } 31 if nx_ac_state_is_terminal(NX_AC_STATE_FAILED) != 1 { return 17 } 32 if nx_ac_state_is_terminal(NX_AC_STATE_READY) != 0 { return 18 } 33 34 // 3: scheduler construction 35 let s: *NxActorScheduler = nx_ac_sched_new(16, 1000000, 4, now) 36 if s.capacity != 16 { return 19 } 37 if s.n_actors != 0 { return 20 } 38 if s.quantum_per_actor != 4 { return 21 } 39 40 if nx_ac_sched_new(0, 1000000, 4, now) != (0 as *NxActorScheduler) { return 22 } 41 if nx_ac_sched_new(16, 1000000, 0, now) != (0 as *NxActorScheduler) { return 23 } 42 43 // 4: spawn actors 44 if nx_ac_spawn(s, 1001, 1, 90, 0, now) != NX_AC_V_STEPPED { return 24 } // LLM 45 if nx_ac_spawn(s, 1002, 2, 50, 0, now) != NX_AC_V_STEPPED { return 25 } // IMAGE 46 if nx_ac_spawn(s, 1003, 3, 30, 0, now) != NX_AC_V_STEPPED { return 26 } // VIDEO 47 if nx_ac_actor_count(s) != 3 { return 27 } 48 49 if nx_ac_spawn(s, 0, 1, 50, 0, now) != NX_AC_V_INVALID { return 28 } 50 51 // 5: find 52 let a1: *NxActor = nx_ac_find(s, 1001) 53 if a1.actor_id != 1001 { return 29 } 54 if a1.role != 1 { return 30 } 55 if a1.priority != 90 { return 31 } 56 if a1.state != NX_AC_STATE_READY { return 32 } 57 58 if (nx_ac_find(s, 9999) as i64) != 0 { return 33 } 59 60 // 6: pick_next -- highest priority wins (LLM = 90) 61 let pick1: *NxActor = nx_ac_pick_next(s) 62 if pick1.actor_id != 1001 { return 34 } 63 64 // 7: step LLM actor, accumulate runtime, increments quanta 65 if nx_ac_step(s, 1001, 5000, now + 100) != NX_AC_V_STEPPED { return 35 } 66 if a1.current_step != 1 { return 36 } 67 if a1.cumulative_runtime_us != 5000 { return 37 } 68 if a1.quanta_used_this_epoch != 1 { return 38 } 69 if a1.state != NX_AC_STATE_RUNNING { return 39 } 70 71 // 8: step until quantum exhausted (quantum_per_actor=4) 72 nx_ac_step(s, 1001, 5000, now + 200) 73 nx_ac_step(s, 1001, 5000, now + 300) 74 let v_exhaust: nx_int = nx_ac_step(s, 1001, 5000, now + 400) 75 if v_exhaust != NX_AC_V_YIELDED { return 40 } 76 if a1.state != NX_AC_STATE_READY { return 41 } 77 if a1.quanta_used_this_epoch != 4 { return 42 } 78 79 // 9: after quantum exhaustion, pick_next prefers IMAGE because LLM has used 4 quanta 80 // (score = 90*1000 - 4 = 89996 vs IMAGE 50*1000 - 0 = 50000). 81 // LLM still wins on priority alone; verify pick logic: 82 let pick2: *NxActor = nx_ac_pick_next(s) 83 if pick2.actor_id != 1001 { return 43 } // LLM still wins by priority 84 85 // 10: set_waiting takes LLM out of contention; now IMAGE wins 86 if nx_ac_set_waiting(s, 1001, NX_AC_WAIT_MESSAGE) != NX_AC_V_BLOCKED { return 44 } 87 let a1w: *NxActor = nx_ac_find(s, 1001) 88 if a1w.state != NX_AC_STATE_WAITING { return 45 } 89 if a1w.wait_reason != NX_AC_WAIT_MESSAGE { return 46 } 90 let pick3: *NxActor = nx_ac_pick_next(s) 91 if pick3.actor_id != 1002 { return 47 } 92 93 // 11: invalid set_waiting / wake 94 if nx_ac_set_waiting(s, 9999, NX_AC_WAIT_MESSAGE) != NX_AC_V_INVALID { return 48 } 95 if nx_ac_set_waiting(s, 1001, 99) != NX_AC_V_INVALID { return 49 } 96 if nx_ac_wake(s, 9999) != NX_AC_V_INVALID { return 50 } 97 if nx_ac_wake(s, 1002) != NX_AC_V_INVALID { return 51 } // not waiting 98 99 // 12: wake LLM back to READY 100 if nx_ac_wake(s, 1001) != NX_AC_V_STEPPED { return 52 } 101 if a1w.state != NX_AC_STATE_READY { return 53 } 102 if a1w.wait_reason != NX_AC_WAIT_NONE { return 54 } 103 104 // 13: epoch_tick resets quanta 105 if nx_ac_epoch_tick(s, now + 1000) != NX_AC_V_STEPPED { return 55 } 106 if a1.quanta_used_this_epoch != 0 { return 56 } 107 if s.epoch_count != 1 { return 57 } 108 109 // 14: pause + resume 110 if nx_ac_pause(s, 1002) != NX_AC_V_BLOCKED { return 58 } 111 let a2p: *NxActor = nx_ac_find(s, 1002) 112 if a2p.state != NX_AC_STATE_PAUSED { return 59 } 113 // PAUSED actors are not runnable, won't be picked 114 let pick4: *NxActor = nx_ac_pick_next(s) 115 if pick4.actor_id != 1001 { return 60 } 116 if nx_ac_resume(s, 1002) != NX_AC_V_STEPPED { return 61 } 117 if a2p.state != NX_AC_STATE_READY { return 62 } 118 119 // 15: cannot resume non-paused 120 if nx_ac_resume(s, 1001) != NX_AC_V_INVALID { return 63 } 121 122 // 16: complete 123 if nx_ac_complete(s, 1003) != NX_AC_V_COMPLETED { return 64 } 124 let a3c: *NxActor = nx_ac_find(s, 1003) 125 if a3c.state != NX_AC_STATE_COMPLETED { return 65 } 126 // Stepping a completed actor -> BLOCKED 127 if nx_ac_step(s, 1003, 1000, now) != NX_AC_V_BLOCKED { return 66 } 128 129 // 17: fail 130 let s2: *NxActorScheduler = nx_ac_sched_new(4, 1000000, 4, now) 131 nx_ac_spawn(s2, 2001, 1, 50, 0, now) 132 if nx_ac_fail(s2, 2001) != NX_AC_V_FAILED { return 67 } 133 let af: *NxActor = nx_ac_find(s2, 2001) 134 if af.state != NX_AC_STATE_FAILED { return 68 } 135 136 // 18: deadline failure -- spawn with tight deadline, step past it 137 let s3: *NxActorScheduler = nx_ac_sched_new(4, 1000000, 4, now) 138 nx_ac_spawn(s3, 3001, 1, 50, now + 1000, now) 139 // Step at now + 2000 -> past deadline -> FAILED 140 if nx_ac_step(s3, 3001, 100, now + 2000) != NX_AC_V_FAILED { return 69 } 141 let a3001: *NxActor = nx_ac_find(s3, 3001) 142 if a3001.state != NX_AC_STATE_FAILED { return 70 } 143 144 // 19: count_by_state 145 let n_ready: nx_int = nx_ac_count_by_state(s, NX_AC_STATE_READY) 146 if n_ready != 2 { return 71 } // 1001 + 1002 both READY 147 if nx_ac_count_by_state(s, NX_AC_STATE_COMPLETED) != 1 { return 72 } 148 149 // 20: total_runtime accumulates 150 if nx_ac_total_runtime_us(s) < 20000 { return 73 } // 4 steps * 5000us = 20000 151 152 // 21: capacity exceeded 153 let s_full: *NxActorScheduler = nx_ac_sched_new(2, 1000000, 4, now) 154 nx_ac_spawn(s_full, 1, 1, 50, 0, now) 155 nx_ac_spawn(s_full, 2, 1, 50, 0, now) 156 if nx_ac_spawn(s_full, 3, 1, 50, 0, now) != NX_AC_V_INVALID { return 74 } 157 158 // 22: null handling 159 let null_s: *NxActorScheduler = (0 as i64) as *NxActorScheduler 160 if nx_ac_spawn(null_s, 1, 1, 50, 0, now) != NX_AC_V_NULL { return 75 } 161 if (nx_ac_find(null_s, 1) as i64) != 0 { return 76 } 162 if nx_ac_step(null_s, 1, 100, now) != NX_AC_V_NULL { return 77 } 163 if nx_ac_set_waiting(null_s, 1, NX_AC_WAIT_MESSAGE) != NX_AC_V_NULL { return 78 } 164 if nx_ac_wake(null_s, 1) != NX_AC_V_NULL { return 79 } 165 if nx_ac_pause(null_s, 1) != NX_AC_V_NULL { return 80 } 166 if nx_ac_resume(null_s, 1) != NX_AC_V_NULL { return 81 } 167 if nx_ac_complete(null_s, 1) != NX_AC_V_NULL { return 82 } 168 if nx_ac_fail(null_s, 1) != NX_AC_V_NULL { return 83 } 169 if nx_ac_epoch_tick(null_s, now) != NX_AC_V_NULL { return 84 } 170 if (nx_ac_pick_next(null_s) as i64) != 0 { return 85 } 171 if nx_ac_count_by_state(null_s, NX_AC_STATE_READY) != 0 { return 86 } 172 if nx_ac_total_runtime_us(null_s) != 0 { return 87 } 173 if nx_ac_actor_count(null_s) != 0 { return 88 } 174 175 return 0 176}