Create leak_count_allocator

This commit is contained in:
Benjamin Feng 2020-01-29 13:18:04 -06:00
parent 4d134a01f5
commit aa9caf5064
22 changed files with 206 additions and 135 deletions

View File

@ -672,7 +672,7 @@ const TermState = enum {
test "term color" {
const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
const result = try termColor(std.testing.allocator, input_bytes);
const result = try termColor(std.testing.leak_count_allocator, input_bytes);
testing.expectEqualSlices(u8, "A<span class=\"t32\">green</span>B", result);
}

View File

@ -320,7 +320,7 @@ test "std.ArrayList.basic" {
}
test "std.ArrayList.orderedRemove" {
var list = ArrayList(i32).init(testing.allocator);
var list = ArrayList(i32).init(testing.leak_count_allocator);
defer list.deinit();
try list.append(1);
@ -347,7 +347,7 @@ test "std.ArrayList.orderedRemove" {
}
test "std.ArrayList.swapRemove" {
var list = ArrayList(i32).init(testing.allocator);
var list = ArrayList(i32).init(testing.leak_count_allocator);
defer list.deinit();
try list.append(1);
@ -374,7 +374,7 @@ test "std.ArrayList.swapRemove" {
}
test "std.ArrayList.swapRemoveOrError" {
var list = ArrayList(i32).init(testing.allocator);
var list = ArrayList(i32).init(testing.leak_count_allocator);
defer list.deinit();
// Test just after initialization
@ -402,7 +402,7 @@ test "std.ArrayList.swapRemoveOrError" {
}
test "std.ArrayList.insert" {
var list = ArrayList(i32).init(testing.allocator);
var list = ArrayList(i32).init(testing.leak_count_allocator);
defer list.deinit();
try list.append(1);
@ -416,7 +416,7 @@ test "std.ArrayList.insert" {
}
test "std.ArrayList.insertSlice" {
var list = ArrayList(i32).init(testing.allocator);
var list = ArrayList(i32).init(testing.leak_count_allocator);
defer list.deinit();
try list.append(1);
@ -443,7 +443,8 @@ const Item = struct {
};
test "std.ArrayList: ArrayList(T) of struct T" {
var root = Item{ .integer = 1, .sub_items = ArrayList(Item).init(testing.allocator) };
try root.sub_items.append(Item{ .integer = 42, .sub_items = ArrayList(Item).init(testing.allocator) });
var root = Item{ .integer = 1, .sub_items = ArrayList(Item).init(testing.leak_count_allocator) };
defer root.sub_items.deinit();
try root.sub_items.append(Item{ .integer = 42, .sub_items = ArrayList(Item).init(testing.leak_count_allocator) });
testing.expect(root.sub_items.items[0].integer == 42);
}

View File

@ -150,7 +150,9 @@ pub const Buffer = struct {
};
test "simple Buffer" {
var buf = try Buffer.init(testing.allocator, "");
var buf = try Buffer.init(testing.leak_count_allocator, "");
defer buf.deinit();
testing.expect(buf.len() == 0);
try buf.append("hello");
try buf.append(" ");
@ -159,6 +161,7 @@ test "simple Buffer" {
testing.expect(mem.eql(u8, mem.toSliceConst(u8, buf.toSliceConst().ptr), buf.toSliceConst()));
var buf2 = try Buffer.initFromBuffer(buf);
defer buf2.deinit();
testing.expect(buf.eql(buf2.toSliceConst()));
testing.expect(buf.startsWith("hell"));
@ -169,14 +172,16 @@ test "simple Buffer" {
}
test "Buffer.initSize" {
var buf = try Buffer.initSize(testing.allocator, 3);
var buf = try Buffer.initSize(testing.leak_count_allocator, 3);
defer buf.deinit();
testing.expect(buf.len() == 3);
try buf.append("hello");
testing.expect(mem.eql(u8, buf.toSliceConst()[3..], "hello"));
}
test "Buffer.initCapacity" {
var buf = try Buffer.initCapacity(testing.allocator, 10);
var buf = try Buffer.initCapacity(testing.leak_count_allocator, 10);
defer buf.deinit();
testing.expect(buf.len() == 0);
testing.expect(buf.capacity() >= 10);
const old_cap = buf.capacity();

View File

@ -2193,7 +2193,7 @@ fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool)
}
pub const global_allocator = blk: {
@compileError("Please switch to std.testing.allocator.");
@compileError("Please switch to std.testing.leak_count_allocator.");
};
var global_fixed_allocator = std.heap.ThreadSafeFixedBufferAllocator.init(global_allocator_mem[0..]);
var global_allocator_mem: [100 * 1024]u8 = undefined;

View File

@ -347,7 +347,7 @@ pub fn LinearFifo(
}
test "LinearFifo(u8, .Dynamic)" {
var fifo = LinearFifo(u8, .Dynamic).init(testing.allocator);
var fifo = LinearFifo(u8, .Dynamic).init(testing.leak_count_allocator);
defer fifo.deinit();
try fifo.write("HELLO");
@ -422,7 +422,7 @@ test "LinearFifo" {
var fifo = switch (bt) {
.Static => FifoType.init(),
.Slice => FifoType.init(buf[0..]),
.Dynamic => FifoType.init(testing.allocator),
.Dynamic => FifoType.init(testing.leak_count_allocator),
};
defer fifo.deinit();

View File

@ -1598,7 +1598,8 @@ test "hexToBytes" {
test "formatIntValue with comptime_int" {
const value: comptime_int = 123456789123456789;
var buf = try std.Buffer.init(std.testing.allocator, "");
var buf = try std.Buffer.init(std.testing.leak_count_allocator, "");
defer buf.deinit();
try formatIntValue(value, "", FormatOptions{}, &buf, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append);
std.testing.expect(mem.eql(u8, buf.toSlice(), "123456789123456789"));
}
@ -1652,19 +1653,23 @@ test "formatType max_depth" {
inst.a = &inst;
inst.tu.ptr = &inst.tu;
var buf0 = try std.Buffer.init(std.testing.allocator, "");
var buf0 = try std.Buffer.init(std.testing.leak_count_allocator, "");
defer buf0.deinit();
try formatType(inst, "", FormatOptions{}, &buf0, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 0);
std.testing.expect(mem.eql(u8, buf0.toSlice(), "S{ ... }"));
var buf1 = try std.Buffer.init(std.testing.allocator, "");
var buf1 = try std.Buffer.init(std.testing.leak_count_allocator, "");
defer buf1.deinit();
try formatType(inst, "", FormatOptions{}, &buf1, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 1);
std.testing.expect(mem.eql(u8, buf1.toSlice(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }"));
var buf2 = try std.Buffer.init(std.testing.allocator, "");
var buf2 = try std.Buffer.init(std.testing.leak_count_allocator, "");
defer buf2.deinit();
try formatType(inst, "", FormatOptions{}, &buf2, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 2);
std.testing.expect(mem.eql(u8, buf2.toSlice(), "S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }"));
var buf3 = try std.Buffer.init(std.testing.allocator, "");
var buf3 = try std.Buffer.init(std.testing.leak_count_allocator, "");
defer buf3.deinit();
try formatType(inst, "", FormatOptions{}, &buf3, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 3);
std.testing.expect(mem.eql(u8, buf3.toSlice(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }"));
}

View File

@ -665,15 +665,16 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
}
test "resolve" {
const cwd = try process.getCwdAlloc(testing.allocator);
const cwd = try process.getCwdAlloc(testing.leak_count_allocator);
defer testing.leak_count_allocator.free(cwd);
if (builtin.os == .windows) {
if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {
cwd[0] = asciiUpper(cwd[0]);
}
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{"."}), cwd));
try testResolveWindows(&[_][]const u8{"."}, cwd);
} else {
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "a/b/c/", "../../.." }), cwd));
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{"."}), cwd));
try testResolvePosix(&[_][]const u8{ "a/b/c/", "../../.." }, cwd);
try testResolvePosix(&[_][]const u8{"."}, cwd);
}
}
@ -683,66 +684,71 @@ test "resolveWindows" {
return error.SkipZigTest;
}
if (builtin.os == .windows) {
const cwd = try process.getCwdAlloc(testing.allocator);
const cwd = try process.getCwdAlloc(testing.leak_count_allocator);
defer testing.leak_count_allocator.free(cwd);
const parsed_cwd = windowsParsePath(cwd);
{
const result = testResolveWindows(&[_][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" });
const expected = try join(testing.allocator, &[_][]const u8{
const expected = try join(testing.leak_count_allocator, &[_][]const u8{
parsed_cwd.disk_designator,
"usr\\local\\lib\\zig\\std\\array_list.zig",
});
defer testing.leak_count_allocator.free(expected);
if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
}
testing.expect(mem.eql(u8, result, expected));
try testResolveWindows(&[_][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" }, expected);
}
{
const result = testResolveWindows(&[_][]const u8{ "usr/local", "lib\\zig" });
const expected = try join(testing.allocator, &[_][]const u8{
const expected = try join(testing.leak_count_allocator, &[_][]const u8{
cwd,
"usr\\local\\lib\\zig",
});
defer testing.leak_count_allocator.free(expected);
if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
}
testing.expect(mem.eql(u8, result, expected));
try testResolveWindows(&[_][]const u8{ "usr/local", "lib\\zig" }, expected);
}
}
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }), "C:\\hi\\ok"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }), "C:\\blah\\a"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "C:../a" }), "C:\\blah\\a"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/ignore", "d:\\a/b\\c/d", "\\e.exe" }), "D:\\e.exe"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/ignore", "c:/some/file" }), "C:\\some\\file"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "d:/ignore", "d:some/dir//" }), "D:\\ignore\\some\\dir"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "//server/share", "..", "relative\\" }), "\\\\server\\share\\relative"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//" }), "C:\\"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//dir" }), "C:\\dir"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//server/share" }), "\\\\server\\share\\"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//server//share" }), "\\\\server\\share\\"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "///some//dir" }), "C:\\some\\dir"));
testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }), "C:\\foo\\tmp.3\\cycles\\root.js"));
try testResolveWindows(&[_][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }, "C:\\hi\\ok");
try testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }, "C:\\blah\\a");
try testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "C:../a" }, "C:\\blah\\a");
try testResolveWindows(&[_][]const u8{ "c:/ignore", "d:\\a/b\\c/d", "\\e.exe" }, "D:\\e.exe");
try testResolveWindows(&[_][]const u8{ "c:/ignore", "c:/some/file" }, "C:\\some\\file");
try testResolveWindows(&[_][]const u8{ "d:/ignore", "d:some/dir//" }, "D:\\ignore\\some\\dir");
try testResolveWindows(&[_][]const u8{ "//server/share", "..", "relative\\" }, "\\\\server\\share\\relative");
try testResolveWindows(&[_][]const u8{ "c:/", "//" }, "C:\\");
try testResolveWindows(&[_][]const u8{ "c:/", "//dir" }, "C:\\dir");
try testResolveWindows(&[_][]const u8{ "c:/", "//server/share" }, "\\\\server\\share\\");
try testResolveWindows(&[_][]const u8{ "c:/", "//server//share" }, "\\\\server\\share\\");
try testResolveWindows(&[_][]const u8{ "c:/", "///some//dir" }, "C:\\some\\dir");
try testResolveWindows(&[_][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }, "C:\\foo\\tmp.3\\cycles\\root.js");
}
test "resolvePosix" {
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/a/b", "c" }), "/a/b/c"));
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/a/b", "c", "//d", "e///" }), "/d/e"));
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/a/b/c", "..", "../" }), "/a"));
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/", "..", ".." }), "/"));
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{"/a/b/c/"}), "/a/b/c"));
try testResolvePosix(&[_][]const u8{ "/a/b", "c" }, "/a/b/c");
try testResolvePosix(&[_][]const u8{ "/a/b", "c", "//d", "e///" }, "/d/e");
try testResolvePosix(&[_][]const u8{ "/a/b/c", "..", "../" }, "/a");
try testResolvePosix(&[_][]const u8{ "/", "..", ".." }, "/");
try testResolvePosix(&[_][]const u8{"/a/b/c/"}, "/a/b/c");
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/var/lib", "../", "file/" }), "/var/file"));
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/var/lib", "/../", "file/" }), "/file"));
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/some/dir", ".", "/absolute/" }), "/absolute"));
testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }), "/foo/tmp.3/cycles/root.js"));
try testResolvePosix(&[_][]const u8{ "/var/lib", "../", "file/" }, "/var/file");
try testResolvePosix(&[_][]const u8{ "/var/lib", "/../", "file/" }, "/file");
try testResolvePosix(&[_][]const u8{ "/some/dir", ".", "/absolute/" }, "/absolute");
try testResolvePosix(&[_][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }, "/foo/tmp.3/cycles/root.js");
}
fn testResolveWindows(paths: []const []const u8) []u8 {
return resolveWindows(testing.allocator, paths) catch unreachable;
fn testResolveWindows(paths: []const []const u8, expected: []const u8) !void {
const actual = try resolveWindows(testing.leak_count_allocator, paths);
defer testing.leak_count_allocator.free(actual);
return testing.expect(mem.eql(u8, actual, expected));
}
fn testResolvePosix(paths: []const []const u8) []u8 {
return resolvePosix(testing.allocator, paths) catch unreachable;
fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void {
const actual = try resolvePosix(testing.leak_count_allocator, paths);
defer testing.leak_count_allocator.free(actual);
return testing.expect(mem.eql(u8, actual, expected));
}
/// If the path is a file in the current directory (no directory component)
@ -1126,51 +1132,53 @@ test "relative" {
// TODO https://github.com/ziglang/zig/issues/3288
return error.SkipZigTest;
}
testRelativeWindows("c:/blah\\blah", "d:/games", "D:\\games");
testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa", "..");
testRelativeWindows("c:/aaaa/bbbb", "c:/cccc", "..\\..\\cccc");
testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa/bbbb", "");
testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa/cccc", "..\\cccc");
testRelativeWindows("c:/aaaa/", "c:/aaaa/cccc", "cccc");
testRelativeWindows("c:/", "c:\\aaaa\\bbbb", "aaaa\\bbbb");
testRelativeWindows("c:/aaaa/bbbb", "d:\\", "D:\\");
testRelativeWindows("c:/AaAa/bbbb", "c:/aaaa/bbbb", "");
testRelativeWindows("c:/aaaaa/", "c:/aaaa/cccc", "..\\aaaa\\cccc");
testRelativeWindows("C:\\foo\\bar\\baz\\quux", "C:\\", "..\\..\\..\\..");
testRelativeWindows("C:\\foo\\test", "C:\\foo\\test\\bar\\package.json", "bar\\package.json");
testRelativeWindows("C:\\foo\\bar\\baz-quux", "C:\\foo\\bar\\baz", "..\\baz");
testRelativeWindows("C:\\foo\\bar\\baz", "C:\\foo\\bar\\baz-quux", "..\\baz-quux");
testRelativeWindows("\\\\foo\\bar", "\\\\foo\\bar\\baz", "baz");
testRelativeWindows("\\\\foo\\bar\\baz", "\\\\foo\\bar", "..");
testRelativeWindows("\\\\foo\\bar\\baz-quux", "\\\\foo\\bar\\baz", "..\\baz");
testRelativeWindows("\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz-quux", "..\\baz-quux");
testRelativeWindows("C:\\baz-quux", "C:\\baz", "..\\baz");
testRelativeWindows("C:\\baz", "C:\\baz-quux", "..\\baz-quux");
testRelativeWindows("\\\\foo\\baz-quux", "\\\\foo\\baz", "..\\baz");
testRelativeWindows("\\\\foo\\baz", "\\\\foo\\baz-quux", "..\\baz-quux");
testRelativeWindows("C:\\baz", "\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz");
testRelativeWindows("\\\\foo\\bar\\baz", "C:\\baz", "C:\\baz");
try testRelativeWindows("c:/blah\\blah", "d:/games", "D:\\games");
try testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa", "..");
try testRelativeWindows("c:/aaaa/bbbb", "c:/cccc", "..\\..\\cccc");
try testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa/bbbb", "");
try testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa/cccc", "..\\cccc");
try testRelativeWindows("c:/aaaa/", "c:/aaaa/cccc", "cccc");
try testRelativeWindows("c:/", "c:\\aaaa\\bbbb", "aaaa\\bbbb");
try testRelativeWindows("c:/aaaa/bbbb", "d:\\", "D:\\");
try testRelativeWindows("c:/AaAa/bbbb", "c:/aaaa/bbbb", "");
try testRelativeWindows("c:/aaaaa/", "c:/aaaa/cccc", "..\\aaaa\\cccc");
try testRelativeWindows("C:\\foo\\bar\\baz\\quux", "C:\\", "..\\..\\..\\..");
try testRelativeWindows("C:\\foo\\test", "C:\\foo\\test\\bar\\package.json", "bar\\package.json");
try testRelativeWindows("C:\\foo\\bar\\baz-quux", "C:\\foo\\bar\\baz", "..\\baz");
try testRelativeWindows("C:\\foo\\bar\\baz", "C:\\foo\\bar\\baz-quux", "..\\baz-quux");
try testRelativeWindows("\\\\foo\\bar", "\\\\foo\\bar\\baz", "baz");
try testRelativeWindows("\\\\foo\\bar\\baz", "\\\\foo\\bar", "..");
try testRelativeWindows("\\\\foo\\bar\\baz-quux", "\\\\foo\\bar\\baz", "..\\baz");
try testRelativeWindows("\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz-quux", "..\\baz-quux");
try testRelativeWindows("C:\\baz-quux", "C:\\baz", "..\\baz");
try testRelativeWindows("C:\\baz", "C:\\baz-quux", "..\\baz-quux");
try testRelativeWindows("\\\\foo\\baz-quux", "\\\\foo\\baz", "..\\baz");
try testRelativeWindows("\\\\foo\\baz", "\\\\foo\\baz-quux", "..\\baz-quux");
try testRelativeWindows("C:\\baz", "\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz");
try testRelativeWindows("\\\\foo\\bar\\baz", "C:\\baz", "C:\\baz");
testRelativePosix("/var/lib", "/var", "..");
testRelativePosix("/var/lib", "/bin", "../../bin");
testRelativePosix("/var/lib", "/var/lib", "");
testRelativePosix("/var/lib", "/var/apache", "../apache");
testRelativePosix("/var/", "/var/lib", "lib");
testRelativePosix("/", "/var/lib", "var/lib");
testRelativePosix("/foo/test", "/foo/test/bar/package.json", "bar/package.json");
testRelativePosix("/Users/a/web/b/test/mails", "/Users/a/web/b", "../..");
testRelativePosix("/foo/bar/baz-quux", "/foo/bar/baz", "../baz");
testRelativePosix("/foo/bar/baz", "/foo/bar/baz-quux", "../baz-quux");
testRelativePosix("/baz-quux", "/baz", "../baz");
testRelativePosix("/baz", "/baz-quux", "../baz-quux");
try testRelativePosix("/var/lib", "/var", "..");
try testRelativePosix("/var/lib", "/bin", "../../bin");
try testRelativePosix("/var/lib", "/var/lib", "");
try testRelativePosix("/var/lib", "/var/apache", "../apache");
try testRelativePosix("/var/", "/var/lib", "lib");
try testRelativePosix("/", "/var/lib", "var/lib");
try testRelativePosix("/foo/test", "/foo/test/bar/package.json", "bar/package.json");
try testRelativePosix("/Users/a/web/b/test/mails", "/Users/a/web/b", "../..");
try testRelativePosix("/foo/bar/baz-quux", "/foo/bar/baz", "../baz");
try testRelativePosix("/foo/bar/baz", "/foo/bar/baz-quux", "../baz-quux");
try testRelativePosix("/baz-quux", "/baz", "../baz");
try testRelativePosix("/baz", "/baz-quux", "../baz-quux");
}
fn testRelativePosix(from: []const u8, to: []const u8, expected_output: []const u8) void {
const result = relativePosix(testing.allocator, from, to) catch unreachable;
fn testRelativePosix(from: []const u8, to: []const u8, expected_output: []const u8) !void {
const result = try relativePosix(testing.leak_count_allocator, from, to);
defer testing.leak_count_allocator.free(result);
testing.expectEqualSlices(u8, expected_output, result);
}
fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []const u8) void {
const result = relativeWindows(testing.allocator, from, to) catch unreachable;
fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []const u8) !void {
const result = try relativeWindows(testing.leak_count_allocator, from, to);
defer testing.leak_count_allocator.free(result);
testing.expectEqualSlices(u8, expected_output, result);
}

View File

@ -143,7 +143,7 @@ pub fn SinglyLinkedList(comptime T: type) type {
}
test "basic SinglyLinkedList test" {
const allocator = testing.allocator;
const allocator = testing.leak_count_allocator;
var list = SinglyLinkedList(u32).init();
var one = try list.createNode(1, allocator);
@ -404,7 +404,7 @@ pub fn TailQueue(comptime T: type) type {
}
test "basic TailQueue test" {
const allocator = testing.allocator;
const allocator = testing.leak_count_allocator;
var list = TailQueue(u32).init();
var one = try list.createNode(1, allocator);
@ -456,7 +456,7 @@ test "basic TailQueue test" {
}
test "TailQueue concatenation" {
const allocator = testing.allocator;
const allocator = testing.leak_count_allocator;
var list1 = TailQueue(u32).init();
var list2 = TailQueue(u32).init();

View File

@ -9,7 +9,7 @@ const elf = std.elf;
const File = std.fs.File;
const Thread = std.Thread;
const a = std.testing.allocator;
const a = std.testing.leak_count_allocator;
const builtin = @import("builtin");
const AtomicRmwOp = builtin.AtomicRmwOp;

View File

@ -239,7 +239,7 @@ fn greaterThan(a: u32, b: u32) bool {
const PQ = PriorityQueue(u32);
test "std.PriorityQueue: add and remove min heap" {
var queue = PQ.init(testing.allocator, lessThan);
var queue = PQ.init(testing.leak_count_allocator, lessThan);
defer queue.deinit();
try queue.add(54);
@ -257,7 +257,7 @@ test "std.PriorityQueue: add and remove min heap" {
}
test "std.PriorityQueue: add and remove same min heap" {
var queue = PQ.init(testing.allocator, lessThan);
var queue = PQ.init(testing.leak_count_allocator, lessThan);
defer queue.deinit();
try queue.add(1);
@ -275,14 +275,14 @@ test "std.PriorityQueue: add and remove same min heap" {
}
test "std.PriorityQueue: removeOrNull on empty" {
var queue = PQ.init(testing.allocator, lessThan);
var queue = PQ.init(testing.leak_count_allocator, lessThan);
defer queue.deinit();
expect(queue.removeOrNull() == null);
}
test "std.PriorityQueue: edge case 3 elements" {
var queue = PQ.init(testing.allocator, lessThan);
var queue = PQ.init(testing.leak_count_allocator, lessThan);
defer queue.deinit();
try queue.add(9);
@ -294,7 +294,7 @@ test "std.PriorityQueue: edge case 3 elements" {
}
test "std.PriorityQueue: peek" {
var queue = PQ.init(testing.allocator, lessThan);
var queue = PQ.init(testing.leak_count_allocator, lessThan);
defer queue.deinit();
expect(queue.peek() == null);
@ -306,7 +306,7 @@ test "std.PriorityQueue: peek" {
}
test "std.PriorityQueue: sift up with odd indices" {
var queue = PQ.init(testing.allocator, lessThan);
var queue = PQ.init(testing.leak_count_allocator, lessThan);
defer queue.deinit();
const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
for (items) |e| {
@ -320,7 +320,7 @@ test "std.PriorityQueue: sift up with odd indices" {
}
test "std.PriorityQueue: addSlice" {
var queue = PQ.init(testing.allocator, lessThan);
var queue = PQ.init(testing.leak_count_allocator, lessThan);
defer queue.deinit();
const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
try queue.addSlice(items[0..]);
@ -333,8 +333,8 @@ test "std.PriorityQueue: addSlice" {
test "std.PriorityQueue: fromOwnedSlice" {
const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
const heap_items = try std.mem.dupe(testing.allocator, u32, items[0..]);
var queue = PQ.fromOwnedSlice(testing.allocator, lessThan, heap_items[0..]);
const heap_items = try std.mem.dupe(testing.leak_count_allocator, u32, items[0..]);
var queue = PQ.fromOwnedSlice(testing.leak_count_allocator, lessThan, heap_items[0..]);
defer queue.deinit();
const sorted_items = [_]u32{ 1, 2, 5, 6, 7, 7, 11, 12, 13, 14, 15, 15, 16, 21, 22, 24, 24, 25 };
@ -344,7 +344,7 @@ test "std.PriorityQueue: fromOwnedSlice" {
}
test "std.PriorityQueue: add and remove max heap" {
var queue = PQ.init(testing.allocator, greaterThan);
var queue = PQ.init(testing.leak_count_allocator, greaterThan);
defer queue.deinit();
try queue.add(54);
@ -362,7 +362,7 @@ test "std.PriorityQueue: add and remove max heap" {
}
test "std.PriorityQueue: add and remove same max heap" {
var queue = PQ.init(testing.allocator, greaterThan);
var queue = PQ.init(testing.leak_count_allocator, greaterThan);
defer queue.deinit();
try queue.add(1);
@ -380,8 +380,8 @@ test "std.PriorityQueue: add and remove same max heap" {
}
test "std.PriorityQueue: iterator" {
var queue = PQ.init(testing.allocator, lessThan);
var map = std.AutoHashMap(u32, void).init(testing.allocator);
var queue = PQ.init(testing.leak_count_allocator, lessThan);
var map = std.AutoHashMap(u32, void).init(testing.leak_count_allocator);
defer {
queue.deinit();
map.deinit();
@ -402,7 +402,7 @@ test "std.PriorityQueue: iterator" {
}
test "std.PriorityQueue: remove at index" {
var queue = PQ.init(testing.allocator, lessThan);
var queue = PQ.init(testing.leak_count_allocator, lessThan);
defer queue.deinit();
try queue.add(3);

View File

@ -114,7 +114,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
}
test "os.getEnvMap" {
var env = try getEnvMap(std.testing.allocator);
var env = try getEnvMap(std.testing.leak_count_allocator);
defer env.deinit();
}
@ -165,7 +165,7 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
}
test "os.getEnvVarOwned" {
var ga = std.testing.allocator;
var ga = std.testing.leak_count_allocator;
testing.expectError(error.EnvironmentVariableNotFound, getEnvVarOwned(ga, "BADENV"));
}
@ -492,10 +492,11 @@ test "windows arg parsing" {
fn testWindowsCmdLine(input_cmd_line: [*]const u8, expected_args: []const []const u8) void {
var it = ArgIteratorWindows.initWithCmdLine(input_cmd_line);
for (expected_args) |expected_arg| {
const arg = it.next(std.testing.allocator).? catch unreachable;
const arg = it.next(std.testing.leak_count_allocator).? catch unreachable;
defer std.testing.leak_count_allocator.free(arg);
testing.expectEqualSlices(u8, expected_arg, arg);
}
testing.expect(it.next(std.testing.allocator) == null);
testing.expect(it.next(std.testing.leak_count_allocator) == null);
}
pub const UserInfo = struct {

View File

@ -14,6 +14,7 @@ pub fn main() anyerror!void {
for (test_fn_list) |test_fn, i| {
std.testing.allocator_instance.reset();
var test_node = root_node.start(test_fn.name, null);
test_node.activate();
progress.refresh();
@ -36,6 +37,8 @@ pub fn main() anyerror!void {
return err;
},
}
try std.testing.leak_count_allocator_instance.validate();
}
root_node.end();
if (ok_count == test_fn_list.len) {

View File

@ -7,6 +7,48 @@ pub const allocator = &allocator_instance.allocator;
pub var allocator_instance = std.heap.ThreadSafeFixedBufferAllocator.init(allocator_mem[0..]);
var allocator_mem: [100 * 1024]u8 = undefined;
pub const leak_count_allocator = &leak_count_allocator_instance.allocator;
pub var leak_count_allocator_instance = LeakCountAllocator.init(allocator);
const LeakCountAllocator = struct {
count: usize,
allocator: std.mem.Allocator,
internal_allocator: *std.mem.Allocator,
fn init(allo: *std.mem.Allocator) LeakCountAllocator {
return .{
.count = 0,
.allocator = .{
.reallocFn = realloc,
.shrinkFn = shrink,
},
.internal_allocator = allo,
};
}
fn realloc(allo: *std.mem.Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
const self = @fieldParentPtr(LeakCountAllocator, "allocator", allo);
if (old_mem.len == 0) {
self.count += 1;
}
return self.internal_allocator.reallocFn(self.internal_allocator, old_mem, old_align, new_size, new_align);
}
fn shrink(allo: *std.mem.Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
const self = @fieldParentPtr(LeakCountAllocator, "allocator", allo);
if (new_size == 0) {
self.count -= 1;
}
return self.internal_allocator.shrinkFn(self.internal_allocator, old_mem, old_align, new_size, new_align);
}
fn validate(self: LeakCountAllocator) !void {
if (self.count > 0) {
std.debug.warn("Detected leaked allocations without matching free: {}\n", .{self.count});
return error.Leak;
}
}
};
/// This function is intended to be used only in tests. It prints diagnostics to stderr
/// and then aborts when actual_error_union is not expected_error.
pub fn expectError(expected_error: anyerror, actual_error_union: var) void {

View File

@ -501,14 +501,16 @@ test "utf16leToUtf8" {
{
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A');
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 'a');
const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
defer std.testing.leak_count_allocator.free(utf8);
testing.expect(mem.eql(u8, utf8, "Aa"));
}
{
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0x80);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xffff);
const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
defer std.testing.leak_count_allocator.free(utf8);
testing.expect(mem.eql(u8, utf8, "\xc2\x80" ++ "\xef\xbf\xbf"));
}
@ -516,7 +518,8 @@ test "utf16leToUtf8" {
// the values just outside the surrogate half range
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd7ff);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xe000);
const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
defer std.testing.leak_count_allocator.free(utf8);
testing.expect(mem.eql(u8, utf8, "\xed\x9f\xbf" ++ "\xee\x80\x80"));
}
@ -524,7 +527,8 @@ test "utf16leToUtf8" {
// smallest surrogate pair
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd800);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00);
const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
defer std.testing.leak_count_allocator.free(utf8);
testing.expect(mem.eql(u8, utf8, "\xf0\x90\x80\x80"));
}
@ -532,14 +536,16 @@ test "utf16leToUtf8" {
// largest surrogate pair
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdfff);
const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
defer std.testing.leak_count_allocator.free(utf8);
testing.expect(mem.eql(u8, utf8, "\xf4\x8f\xbf\xbf"));
}
{
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00);
const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
defer std.testing.leak_count_allocator.free(utf8);
testing.expect(mem.eql(u8, utf8, "\xf4\x8f\xb0\x80"));
}
}

View File

@ -2287,7 +2287,7 @@ pub const Node = struct {
test "iterate" {
var root = Node.Root{
.base = Node{ .id = Node.Id.Root },
.decls = Node.Root.DeclList.init(std.testing.allocator),
.decls = Node.Root.DeclList.init(std.testing.leak_count_allocator),
.eof_token = 0,
};
var base = &root.base;

View File

@ -445,7 +445,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std");
\\const io = std.io;
\\const os = std.os;
\\const allocator = std.testing.allocator;
\\const allocator = std.testing.leak_count_allocator;
\\
\\pub fn main() !void {
\\ var args_it = std.process.args();
@ -486,7 +486,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std");
\\const io = std.io;
\\const os = std.os;
\\const allocator = std.testing.allocator;
\\const allocator = std.testing.leak_count_allocator;
\\
\\pub fn main() !void {
\\ var args_it = std.process.args();

View File

@ -5765,7 +5765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\
\\export fn entry() void {
\\ const a = MdNode.Header {
\\ .text = MdText.init(&std.testing.allocator),
\\ .text = MdText.init(&std.testing.leak_count_allocator),
\\ .weight = HeaderWeight.H1,
\\ };
\\}

View File

@ -22,7 +22,7 @@ fn foo(args: [][]const u8) void {
}
fn bar(argc: usize) void {
const args = testing.allocator.alloc([]const u8, argc) catch unreachable;
const args = testing.leak_count_allocator.alloc([]const u8, argc) catch unreachable;
for (args) |_, i| {
const ptr = argv[i];
args[i] = ptr[0..strlen(ptr)];

View File

@ -201,7 +201,7 @@ pub fn main() !void {
}
test "invalid inputs" {
global_allocator = std.testing.allocator;
global_allocator = std.testing.leak_count_allocator;
expectError("}ABC", error.InvalidInput);
expectError("{ABC", error.InvalidInput);
@ -222,7 +222,7 @@ fn expectError(test_input: []const u8, expected_err: anyerror) void {
}
test "valid inputs" {
global_allocator = std.testing.allocator;
global_allocator = std.testing.leak_count_allocator;
expectExpansion("{x,y,z}", "x y z");
expectExpansion("{A,B}{x,y}", "Ax Ay Bx By");

View File

@ -4,7 +4,7 @@ const process = std.process;
const fs = std.fs;
const mem = std.mem;
const warn = std.debug.warn;
const allocator = std.testing.allocator;
const allocator = std.testing.leak_count_allocator;
pub fn main() !void {
var args_it = process.args();

View File

@ -1,6 +1,6 @@
const std = @import("std");
pub fn main() void {
const env_map = std.process.getEnvMap(std.testing.allocator) catch @panic("unable to get env map");
const env_map = std.process.getEnvMap(std.testing.leak_count_allocator) catch @panic("unable to get env map");
std.testing.expect(env_map.count() == 0);
}

View File

@ -1,8 +1,8 @@
const std = @import("std");
pub fn main() !void {
const args = try std.process.argsAlloc(std.testing.allocator);
defer std.process.argsFree(std.testing.allocator, args);
const args = try std.process.argsAlloc(std.testing.leak_count_allocator);
defer std.process.argsFree(std.testing.leak_count_allocator, args);
const dynlib_name = args[1];