nx_fruiting_test.nx source
↩ module page · 162 lines · 6897 B
1// nx_fruiting_test.nx -- smoke for nx_fruiting.
2
3import "nx_syscalls.nx"
4import "nx_fruiting.nx"
5
6func main() -> i64 {
7 let now: nx_size = 1000
8
9 // 1: dispersal mode enum validity
10 if nx_fr_mode_is_valid(NX_FR_ANEMOPHILY) != 1 { return 1 }
11 if nx_fr_mode_is_valid(NX_FR_AUTOCHORY) != 1 { return 2 }
12 if nx_fr_mode_is_valid(-1) != 0 { return 3 }
13 if nx_fr_mode_is_valid(5) != 0 { return 4 }
14 if NX_FR_N_MODES != 5 { return 5 }
15
16 // 2: state enum validity
17 if nx_fb_state_is_valid(NX_FB_DEVELOPING) != 1 { return 6 }
18 if nx_fb_state_is_valid(NX_FB_FAILED) != 1 { return 7 }
19 if nx_fb_state_is_valid(-1) != 0 { return 8 }
20 if nx_fb_state_is_valid(5) != 0 { return 9 }
21
22 // 3: verdict enum validity
23 if nx_fr_verdict_is_valid(NX_FR_OK) != 1 { return 10 }
24 if nx_fr_verdict_is_valid(NX_FR_ERR_NULL_INPUT) != 1 { return 11 }
25 if nx_fr_verdict_is_valid(-1) != 0 { return 12 }
26 if nx_fr_verdict_is_valid(7) != 0 { return 13 }
27
28 // 4: broadcast-mode predicate
29 if nx_fr_mode_is_broadcast(NX_FR_ANEMOPHILY) != 1 { return 14 }
30 if nx_fr_mode_is_broadcast(NX_FR_HYDROPHILY) != 1 { return 15 }
31 if nx_fr_mode_is_broadcast(NX_FR_ZOOCHORY) != 0 { return 16 }
32 if nx_fr_mode_is_broadcast(NX_FR_BALLISTOSPORY) != 0 { return 17 }
33 if nx_fr_mode_is_broadcast(NX_FR_AUTOCHORY) != 0 { return 18 }
34
35 // 5: active-sender predicate
36 if nx_fr_mode_requires_active_sender(NX_FR_BALLISTOSPORY) != 1 { return 19 }
37 if nx_fr_mode_requires_active_sender(NX_FR_ANEMOPHILY) != 0 { return 20 }
38 if nx_fr_mode_requires_active_sender(NX_FR_AUTOCHORY) != 0 { return 21 }
39
40 // 6: state predicates
41 if nx_fb_state_is_serving(NX_FB_DISPERSING) != 1 { return 22 }
42 if nx_fb_state_is_serving(NX_FB_DEVELOPING) != 0 { return 23 }
43 if nx_fb_state_is_terminal(NX_FB_QUIESCENT) != 1 { return 24 }
44 if nx_fb_state_is_terminal(NX_FB_FAILED) != 1 { return 25 }
45 if nx_fb_state_is_terminal(NX_FB_DISPERSING) != 0 { return 26 }
46
47 // 7: fresh body defaults
48 let b: *NxFruitingBody = nx_fb_new(42, NX_FR_ANEMOPHILY, 10, 1234, now)
49 if b.body_id != 42 { return 27 }
50 if b.dispersal_mode != NX_FR_ANEMOPHILY { return 28 }
51 if b.state != NX_FB_DEVELOPING { return 29 }
52 if b.total_fragments != 10 { return 30 }
53 if b.fragments_complete != 0 { return 31 }
54 if b.served_count != 0 { return 32 }
55 // Default budget = 10 * 100 = 1000
56 if b.dispersal_budget != 1000 { return 33 }
57 if b.root_methyl_id != 1234 { return 34 }
58
59 // 8: invalid total_fragments returns null
60 let b_bad: *NxFruitingBody = nx_fb_new(1, NX_FR_ANEMOPHILY, 0, 0, now)
61 if b_bad != (0 as *NxFruitingBody) { return 35 }
62
63 // 9: cannot transition to READY before all fragments complete
64 let bad_ready: nx_int = nx_fb_transition(b, NX_FB_READY_TO_DISPERSE)
65 if bad_ready != NX_FR_ERR_FRAGMENT_OUT_OF_RANGE { return 36 }
66
67 // 10: record fragment-complete events
68 var i: nx_int = 0
69 while i < 10 {
70 let rc: nx_int = nx_fb_record_fragment_complete(b)
71 if rc != NX_FR_OK { return 37 }
72 i = i + 1
73 }
74 if b.fragments_complete != 10 { return 38 }
75 if nx_fb_is_complete(b) != 1 { return 39 }
76
77 // 11: over-complete rejected
78 let over: nx_int = nx_fb_record_fragment_complete(b)
79 if over != NX_FR_ERR_FRAGMENT_OUT_OF_RANGE { return 40 }
80
81 // 12: transition DEVELOPING -> READY
82 let v_ready: nx_int = nx_fb_transition(b, NX_FB_READY_TO_DISPERSE)
83 if v_ready != NX_FR_OK { return 41 }
84 if b.state != NX_FB_READY_TO_DISPERSE { return 42 }
85
86 // 13: cannot record fragment-complete after DEVELOPING
87 let bad_rec: nx_int = nx_fb_record_fragment_complete(b)
88 if bad_rec != NX_FR_ERR_INVALID_STATE { return 43 }
89
90 // 14: budget override allowed before DISPERSING
91 let v_budget: nx_int = nx_fb_set_dispersal_budget(b, 50)
92 if v_budget != NX_FR_OK { return 44 }
93 if b.dispersal_budget != 50 { return 45 }
94
95 // 15: transition READY -> DISPERSING
96 let v_disp: nx_int = nx_fb_transition(b, NX_FB_DISPERSING)
97 if v_disp != NX_FR_OK { return 46 }
98 if b.state != NX_FB_DISPERSING { return 47 }
99
100 // 16: budget cannot be changed once DISPERSING
101 let bad_budget: nx_int = nx_fb_set_dispersal_budget(b, 100)
102 if bad_budget != NX_FR_ERR_INVALID_STATE { return 48 }
103
104 // 17: serve fragments + verify count
105 var j: nx_int = 0
106 while j < 30 {
107 let rc: nx_int = nx_fb_serve_fragment(b, j % 10, now + j)
108 if rc != NX_FR_OK { return 49 }
109 j = j + 1
110 }
111 if b.served_count != 30 { return 50 }
112 if nx_fb_remaining_budget(b) != 20 { return 51 } // 50 - 30
113
114 // 18: invalid fragment_index rejected
115 let bad_idx: nx_int = nx_fb_serve_fragment(b, 99, now)
116 if bad_idx != NX_FR_ERR_FRAGMENT_OUT_OF_RANGE { return 52 }
117 let bad_neg: nx_int = nx_fb_serve_fragment(b, -1, now)
118 if bad_neg != NX_FR_ERR_FRAGMENT_OUT_OF_RANGE { return 53 }
119
120 // 19: exhaust budget + auto-quiesce
121 var k: nx_int = 0
122 while k < 20 {
123 nx_fb_serve_fragment(b, k % 10, now + 100 + k)
124 k = k + 1
125 }
126 // served_count = 50, budget = 50 -> next serve fails + state QUIESCENT
127 if b.served_count != 50 { return 54 }
128 if b.state != NX_FB_QUIESCENT { return 55 }
129
130 // 20: budget-exhausted rejection
131 let bad_exhaust: nx_int = nx_fb_serve_fragment(b, 0, now + 200)
132 if bad_exhaust != NX_FR_ERR_INVALID_STATE { return 56 }
133
134 // 21: cannot transition out of QUIESCENT (terminal)
135 let bad_term: nx_int = nx_fb_transition(b, NX_FB_DEVELOPING)
136 if bad_term != NX_FR_ERR_INVALID_TRANSITION { return 57 }
137
138 // 22: separate body -- ballistospory (active push) mode
139 let b2: *NxFruitingBody = nx_fb_new(99, NX_FR_BALLISTOSPORY, 5, 5678, now)
140 if b2.dispersal_mode != NX_FR_BALLISTOSPORY { return 58 }
141 if nx_fr_mode_requires_active_sender(b2.dispersal_mode) != 1 { return 59 }
142
143 // 23: another body -- FAILED transition from any non-terminal
144 let b3: *NxFruitingBody = nx_fb_new(100, NX_FR_AUTOCHORY, 3, 0, now)
145 let v_fail: nx_int = nx_fb_transition(b3, NX_FB_FAILED)
146 if v_fail != NX_FR_OK { return 60 }
147 if b3.state != NX_FB_FAILED { return 61 }
148 // FAILED is terminal; no further transitions
149 let bad_resume: nx_int = nx_fb_transition(b3, NX_FB_DEVELOPING)
150 if bad_resume != NX_FR_ERR_INVALID_TRANSITION { return 62 }
151
152 // 24: null input handling
153 let null_b: *NxFruitingBody = (0 as i64) as *NxFruitingBody
154 if nx_fb_record_fragment_complete(null_b) != NX_FR_ERR_NULL_INPUT { return 63 }
155 if nx_fb_transition(null_b, NX_FB_FAILED) != NX_FR_ERR_NULL_INPUT { return 64 }
156 if nx_fb_serve_fragment(null_b, 0, now) != NX_FR_ERR_NULL_INPUT { return 65 }
157 if nx_fb_set_dispersal_budget(null_b, 100) != NX_FR_ERR_NULL_INPUT { return 66 }
158 if nx_fb_is_complete(null_b) != 0 { return 67 }
159 if nx_fb_remaining_budget(null_b) != 0 { return 68 }
160
161 return 0
162}