authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2025-04-19 15:37:08-07:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-04-25 19:58:11+02:00
logaa013b7643870aef006a05146672a971500a0243
tree077c4a409f2b50666b8adef0e30a01352aa0e59e
parentf38a28a6261e6a3a5676d0438a6d5c7b6047ac52
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

FailingAllocator: remove outdated doc comments, move doc comment example to decltest

Note: The decltests for files-as-a-struct don't show up in autodoc currently

1 files changed, 38 insertions(+), 14 deletions(-)

lib/std/testing/FailingAllocator.zig+38-14
......@@ -1,13 +1,5 @@
11//! Allocator that fails after N allocations, useful for making sure out of
22//! memory conditions are handled correctly.
3//!
4//! To use this, first initialize it and get an allocator with
5//!
6//! `const failing_allocator = &FailingAllocator.init(<allocator>,
7//! <config>).allocator;`
8//!
9//! Then use `failing_allocator` anywhere you would have used a
10//! different allocator.
113const std = @import("../std.zig");
124const mem = std.mem;
135const FailingAllocator = @This();
......@@ -28,12 +20,7 @@ const num_stack_frames = if (std.debug.sys_can_stack_trace) 16 else 0;
2820
2921pub const Config = struct {
3022 /// The number of successful allocations you can expect from this allocator.
31 /// The next allocation will fail. For example, with `fail_index` equal to
32 /// 2, the following test will pass:
33 ///
34 /// var a = try failing_alloc.create(i32);
35 /// var b = try failing_alloc.create(i32);
36 /// testing.expectError(error.OutOfMemory, failing_alloc.create(i32));
23 /// The next allocation will fail.
3724 fail_index: usize = std.math.maxInt(usize),
3825
3926 /// Number of successful resizes to expect from this allocator. The next resize will fail.
......@@ -159,3 +146,40 @@ pub fn getStackTrace(self: *FailingAllocator) std.builtin.StackTrace {
159146 .index = len,
160147 };
161148}
149
150test FailingAllocator {
151 // Fail on allocation
152 {
153 var failing_allocator_state = FailingAllocator.init(std.testing.allocator, .{
154 .fail_index = 2,
155 });
156 const failing_alloc = failing_allocator_state.allocator();
157
158 const a = try failing_alloc.create(i32);
159 defer failing_alloc.destroy(a);
160 const b = try failing_alloc.create(i32);
161 defer failing_alloc.destroy(b);
162 try std.testing.expectError(error.OutOfMemory, failing_alloc.create(i32));
163 }
164 // Fail on resize
165 {
166 var failing_allocator_state = FailingAllocator.init(std.testing.allocator, .{
167 .resize_fail_index = 1,
168 });
169 const failing_alloc = failing_allocator_state.allocator();
170
171 const resized_slice = blk: {
172 const slice = try failing_alloc.alloc(u8, 8);
173 errdefer failing_alloc.free(slice);
174
175 break :blk failing_alloc.remap(slice, 6) orelse return error.UnexpectedRemapFailure;
176 };
177 defer failing_alloc.free(resized_slice);
178
179 // Remap and resize should fail from here on out
180 try std.testing.expectEqual(null, failing_alloc.remap(resized_slice, 4));
181 try std.testing.expectEqual(false, failing_alloc.resize(resized_slice, 4));
182
183 // Note: realloc could succeed because it falls back to free+alloc
184 }
185}