code wiki / (root) / nx_fruiting_test.nx

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}