aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/core/mem/test_core_mem.odin108
-rw-r--r--tests/issues/run.bat1
-rwxr-xr-xtests/issues/run.sh1
-rw-r--r--tests/issues/test_issue_2694.odin42
4 files changed, 152 insertions, 0 deletions
diff --git a/tests/core/mem/test_core_mem.odin b/tests/core/mem/test_core_mem.odin
index bd072b4e9..c1cb59c68 100644
--- a/tests/core/mem/test_core_mem.odin
+++ b/tests/core/mem/test_core_mem.odin
@@ -193,3 +193,111 @@ fail_if_allocations_overlap :: proc(t: ^testing.T, a, b: []byte) {
testing.fail_now(t, "Allocations overlapped")
}
}
+
+
+// This merely does a few simple operations to test basic sanity.
+//
+// A serious test of an allocator would require hooking it up to a benchmark or
+// a large, complicated program in order to get all manner of usage patterns.
+basic_sanity_test :: proc(t: ^testing.T, allocator: mem.Allocator, limit: int, loc := #caller_location) -> bool {
+ context.allocator = allocator
+
+ {
+ a := make([dynamic]u8)
+ for i in 0..<limit {
+ append(&a, u8(i))
+ }
+ testing.expect_value(t, len(a), limit, loc) or_return
+ for i in 0..<limit {
+ testing.expect_value(t, a[i], u8(i), loc) or_return
+ }
+ delete(a)
+ }
+
+ {
+ v := make([]u8, limit)
+ testing.expect_value(t, len(v), limit, loc) or_return
+ for i in 0..<limit {
+ v[i] = u8(i)
+ testing.expect_value(t, v[i], u8(i), loc) or_return
+ }
+ delete(v)
+ }
+
+ {
+ for i in 0..<limit {
+ v := make([]u8, 1)
+ v[0] = u8(i)
+ testing.expect_value(t, v[0], u8(i), loc) or_return
+ delete(v)
+ }
+ }
+
+ return true
+}
+
+@test
+test_scratch :: proc(t: ^testing.T) {
+ N :: 4096
+ sa: mem.Scratch_Allocator
+ mem.scratch_init(&sa, N)
+ defer mem.scratch_destroy(&sa)
+ basic_sanity_test(t, mem.scratch_allocator(&sa), N / 4)
+ basic_sanity_test(t, mem.scratch_allocator(&sa), N / 4)
+}
+
+@test
+test_stack :: proc(t: ^testing.T) {
+ N :: 4096
+ buf: [N]u8
+
+ sa: mem.Stack
+ mem.stack_init(&sa, buf[:])
+ basic_sanity_test(t, mem.stack_allocator(&sa), N / 4)
+ basic_sanity_test(t, mem.stack_allocator(&sa), N / 4)
+}
+
+@test
+test_small_stack :: proc(t: ^testing.T) {
+ N :: 4096
+ buf: [N]u8
+
+ ss: mem.Small_Stack
+ mem.small_stack_init(&ss, buf[:])
+ basic_sanity_test(t, mem.small_stack_allocator(&ss), N / 4)
+ // The test cannot be run a second time on top of the last for a Small
+ // Stack because the dynamic array inside will resize and leave a gap, thus
+ // limiting the amount of space.
+ basic_sanity_test(t, mem.small_stack_allocator(&ss), N / 8)
+}
+
+@test
+test_dynamic_arena :: proc(t: ^testing.T) {
+ da: mem.Dynamic_Arena
+ mem.dynamic_arena_init(&da)
+ defer mem.dynamic_arena_destroy(&da)
+ basic_sanity_test(t, mem.dynamic_arena_allocator(&da), da.block_size / 4)
+ basic_sanity_test(t, mem.dynamic_arena_allocator(&da), da.block_size / 4)
+}
+
+@test
+test_buddy :: proc(t: ^testing.T) {
+ N :: 4096
+ buf: [N]u8
+
+ ba: mem.Buddy_Allocator
+ mem.buddy_allocator_init(&ba, buf[:], align_of(u8))
+ basic_sanity_test(t, mem.buddy_allocator(&ba), N / 8)
+ basic_sanity_test(t, mem.buddy_allocator(&ba), N / 8)
+}
+
+@test
+test_rollback :: proc(t: ^testing.T) {
+ N :: 4096
+ buf: [N]u8
+
+ rb: mem.Rollback_Stack
+ mem.rollback_stack_init(&rb, buf[:])
+ basic_sanity_test(t, mem.rollback_stack_allocator(&rb), N / 8)
+ basic_sanity_test(t, mem.rollback_stack_allocator(&rb), N / 8)
+}
diff --git a/tests/issues/run.bat b/tests/issues/run.bat
index 8e71c3f3d..76d8f58b6 100644
--- a/tests/issues/run.bat
+++ b/tests/issues/run.bat
@@ -16,6 +16,7 @@ set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style
..\..\..\odin test ..\test_issue_2615.odin %COMMON% || exit /b
..\..\..\odin test ..\test_issue_2637.odin %COMMON% || exit /b
..\..\..\odin test ..\test_issue_2666.odin %COMMON% || exit /b
+..\..\..\odin test ..\test_issue_2694.odin %COMMON% || exit /b
..\..\..\odin test ..\test_issue_4210.odin %COMMON% || exit /b
..\..\..\odin test ..\test_issue_4364.odin %COMMON% || exit /b
..\..\..\odin test ..\test_issue_4584.odin %COMMON% || exit /b
diff --git a/tests/issues/run.sh b/tests/issues/run.sh
index fc8ab513f..305329e7d 100755
--- a/tests/issues/run.sh
+++ b/tests/issues/run.sh
@@ -17,6 +17,7 @@ $ODIN test ../test_issue_2466.odin $COMMON
$ODIN test ../test_issue_2615.odin $COMMON
$ODIN test ../test_issue_2637.odin $COMMON
$ODIN test ../test_issue_2666.odin $COMMON
+$ODIN test ../test_issue_2694.odin $COMMON
$ODIN test ../test_issue_4210.odin $COMMON
$ODIN test ../test_issue_4364.odin $COMMON
$ODIN test ../test_issue_4584.odin $COMMON
diff --git a/tests/issues/test_issue_2694.odin b/tests/issues/test_issue_2694.odin
new file mode 100644
index 000000000..01860d603
--- /dev/null
+++ b/tests/issues/test_issue_2694.odin
@@ -0,0 +1,42 @@
+package test_issues
+
+import "core:fmt"
+import "core:encoding/json"
+import "core:log"
+import "core:mem"
+import "core:testing"
+
+// This is a minimal reproduction of the code in #2694.
+// It exemplifies the original problem as briefly as possible.
+
+SAMPLE_JSON :: `
+{
+ "foo": 0,
+ "things": [
+ { "a": "ZZZZ"},
+ ]
+}
+`
+
+@test
+test_issue_2694 :: proc(t: ^testing.T) {
+ into: struct {
+ foo: int,
+ things: []json.Object,
+ }
+
+ scratch := new(mem.Scratch_Allocator)
+ defer free(scratch)
+ if mem.scratch_allocator_init(scratch, 4 * mem.Megabyte) != .None {
+ log.error("unable to initialize scratch allocator")
+ return
+ }
+ defer mem.scratch_allocator_destroy(scratch)
+
+ err := json.unmarshal_string(SAMPLE_JSON, &into, allocator = mem.scratch_allocator(scratch))
+ testing.expect(t, err == nil)
+
+ output := fmt.tprintf("%v", into)
+ expected := `{foo = 0, things = [map[a="ZZZZ"]]}`
+ testing.expectf(t, output == expected, "\n\texpected: %q\n\tgot: %q", expected, output)
+}