test_map.odin 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. package test_internal_map
  2. import "core:fmt"
  3. import "base:intrinsics"
  4. import "core:math/rand"
  5. import "core:mem"
  6. import "core:os"
  7. import "core:testing"
  8. seed: u64
  9. ENTRY_COUNTS := []int{11, 101, 1_001, 10_001, 100_001, 1_000_001}
  10. @test
  11. map_insert_random_key_value :: proc(t: ^testing.T) {
  12. seed_incr := u64(0)
  13. for entries in ENTRY_COUNTS {
  14. fmt.printf("[map_insert_random_key_value] Testing %v entries.\n", entries)
  15. m: map[i64]i64
  16. defer delete(m)
  17. unique_keys := 0
  18. r := rand.create(seed + seed_incr)
  19. for _ in 0..<entries {
  20. k := rand.int63(&r)
  21. v := rand.int63(&r)
  22. if k not_in m {
  23. unique_keys += 1
  24. }
  25. m[k] = v
  26. }
  27. key_count := 0
  28. for _ in m {
  29. key_count += 1
  30. }
  31. expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
  32. expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
  33. // Reset randomizer and verify
  34. r = rand.create(seed + seed_incr)
  35. num_fails := 0
  36. for _ in 0..<entries {
  37. k := rand.int63(&r)
  38. v := rand.int63(&r)
  39. cond := m[k] == v
  40. if !cond {
  41. num_fails += 1
  42. if num_fails > 5 {
  43. fmt.println("... and more")
  44. break
  45. }
  46. expect(t, false, fmt.tprintf("Unexpected value. Expected m[%v] = %v, got %v", k, v, m[k]))
  47. }
  48. }
  49. seed_incr += 1
  50. }
  51. }
  52. @test
  53. map_update_random_key_value :: proc(t: ^testing.T) {
  54. seed_incr := u64(0)
  55. for entries in ENTRY_COUNTS {
  56. fmt.printf("[map_update_random_key_value] Testing %v entries.\n", entries)
  57. m: map[i64]i64
  58. defer delete(m)
  59. unique_keys := 0
  60. r := rand.create(seed + seed_incr)
  61. for _ in 0..<entries {
  62. k := rand.int63(&r)
  63. v := rand.int63(&r)
  64. if k not_in m {
  65. unique_keys += 1
  66. }
  67. m[k] = v
  68. }
  69. key_count := 0
  70. for _ in m {
  71. key_count += 1
  72. }
  73. expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
  74. expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
  75. half_entries := entries / 2
  76. // Reset randomizer and update half the entries
  77. r = rand.create(seed + seed_incr)
  78. for _ in 0..<half_entries {
  79. k := rand.int63(&r)
  80. v := rand.int63(&r)
  81. m[k] = v + 42
  82. }
  83. // Reset randomizer and verify
  84. r = rand.create(seed + seed_incr)
  85. num_fails := 0
  86. for i in 0..<entries {
  87. k := rand.int63(&r)
  88. v := rand.int63(&r)
  89. diff := i64(42) if i < half_entries else i64(0)
  90. cond := m[k] == (v + diff)
  91. if !cond {
  92. num_fails += 1
  93. if num_fails > 5 {
  94. fmt.println("... and more")
  95. break
  96. }
  97. expect(t, false, fmt.tprintf("Unexpected value. Expected m[%v] = %v, got %v", k, v, m[k]))
  98. }
  99. }
  100. seed_incr += 1
  101. }
  102. }
  103. @test
  104. map_delete_random_key_value :: proc(t: ^testing.T) {
  105. seed_incr := u64(0)
  106. for entries in ENTRY_COUNTS {
  107. fmt.printf("[map_delete_random_key_value] Testing %v entries.\n", entries)
  108. m: map[i64]i64
  109. defer delete(m)
  110. unique_keys := 0
  111. r := rand.create(seed + seed_incr)
  112. for _ in 0..<entries {
  113. k := rand.int63(&r)
  114. v := rand.int63(&r)
  115. if k not_in m {
  116. unique_keys += 1
  117. }
  118. m[k] = v
  119. }
  120. key_count := 0
  121. for _ in m {
  122. key_count += 1
  123. }
  124. expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
  125. expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
  126. half_entries := entries / 2
  127. // Reset randomizer and delete half the entries
  128. r = rand.create(seed + seed_incr)
  129. for _ in 0..<half_entries {
  130. k := rand.int63(&r)
  131. _ = rand.int63(&r)
  132. delete_key(&m, k)
  133. }
  134. // Reset randomizer and verify
  135. r = rand.create(seed + seed_incr)
  136. num_fails := 0
  137. for i in 0..<entries {
  138. k := rand.int63(&r)
  139. v := rand.int63(&r)
  140. if i < half_entries {
  141. if k in m {
  142. num_fails += 1
  143. if num_fails > 5 {
  144. fmt.println("... and more")
  145. break
  146. }
  147. expect(t, false, fmt.tprintf("Unexpected key present. Expected m[%v] to have been deleted, got %v", k, m[k]))
  148. }
  149. } else {
  150. if k not_in m {
  151. num_fails += 1
  152. if num_fails > 5 {
  153. fmt.println("... and more")
  154. break
  155. }
  156. expect(t, false, fmt.tprintf("Expected key not present. Expected m[%v] = %v", k, v))
  157. } else if m[k] != v {
  158. num_fails += 1
  159. if num_fails > 5 {
  160. fmt.println("... and more")
  161. break
  162. }
  163. expect(t, false, fmt.tprintf("Unexpected value. Expected m[%v] = %v, got %v", k, v, m[k]))
  164. }
  165. }
  166. }
  167. seed_incr += 1
  168. }
  169. }
  170. @test
  171. set_insert_random_key_value :: proc(t: ^testing.T) {
  172. seed_incr := u64(0)
  173. for entries in ENTRY_COUNTS {
  174. fmt.printf("[set_insert_random_key_value] Testing %v entries.\n", entries)
  175. m: map[i64]struct{}
  176. defer delete(m)
  177. unique_keys := 0
  178. r := rand.create(seed + seed_incr)
  179. for _ in 0..<entries {
  180. k := rand.int63(&r)
  181. if k not_in m {
  182. unique_keys += 1
  183. }
  184. m[k] = {}
  185. }
  186. key_count := 0
  187. for _ in m {
  188. key_count += 1
  189. }
  190. expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
  191. expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
  192. // Reset randomizer and verify
  193. r = rand.create(seed + seed_incr)
  194. num_fails := 0
  195. for _ in 0..<entries {
  196. k := rand.int63(&r)
  197. cond := k in m
  198. if !cond {
  199. num_fails += 1
  200. if num_fails > 5 {
  201. fmt.println("... and more")
  202. break
  203. }
  204. expect(t, false, fmt.tprintf("Unexpected value. Expected m[%v] to exist", k))
  205. }
  206. }
  207. seed_incr += 1
  208. }
  209. }
  210. @test
  211. set_delete_random_key_value :: proc(t: ^testing.T) {
  212. seed_incr := u64(0)
  213. for entries in ENTRY_COUNTS {
  214. fmt.printf("[set_delete_random_key_value] Testing %v entries.\n", entries)
  215. m: map[i64]struct{}
  216. defer delete(m)
  217. unique_keys := 0
  218. r := rand.create(seed + seed_incr)
  219. for _ in 0..<entries {
  220. k := rand.int63(&r)
  221. if k not_in m {
  222. unique_keys += 1
  223. }
  224. m[k] = {}
  225. }
  226. key_count := 0
  227. for _ in m {
  228. key_count += 1
  229. }
  230. expect(t, key_count == unique_keys, fmt.tprintf("Expected key_count to equal %v, got %v", unique_keys, key_count))
  231. expect(t, len(m) == unique_keys, fmt.tprintf("Expected len(map) to equal %v, got %v", unique_keys, len(m)))
  232. half_entries := entries / 2
  233. // Reset randomizer and delete half the entries
  234. r = rand.create(seed + seed_incr)
  235. for _ in 0..<half_entries {
  236. k := rand.int63(&r)
  237. delete_key(&m, k)
  238. }
  239. // Reset randomizer and verify
  240. r = rand.create(seed + seed_incr)
  241. num_fails := 0
  242. for i in 0..<entries {
  243. k := rand.int63(&r)
  244. if i < half_entries {
  245. if k in m {
  246. num_fails += 1
  247. if num_fails > 5 {
  248. fmt.println("... and more")
  249. break
  250. }
  251. expect(t, false, fmt.tprintf("Unexpected key present. Expected m[%v] to have been deleted", k))
  252. }
  253. } else {
  254. if k not_in m {
  255. num_fails += 1
  256. if num_fails > 5 {
  257. fmt.println("... and more")
  258. break
  259. }
  260. expect(t, false, fmt.tprintf("Expected key not present. Expected m[%v] to exist", k))
  261. }
  262. }
  263. }
  264. seed_incr += 1
  265. }
  266. }
  267. // -------- -------- -------- -------- -------- -------- -------- -------- -------- --------
  268. main :: proc() {
  269. t := testing.T{}
  270. // Allow tests to be repeatable
  271. SEED :: #config(SEED, -1)
  272. when SEED > 0 {
  273. seed = u64(SEED)
  274. } else {
  275. seed = u64(intrinsics.read_cycle_counter())
  276. }
  277. fmt.println("Initialized seed to", seed)
  278. mem_track_test(&t, map_insert_random_key_value)
  279. mem_track_test(&t, map_update_random_key_value)
  280. mem_track_test(&t, map_delete_random_key_value)
  281. mem_track_test(&t, set_insert_random_key_value)
  282. mem_track_test(&t, set_delete_random_key_value)
  283. fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
  284. if TEST_fail > 0 {
  285. os.exit(1)
  286. }
  287. }
  288. mem_track_test :: proc(t: ^testing.T, test: proc(t: ^testing.T)) {
  289. track: mem.Tracking_Allocator
  290. mem.tracking_allocator_init(&track, context.allocator)
  291. context.allocator = mem.tracking_allocator(&track)
  292. test(t)
  293. expect(t, len(track.allocation_map) == 0, "Expected no leaks.")
  294. expect(t, len(track.bad_free_array) == 0, "Expected no leaks.")
  295. for _, leak in track.allocation_map {
  296. fmt.printf("%v leaked %v bytes\n", leak.location, leak.size)
  297. }
  298. for bad_free in track.bad_free_array {
  299. fmt.printf("%v allocation %p was freed badly\n", bad_free.location, bad_free.memory)
  300. }
  301. }
  302. TEST_count := 0
  303. TEST_fail := 0
  304. when ODIN_TEST {
  305. expect :: testing.expect
  306. log :: testing.log
  307. } else {
  308. expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
  309. TEST_count += 1
  310. if !condition {
  311. TEST_fail += 1
  312. fmt.printf("[%v] %v\n", loc, message)
  313. return
  314. }
  315. }
  316. log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
  317. fmt.printf("[%v] ", loc)
  318. fmt.printf("log: %v\n", v)
  319. }
  320. }