code wiki / (root) / nx_kv_store_test.nx

nx_kv_store_test.nx source

↩ module page · 133 lines · 6191 B

1// nx_kv_store_test.nx -- smoke for append-only KV store. 2// 3// expect_exit: 0 4// 5// license_tier: ORIGINAL 6 7import "nx_syscalls_x86_64.nx" 8import "nx_kv_store.nx" 9 10func bytes_eq(a: *u8, b: *u8, n: i64) -> i64 { 11 var i: i64 = 0 12 while i < n { 13 if a[i] != b[i] { return 0 } 14 i = i + 1 15 } 16 return 1 17} 18 19func main() -> i64 { 20 // ---- Verdict enum ---- 21 if nxkv_verdict_is_valid(NXKV_OK) != 1 { return 1 } 22 if nxkv_verdict_is_valid(NXKV_NOT_FOUND) != 1 { return 2 } 23 if nxkv_verdict_is_valid(NXKV_VERDICT_N) != 0 { return 3 } 24 if bytes_eq(nxkv_verdict_name(NXKV_OK), "OK" as *u8, 2) != 1 { return 4 } 25 if bytes_eq(nxkv_verdict_name(NXKV_NOT_FOUND), "NOT_FOUND" as *u8, 9) != 1 { return 5 } 26 if bytes_eq(nxkv_verdict_name(NXKV_OOM_DATA), "OOM_DATA" as *u8, 8) != 1 { return 6 } 27 28 // ---- Init ---- 29 let kv_raw: *u8 = sys_mmap(NX_KV_STORE_BYTES) 30 let kv: *NxKvStore = kv_raw as *NxKvStore 31 let data_buf: *u8 = sys_mmap(4096) 32 let index_buf: *u8 = sys_mmap(1024) 33 if nx_kv_store_init(kv, data_buf, 4096, index_buf, 1024) != NXKV_OK { return 10 } 34 if nx_kv_store_len(kv) != 0 { return 11 } 35 if nx_kv_store_bytes_used(kv) != 0 { return 12 } 36 37 // ---- Put + get single key ---- 38 if nx_kv_store_put(kv, "session_abc123" as *u8, 14, 39 "alice@example.com" as *u8, 17) != NXKV_OK { return 20 } 40 if nx_kv_store_len(kv) != 1 { return 21 } 41 // bytes_used = 4 + 14 + 4 + 17 = 39 42 if nx_kv_store_bytes_used(kv) != 39 { return 22 } 43 44 let voff: *i64 = sys_mmap(8) as *i64 45 let vlen: *i64 = sys_mmap(8) as *i64 46 if nx_kv_store_get(kv, "session_abc123" as *u8, 14, voff, vlen) != NXKV_OK { return 30 } 47 if vlen[0] != 17 { return 31 } 48 let v_ptr: *u8 = ((data_buf as i64) + voff[0]) as *u8 49 if bytes_eq(v_ptr, "alice@example.com" as *u8, 17) != 1 { return 32 } 50 51 // ---- contains ---- 52 if nx_kv_store_contains(kv, "session_abc123" as *u8, 14) != 1 { return 40 } 53 if nx_kv_store_contains(kv, "session_xyz999" as *u8, 14) != 0 { return 41 } 54 55 // ---- Put second key ---- 56 if nx_kv_store_put(kv, "session_xyz999" as *u8, 14, 57 "bob@example.com" as *u8, 15) != NXKV_OK { return 50 } 58 if nx_kv_store_len(kv) != 2 { return 51 } 59 60 // Both findable 61 if nx_kv_store_get(kv, "session_xyz999" as *u8, 14, voff, vlen) != NXKV_OK { return 52 } 62 if vlen[0] != 15 { return 53 } 63 let v2_ptr: *u8 = ((data_buf as i64) + voff[0]) as *u8 64 if bytes_eq(v2_ptr, "bob@example.com" as *u8, 15) != 1 { return 54 } 65 66 if nx_kv_store_get(kv, "session_abc123" as *u8, 14, voff, vlen) != NXKV_OK { return 55 } 67 if vlen[0] != 17 { return 56 } 68 69 // ---- NOT_FOUND ---- 70 if nx_kv_store_get(kv, "missing_key_xx" as *u8, 14, voff, vlen) != NXKV_NOT_FOUND { return 60 } 71 72 // ---- Additive update (overwrite key; most recent wins) ---- 73 if nx_kv_store_put(kv, "session_abc123" as *u8, 14, 74 "alice@updated.com" as *u8, 17) != NXKV_OK { return 70 } 75 if nx_kv_store_len(kv) != 3 { return 71 } // 3 entries (history preserved) 76 if nx_kv_store_get(kv, "session_abc123" as *u8, 14, voff, vlen) != NXKV_OK { return 72 } 77 if vlen[0] != 17 { return 73 } 78 let v3_ptr: *u8 = ((data_buf as i64) + voff[0]) as *u8 79 if bytes_eq(v3_ptr, "alice@updated.com" as *u8, 17) != 1 { return 74 } 80 81 // ---- Replay: rebuild index from existing data buf ---- 82 // Save data_buf state to a new store; replay should rebuild. 83 let kv2_raw: *u8 = sys_mmap(NX_KV_STORE_BYTES) 84 let kv2: *NxKvStore = kv2_raw as *NxKvStore 85 let data_buf2: *u8 = sys_mmap(4096) 86 let index_buf2: *u8 = sys_mmap(1024) 87 // Copy data_buf contents to data_buf2. 88 let used: i64 = nx_kv_store_bytes_used(kv) 89 var ci: i64 = 0 90 while ci < used { data_buf2[ci] = data_buf[ci]; ci = ci + 1 } 91 nx_kv_store_init(kv2, data_buf2, 4096, index_buf2, 1024) 92 if nx_kv_store_replay(kv2, used) != NXKV_OK { return 80 } 93 if nx_kv_store_len(kv2) != 3 { return 81 } 94 if nx_kv_store_bytes_used(kv2) != used { return 82 } 95 // Get should return the LATEST version of session_abc123. 96 if nx_kv_store_get(kv2, "session_abc123" as *u8, 14, voff, vlen) != NXKV_OK { return 83 } 97 if vlen[0] != 17 { return 84 } 98 let v_replay_ptr: *u8 = ((data_buf2 as i64) + voff[0]) as *u8 99 if bytes_eq(v_replay_ptr, "alice@updated.com" as *u8, 17) != 1 { return 85 } 100 101 // ---- OOM_DATA ---- 102 let kv3_raw: *u8 = sys_mmap(NX_KV_STORE_BYTES) 103 let kv3: *NxKvStore = kv3_raw as *NxKvStore 104 let tiny_data: *u8 = sys_mmap(32) 105 let tiny_index: *u8 = sys_mmap(64) 106 nx_kv_store_init(kv3, tiny_data, 32, tiny_index, 64) 107 // First put fits (4+5+4+5=18 bytes) 108 if nx_kv_store_put(kv3, "abcde" as *u8, 5, "12345" as *u8, 5) != NXKV_OK { return 90 } 109 // Second put fits (4+5+4+5=18 bytes; total 36 > 32 cap) 110 if nx_kv_store_put(kv3, "fghij" as *u8, 5, "67890" as *u8, 5) != NXKV_OOM_DATA { return 91 } 111 112 // ---- Empty value ---- 113 let kv4_raw: *u8 = sys_mmap(NX_KV_STORE_BYTES) 114 let kv4: *NxKvStore = kv4_raw as *NxKvStore 115 let d4: *u8 = sys_mmap(256) 116 let i4: *u8 = sys_mmap(256) 117 nx_kv_store_init(kv4, d4, 256, i4, 256) 118 if nx_kv_store_put(kv4, "empty_val" as *u8, 9, "" as *u8, 0) != NXKV_OK { return 100 } 119 if nx_kv_store_get(kv4, "empty_val" as *u8, 9, voff, vlen) != NXKV_OK { return 101 } 120 if vlen[0] != 0 { return 102 } 121 122 // ---- BAD_ARG ---- 123 if nx_kv_store_init(0 as *NxKvStore, data_buf, 4096, index_buf, 1024) != NXKV_BAD_ARG { return 110 } 124 if nx_kv_store_init(kv, 0 as *u8, 4096, index_buf, 1024) != NXKV_BAD_ARG { return 111 } 125 if nx_kv_store_init(kv, data_buf, 0, index_buf, 1024) != NXKV_BAD_ARG { return 112 } 126 if nx_kv_store_init(kv, data_buf, 4096, index_buf, 8) != NXKV_BAD_ARG { return 113 } 127 if nx_kv_store_put(0 as *NxKvStore, "k" as *u8, 1, "v" as *u8, 1) != NXKV_BAD_ARG { return 114 } 128 if nx_kv_store_put(kv, 0 as *u8, 1, "v" as *u8, 1) != NXKV_BAD_ARG { return 115 } 129 if nx_kv_store_put(kv, "k" as *u8, 0, "v" as *u8, 1) != NXKV_BAD_ARG { return 116 } 130 if nx_kv_store_put(kv, "k" as *u8, 1, "v" as *u8, -1) != NXKV_BAD_ARG { return 117 } 131 132 return 0 133}