diff --git a/lib/std/core/runtime_test.c3 b/lib/std/core/runtime_test.c3 index 4faad43c9..1c3bbe0c0 100644 --- a/lib/std/core/runtime_test.c3 +++ b/lib/std/core/runtime_test.c3 @@ -27,6 +27,8 @@ struct TestContext bool is_in_panic; bool is_quiet_mode; bool is_no_capture; + bool sort; + bool check_leaks; String current_test_name; TestFn setup_fn; TestFn teardown_fn; @@ -185,8 +187,6 @@ fn void unmute_output(bool has_error) @local fn bool run_tests(String[] args, TestUnit[] tests) @private { usz max_name; - bool sort_tests = true; - bool check_leaks = true; if (!tests.len) { io::printn("There are no test units to run."); @@ -204,6 +204,8 @@ $endif { .assert_print_backtrace = true, .breakpoint_on_assert = false, + .sort = true, + .check_leaks = true, .log_level = LogPriority.ERROR, .test_filter = "", .has_ansi_codes = terminal_has_ansi_codes(), @@ -218,9 +220,9 @@ $endif case "--test-breakpoint": context.breakpoint_on_assert = true; case "--test-nosort": - sort_tests = false; + context.sort = false; case "--test-noleak": - check_leaks = false; + context.check_leaks = false; case "--test-nocapture": case "--test-show-output": context.is_no_capture = true; @@ -261,7 +263,7 @@ $endif test_context = &context; log::set_priority_all(test_context.log_level); - if (sort_tests) + if (context.sort) { quicksort(tests, &cmp_test_unit); } @@ -321,14 +323,17 @@ $endif { mute_output(); mem.clear(); - if (check_leaks) allocator::thread_allocator = &mem; - unit.func(); + if (context.check_leaks) allocator::thread_allocator = &mem; + @pool() + { + unit.func(); + }; // track cleanup that may take place in teardown_fn if (context.teardown_fn) { context.teardown_fn(); } - if (check_leaks) allocator::thread_allocator = context.stored.allocator; + if (context.check_leaks) allocator::thread_allocator = context.stored.allocator; unmute_output(false); // all good, discard output if (mem.has_leaks()) diff --git a/releasenotes.md b/releasenotes.md index c574ea3b1..dc61084e9 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -22,6 +22,7 @@ - Hard limit of 127 characters for identifiers. - `$$LINE` would sometimes yield the incorrect format. - Fix error message when a method has the wrong type for the first argument. +- Unit tests allocating too much `tmem` without `@pool` would cause errors in unrelated tests. #2654 ### Stdlib changes - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. diff --git a/test/unit/stdlib/runtime_test.c3 b/test/unit/stdlib/runtime_test.c3 new file mode 100644 index 000000000..d79a297c5 --- /dev/null +++ b/test/unit/stdlib/runtime_test.c3 @@ -0,0 +1,26 @@ +module runtime_test_tests @test; + +import std::core::runtime @public; +import std::core::mem::allocator @public; +import std::math::random; + + +fn void tmem_shouldnt_leak_if_no_pool() +{ + for (usz i = 0; i < 256; i++) + { + char[] my_arr = mem::talloc_array(char, 1024); + my_arr[..] = (char[*]){ [0..1023] = 0xA5 }[..]; + } +} + +fn void ensure_leak_check_works() +{ + if (!(runtime::test_context.check_leaks)) return; + + char[] my_arr = mem::alloc_array(char, 1024); + test::@check(((TrackingAllocator*)allocator::thread_allocator).has_leaks()); + + mem::free(my_arr); + test::@check(!((TrackingAllocator*)allocator::thread_allocator).has_leaks()); +}