nx_actor_role_llm_v2_test.nx source
↩ module page · 126 lines · 6857 B
1// nx_actor_role_llm_v2_test.nx -- wiring smoke for nx_actor_role_llm_v2.
2//
3// HONEST SCOPE: this smoke proves the adapter compiles, constructs,
4// validates inputs, and exposes correct accessors / phase + verdict
5// enums. It does NOT drive the v2 runner end-to-end because that
6// requires a real GGUF fixture (the v2 runner has its own real-GGUF
7// happy-path smoke at nx_llm_run_v2_test.nx). Driving the runner with
8// null/empty inputs segfaults inside nx_bpe_encode -- so the adapter's
9// constructor rejects all null pointers at the boundary per the
10// defensive-at-boundaries discipline, and this smoke verifies those
11// rejections. Future smoke would compose with a synthetic GGUF
12// builder to exercise the RUN -> EMIT path end-to-end.
13
14import "nx_syscalls.nx"
15import "nx_tier.nx"
16import "nx_model_spec.nx"
17import "nx_gguf.nx"
18import "nx_bpe.nx"
19import "nx_actor.nx"
20import "nx_message.nx"
21import "nx_actor_role_llm_v2.nx"
22
23func main() -> i64 {
24 let now: nx_size = 1000000
25
26 // 1: phase enum validity
27 if nx_lv_phase_is_valid(NX_LV_PHASE_INIT) != 1 { return 1 }
28 if nx_lv_phase_is_valid(NX_LV_PHASE_RUN) != 1 { return 2 }
29 if nx_lv_phase_is_valid(NX_LV_PHASE_EMIT) != 1 { return 3 }
30 if nx_lv_phase_is_valid(NX_LV_PHASE_DONE) != 1 { return 4 }
31 if nx_lv_phase_is_valid(-1) != 0 { return 5 }
32 if nx_lv_phase_is_valid(4) != 0 { return 6 }
33 if NX_LV_PHASE_N != 4 { return 7 }
34
35 // 2: verdict enum validity
36 if nx_lv_v_is_valid(NX_LV_V_STEPPED) != 1 { return 8 }
37 if nx_lv_v_is_valid(NX_LV_V_COMPLETED) != 1 { return 9 }
38 if nx_lv_v_is_valid(NX_LV_V_FAILED_RUN) != 1 { return 10 }
39 if nx_lv_v_is_valid(NX_LV_V_INVALID) != 1 { return 11 }
40 if nx_lv_v_is_valid(NX_LV_V_NULL) != 1 { return 12 }
41 if nx_lv_v_is_valid(-1) != 0 { return 13 }
42 if nx_lv_v_is_valid(NX_LV_V_N) != 0 { return 14 }
43
44 // 3: build typed non-null sentinel inputs (NOT a real fixture, just
45 // enough to satisfy the constructor's null-pointer checks). We
46 // will not invoke the actor's RUN step on these because that
47 // would crash inside the runner; instead we test the WIRING:
48 // construction, accessors, idempotent step-past-DONE, null guards.
49 let spec: *NxModelSpec = nx_model_spec_gpt2_small()
50 if (spec as i64) == 0 { return 15 }
51 if nx_model_spec_validate(spec) != NX_MS_OK { return 16 }
52
53 let gguf_buf: *u8 = sys_mmap(64)
54 let hdr_ptr: *u8 = sys_mmap(NX_GGUF_HDR_BYTES)
55 let hdr: *NxGgufHeader = hdr_ptr as *NxGgufHeader
56 let bpe_ptr: *u8 = sys_mmap(NX_BPE_VOCAB_BYTES)
57 let bpe: *NxBpeVocab = bpe_ptr as *NxBpeVocab
58 let prompt: *u8 = sys_mmap(16)
59 prompt[0] = 65 as u8
60 prompt[1] = 66 as u8
61 let prng_buf: *u8 = sys_mmap(16)
62 let prng: *i64 = prng_buf as *i64
63 prng[0] = 42
64
65 // 4: valid constructor
66 let ctx: *NxLlmV2ActorCtx = nx_lv_actor_new(
67 spec, gguf_buf, hdr, bpe, prompt, 2,
68 1024, 40, prng, 10000, 91)
69 if (ctx as i64) == 0 { return 17 }
70 if ctx.prompt_len != 2 { return 18 }
71 if ctx.temperature_q10 != 1024 { return 19 }
72 if ctx.top_k != 40 { return 20 }
73 if ctx.rope_base != 10000 { return 21 }
74 if ctx.attn_scale_q10 != 91 { return 22 }
75 if ctx.current_phase != NX_LV_PHASE_INIT { return 23 }
76 if ctx.runner_verdict != NX_LR2_OK { return 24 }
77 if ctx.runner_result != 0 { return 25 }
78
79 // 5: constructor rejects null pointers at boundary
80 let null_spec: *NxModelSpec = (0 as i64) as *NxModelSpec
81 let null_buf: *u8 = (0 as i64) as *u8
82 let null_hdr: *NxGgufHeader = (0 as i64) as *NxGgufHeader
83 let null_bpe: *NxBpeVocab = (0 as i64) as *NxBpeVocab
84 let null_prng: *i64 = (0 as i64) as *i64
85
86 if nx_lv_actor_new(null_spec, gguf_buf, hdr, bpe, prompt, 2, 1024, 40, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 26 }
87 if nx_lv_actor_new(spec, null_buf, hdr, bpe, prompt, 2, 1024, 40, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 27 }
88 if nx_lv_actor_new(spec, gguf_buf, null_hdr, bpe, prompt, 2, 1024, 40, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 28 }
89 if nx_lv_actor_new(spec, gguf_buf, hdr, null_bpe, prompt, 2, 1024, 40, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 29 }
90 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, null_buf, 2, 1024, 40, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 30 }
91 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 2, 1024, 40, null_prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 31 }
92
93 // 6: constructor rejects invalid scalar params
94 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 0, 1024, 40, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 32 }
95 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, -1, 1024, 40, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 33 }
96 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 2, 0, 40, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 34 }
97 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 2, -1, 40, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 35 }
98 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 2, 1024, 0, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 36 }
99 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 2, 1024, -1, prng, 10000, 91) != (0 as *NxLlmV2ActorCtx) { return 37 }
100 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 2, 1024, 40, prng, 0, 91) != (0 as *NxLlmV2ActorCtx) { return 38 }
101 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 2, 1024, 40, prng, 1, 91) != (0 as *NxLlmV2ActorCtx) { return 39 }
102 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 2, 1024, 40, prng, 10000, 0) != (0 as *NxLlmV2ActorCtx) { return 40 }
103 if nx_lv_actor_new(spec, gguf_buf, hdr, bpe, prompt, 2, 1024, 40, prng, 10000, -1) != (0 as *NxLlmV2ActorCtx) { return 41 }
104
105 // 7: accessors on valid pre-RUN ctx
106 if nx_lv_actor_phase(ctx) != NX_LV_PHASE_INIT { return 42 }
107 // runner_result == 0 (pre-RUN); token accessor returns 0 (token id 0 is
108 // valid, but in pre-RUN state caller should not interpret it).
109 if nx_lv_actor_token(ctx) != 0 { return 43 }
110 if nx_lv_actor_runner_verdict(ctx) != NX_LR2_OK { return 44 }
111 if nx_lv_actor_is_done(ctx) != 0 { return 45 }
112
113 // 8: null guards on accessors
114 let null_ctx: *NxLlmV2ActorCtx = (0 as i64) as *NxLlmV2ActorCtx
115 if nx_lv_actor_phase(null_ctx) != NX_LV_PHASE_DONE { return 46 }
116 if nx_lv_actor_token(null_ctx) != -1 { return 47 }
117 if nx_lv_actor_runner_verdict(null_ctx) != NX_LR2_ERR_BAD_SPEC { return 48 }
118 if nx_lv_actor_is_done(null_ctx) != 0 { return 49 }
119
120 // 9: step on null ctx returns NULL verdict (no crash)
121 let sched: *NxActorScheduler = nx_ac_sched_new(2, 1000000, 4, now)
122 let bus: *NxMessageBus = nx_ms_bus_new(2, 2, 4)
123 if nx_lv_actor_step(null_ctx, sched, bus, 1, now) != NX_LV_V_NULL { return 50 }
124
125 return 0
126}