| ... | @@ -534,18 +534,27 @@ test { | ... | @@ -534,18 +534,27 @@ test { |
| 534 | /// | 534 | /// |
| 535 | /// Any relevant state shared between runs of `test_fn` *must* be reset within `test_fn`. | 535 | /// Any relevant state shared between runs of `test_fn` *must* be reset within `test_fn`. |
| 536 | /// | 536 | /// |
| 537 | /// Expects that the `test_fn` has a deterministic number of memory allocations | | |
| 538 | /// (an error will be returned if non-deterministic allocations are detected). | | |
| 539 | /// | | |
| 540 | /// The strategy employed is to: | 537 | /// The strategy employed is to: |
| 541 | /// - Run the test function once to get the total number of allocations. | 538 | /// - Run the test function once to get the total number of allocations. |
| 542 | /// - Then, iterate and run the function X more times, incrementing | 539 | /// - Then, iterate and run the function X more times, incrementing |
| 543 | /// the failing index each iteration (where X is the total number of | 540 | /// the failing index each iteration (where X is the total number of |
| 544 | /// allocations determined previously) | 541 | /// allocations determined previously) |
| 545 | /// | 542 | /// |
| | 543 | /// Expects that `test_fn` has a deterministic number of memory allocations: |
| | 544 | /// - If an allocation was made to fail during a run of `test_fn`, but `test_fn` |
| | 545 | /// didn't return `error.OutOfMemory`, then `error.SwallowedOutOfMemoryError` |
| | 546 | /// is returned from `checkAllAllocationFailures`. You may want to ignore this |
| | 547 | /// depending on whether or not the code you're testing includes some strategies |
| | 548 | /// for recovering from `error.OutOfMemory`. |
| | 549 | /// - If a run of `test_fn` with an expected allocation failure executes without |
| | 550 | /// an allocation failure being induced, then `error.NondeterministicMemoryUsage` |
| | 551 | /// is returned. This error means that there are allocation points that won't be |
| | 552 | /// tested by the strategy this function employs (that is, there are sometimes more |
| | 553 | /// points of allocation than the initial run of `test_fn` detects). |
| | 554 | /// |
| 546 | /// --- | 555 | /// --- |
| 547 | /// | 556 | /// |
| 548 | /// Here's an example of using a simple test case that will cause a leak when the | 557 | /// Here's an example using a simple test case that will cause a leak when the |
| 549 | /// allocation of `bar` fails (but will pass normally): | 558 | /// allocation of `bar` fails (but will pass normally): |
| 550 | /// | 559 | /// |
| 551 | /// ```zig | 560 | /// ```zig |
| ... | @@ -645,7 +654,11 @@ pub fn checkAllAllocationFailures(backing_allocator: std.mem.Allocator, comptime | ... | @@ -645,7 +654,11 @@ pub fn checkAllAllocationFailures(backing_allocator: std.mem.Allocator, comptime |
| 645 | args.@"0" = failing_allocator_inst.allocator(); | 654 | args.@"0" = failing_allocator_inst.allocator(); |
| 646 | | 655 | |
| 647 | if (@call(.{}, test_fn, args)) |_| { | 656 | if (@call(.{}, test_fn, args)) |_| { |
| 648 | return error.NondeterministicMemoryUsage; | 657 | if (failing_allocator_inst.has_induced_failure) { |
| | 658 | return error.SwallowedOutOfMemoryError; |
| | 659 | } else { |
| | 660 | return error.NondeterministicMemoryUsage; |
| | 661 | } |
| 649 | } else |err| switch (err) { | 662 | } else |err| switch (err) { |
| 650 | error.OutOfMemory => { | 663 | error.OutOfMemory => { |
| 651 | if (failing_allocator_inst.allocated_bytes != failing_allocator_inst.freed_bytes) { | 664 | if (failing_allocator_inst.allocated_bytes != failing_allocator_inst.freed_bytes) { |