Commit c06fecd466

Ryan Liptak <squeek502@hotmail.com>
2025-04-20 00:37:08
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 parent 927f233
Changed files (1)
lib
lib/std/testing/FailingAllocator.zig
@@ -1,13 +1,5 @@
 //! Allocator that fails after N allocations, useful for making sure out of
 //! memory conditions are handled correctly.
-//!
-//! To use this, first initialize it and get an allocator with
-//!
-//! `const failing_allocator = &FailingAllocator.init(<allocator>,
-//!                                                   <config>).allocator;`
-//!
-//! Then use `failing_allocator` anywhere you would have used a
-//! different allocator.
 const std = @import("../std.zig");
 const mem = std.mem;
 const FailingAllocator = @This();
@@ -28,12 +20,7 @@ const num_stack_frames = if (std.debug.sys_can_stack_trace) 16 else 0;
 
 pub const Config = struct {
     /// The number of successful allocations you can expect from this allocator.
-    /// The next allocation will fail. For example, with `fail_index` equal to
-    /// 2, the following test will pass:
-    ///
-    /// var a = try failing_alloc.create(i32);
-    /// var b = try failing_alloc.create(i32);
-    /// testing.expectError(error.OutOfMemory, failing_alloc.create(i32));
+    /// The next allocation will fail.
     fail_index: usize = std.math.maxInt(usize),
 
     /// 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 {
         .index = len,
     };
 }
+
+test FailingAllocator {
+    // Fail on allocation
+    {
+        var failing_allocator_state = FailingAllocator.init(std.testing.allocator, .{
+            .fail_index = 2,
+        });
+        const failing_alloc = failing_allocator_state.allocator();
+
+        const a = try failing_alloc.create(i32);
+        defer failing_alloc.destroy(a);
+        const b = try failing_alloc.create(i32);
+        defer failing_alloc.destroy(b);
+        try std.testing.expectError(error.OutOfMemory, failing_alloc.create(i32));
+    }
+    // Fail on resize
+    {
+        var failing_allocator_state = FailingAllocator.init(std.testing.allocator, .{
+            .resize_fail_index = 1,
+        });
+        const failing_alloc = failing_allocator_state.allocator();
+
+        const resized_slice = blk: {
+            const slice = try failing_alloc.alloc(u8, 8);
+            errdefer failing_alloc.free(slice);
+
+            break :blk failing_alloc.remap(slice, 6) orelse return error.UnexpectedRemapFailure;
+        };
+        defer failing_alloc.free(resized_slice);
+
+        // Remap and resize should fail from here on out
+        try std.testing.expectEqual(null, failing_alloc.remap(resized_slice, 4));
+        try std.testing.expectEqual(false, failing_alloc.resize(resized_slice, 4));
+
+        // Note: realloc could succeed because it falls back to free+alloc
+    }
+}