| ... | @@ -1149,7 +1149,9 @@ pub fn checkAllAllocationFailures( | ... | @@ -1149,7 +1149,9 @@ pub fn checkAllAllocationFailures( |
| 1149 | ) !void { | 1149 | ) !void { |
| 1150 | // Try it once with unlimited memory, make sure it works | 1150 | // Try it once with unlimited memory, make sure it works |
| 1151 | const needed_alloc_count = x: { | 1151 | const needed_alloc_count = x: { |
| 1152 | var failing_allocator_inst = std.testing.FailingAllocator.init(backing_allocator, .{}); | 1152 | var failing_allocator_inst = std.testing.FailingAllocator.init(backing_allocator, .{ |
| | 1153 | .resize_fail_index = 0, |
| | 1154 | }); |
| 1153 | | 1155 | |
| 1154 | try @call(.auto, test_fn, .{failing_allocator_inst.allocator()} ++ extra_args); | 1156 | try @call(.auto, test_fn, .{failing_allocator_inst.allocator()} ++ extra_args); |
| 1155 | break :x failing_allocator_inst.alloc_index; | 1157 | break :x failing_allocator_inst.alloc_index; |
| ... | @@ -1158,6 +1160,7 @@ pub fn checkAllAllocationFailures( | ... | @@ -1158,6 +1160,7 @@ pub fn checkAllAllocationFailures( |
| 1158 | for (0..needed_alloc_count) |fail_index| { | 1160 | for (0..needed_alloc_count) |fail_index| { |
| 1159 | var failing_allocator_inst = std.testing.FailingAllocator.init(backing_allocator, .{ | 1161 | var failing_allocator_inst = std.testing.FailingAllocator.init(backing_allocator, .{ |
| 1160 | .fail_index = fail_index, | 1162 | .fail_index = fail_index, |
| | 1163 | .resize_fail_index = 0, |
| 1161 | }); | 1164 | }); |
| 1162 | | 1165 | |
| 1163 | if (@call(.auto, test_fn, .{failing_allocator_inst.allocator()} ++ extra_args)) |_| { | 1166 | if (@call(.auto, test_fn, .{failing_allocator_inst.allocator()} ++ extra_args)) |_| { |
| ... | @@ -1239,6 +1242,24 @@ test "checkAllAllocationFailures provide result type to 'extra_args' argument" { | ... | @@ -1239,6 +1242,24 @@ test "checkAllAllocationFailures provide result type to 'extra_args' argument" { |
| 1239 | ); | 1242 | ); |
| 1240 | } | 1243 | } |
| 1241 | | 1244 | |
| | 1245 | test "checkAllAllocationFailures does not depend on in-place resizes" { |
| | 1246 | // `std.testing.allocator` never reuses memory, so whether a list can grow in place depends |
| | 1247 | // on where in its bucket it landed, which differs from one run to the next. |
| | 1248 | const S = struct { |
| | 1249 | fn f(gpa: std.mem.Allocator) !void { |
| | 1250 | var a: std.ArrayList(u8) = .empty; |
| | 1251 | defer a.deinit(gpa); |
| | 1252 | var b: std.ArrayList(u8) = .empty; |
| | 1253 | defer b.deinit(gpa); |
| | 1254 | for (0..2000) |i| { |
| | 1255 | try a.append(gpa, @truncate(i)); |
| | 1256 | try b.append(gpa, @truncate(i)); |
| | 1257 | } |
| | 1258 | } |
| | 1259 | }; |
| | 1260 | try checkAllAllocationFailures(std.testing.allocator, S.f, .{}); |
| | 1261 | } |
| | 1262 | |
| 1242 | /// Given a type, references all the declarations inside, so that the semantic analyzer sees them. | 1263 | /// Given a type, references all the declarations inside, so that the semantic analyzer sees them. |
| 1243 | pub fn refAllDecls(comptime T: type) void { | 1264 | pub fn refAllDecls(comptime T: type) void { |
| 1244 | if (!builtin.is_test) return; | 1265 | if (!builtin.is_test) return; |