This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig standard library. Public Function
Exhaustively check that allocation failures within test_fn are handled without introducing memory leaks. If used with the testing.allocator as the backing_allocator, it will also be able to detect double frees, etc (when runtime safety is enabled).
The provided test_fn must have a std.mem.Allocator as its first argument, and must have a return type of !void. Any extra arguments of test_fn can be provided via the extra_args tuple.
Any relevant state shared between runs of test_fnmust be reset within test_fn.
The strategy employed is to:
Run the test function once to get the total number of allocations.
Then, iterate and run the function X more times, incrementing the failing index each iteration (where X is the total number of allocations determined previously)
Expects that test_fn has a deterministic number of memory allocations:
If an allocation was made to fail during a run of test_fn, but test_fn didn't return error.OutOfMemory, then error.SwallowedOutOfMemoryError is returned from checkAllAllocationFailures. You may want to ignore this depending on whether or not the code you're testing includes some strategies for recovering from error.OutOfMemory.
If a run of test_fn with an expected allocation failure executes without an allocation failure being induced, then error.NondeterministicMemoryUsage is returned. This error means that there are allocation points that won't be tested by the strategy this function employs (that is, there are sometimes more points of allocation than the initial run of test_fn detects).
Here's an example using a simple test case that will cause a leak when the allocation of bar fails (but will pass normally):
test {
const length: usize = 10;
const allocator = std.testing.allocator;
var foo = try allocator.alloc(u8, length);
var bar = try allocator.alloc(u8, length);
allocator.free(foo);
allocator.free(bar);
}
The test case can be converted to something that this function can use by doing:
fn testImpl(allocator: std.mem.Allocator, length: usize) !void {
var foo = try allocator.alloc(u8, length);
var bar = try allocator.alloc(u8, length);
allocator.free(foo);
allocator.free(bar);
}
test {
const length: usize = 10;
const allocator = std.testing.allocator;
try std.testing.checkAllAllocationFailures(allocator, testImpl, .{length});
}
Running this test will show that foo is leaked when the allocation of bar fails. The simplest fix, in this case, would be to use defer like so:
fn testImpl(allocator: std.mem.Allocator, length: usize) !void {
var foo = try allocator.alloc(u8, length);
defer allocator.free(foo);
var bar = try allocator.alloc(u8, length);
defer allocator.free(bar);
}
Exhaustively check that allocation failures within
test_fnare handled without introducing memory leaks. If used with thetesting.allocatoras thebacking_allocator, it will also be able to detect double frees, etc (when runtime safety is enabled).The provided
test_fnmust have astd.mem.Allocatoras its first argument, and must have a return type of!void. Any extra arguments oftest_fncan be provided via theextra_argstuple.Any relevant state shared between runs of
test_fnmust be reset withintest_fn.The strategy employed is to:
Expects that
test_fnhas a deterministic number of memory allocations:test_fn, buttest_fndidn't returnerror.OutOfMemory, thenerror.SwallowedOutOfMemoryErroris returned fromcheckAllAllocationFailures. You may want to ignore this depending on whether or not the code you're testing includes some strategies for recovering fromerror.OutOfMemory.test_fnwith an expected allocation failure executes without an allocation failure being induced, thenerror.NondeterministicMemoryUsageis returned. This error means that there are allocation points that won't be tested by the strategy this function employs (that is, there are sometimes more points of allocation than the initial run oftest_fndetects).Here's an example using a simple test case that will cause a leak when the allocation of
barfails (but will pass normally):The test case can be converted to something that this function can use by doing:
Running this test will show that
foois leaked when the allocation ofbarfails. The simplest fix, in this case, would be to use defer like so: