authorgravatar for benjamin.feng@glassdoor.comBenjamin Feng <benjamin.feng@glassdoor.com> 2020-01-29 13:18:04-06:00
committergravatar for benjamin.feng@glassdoor.comBenjamin Feng <benjamin.feng@glassdoor.com> 2020-01-29 14:37:01-06:00
logaa9caf5064b3fc01579b7bd8c765ff33323a073a
tree1072a5e6fe39957fd2fdb37f4816799ecf9a627b
parent4d134a01f5a8baae346783f19d9b5db8c8256d32

Create leak_count_allocator


22 files changed, 208 insertions(+), 137 deletions(-)

doc/docgen.zig+1-1
......@@ -672,7 +672,7 @@ const TermState = enum {
672672
673673test "term color" {
674674 const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
675 const result = try termColor(std.testing.allocator, input_bytes);
675 const result = try termColor(std.testing.leak_count_allocator, input_bytes);
676676 testing.expectEqualSlices(u8, "A<span class=\"t32\">green</span>B", result);
677677}
678678
lib/std/array_list.zig+8-7
......@@ -320,7 +320,7 @@ test "std.ArrayList.basic" {
320320}
321321
322322test "std.ArrayList.orderedRemove" {
323 var list = ArrayList(i32).init(testing.allocator);
323 var list = ArrayList(i32).init(testing.leak_count_allocator);
324324 defer list.deinit();
325325
326326 try list.append(1);
......@@ -347,7 +347,7 @@ test "std.ArrayList.orderedRemove" {
347347}
348348
349349test "std.ArrayList.swapRemove" {
350 var list = ArrayList(i32).init(testing.allocator);
350 var list = ArrayList(i32).init(testing.leak_count_allocator);
351351 defer list.deinit();
352352
353353 try list.append(1);
......@@ -374,7 +374,7 @@ test "std.ArrayList.swapRemove" {
374374}
375375
376376test "std.ArrayList.swapRemoveOrError" {
377 var list = ArrayList(i32).init(testing.allocator);
377 var list = ArrayList(i32).init(testing.leak_count_allocator);
378378 defer list.deinit();
379379
380380 // Test just after initialization
......@@ -402,7 +402,7 @@ test "std.ArrayList.swapRemoveOrError" {
402402}
403403
404404test "std.ArrayList.insert" {
405 var list = ArrayList(i32).init(testing.allocator);
405 var list = ArrayList(i32).init(testing.leak_count_allocator);
406406 defer list.deinit();
407407
408408 try list.append(1);
......@@ -416,7 +416,7 @@ test "std.ArrayList.insert" {
416416}
417417
418418test "std.ArrayList.insertSlice" {
419 var list = ArrayList(i32).init(testing.allocator);
419 var list = ArrayList(i32).init(testing.leak_count_allocator);
420420 defer list.deinit();
421421
422422 try list.append(1);
......@@ -443,7 +443,8 @@ const Item = struct {
443443};
444444
445445test "std.ArrayList: ArrayList(T) of struct T" {
446 var root = Item{ .integer = 1, .sub_items = ArrayList(Item).init(testing.allocator) };
447 try root.sub_items.append(Item{ .integer = 42, .sub_items = ArrayList(Item).init(testing.allocator) });
446 var root = Item{ .integer = 1, .sub_items = ArrayList(Item).init(testing.leak_count_allocator) };
447 defer root.sub_items.deinit();
448 try root.sub_items.append(Item{ .integer = 42, .sub_items = ArrayList(Item).init(testing.leak_count_allocator) });
448449 testing.expect(root.sub_items.items[0].integer == 42);
449450}
lib/std/buffer.zig+8-3
......@@ -150,7 +150,9 @@ pub const Buffer = struct {
150150};
151151
152152test "simple Buffer" {
153 var buf = try Buffer.init(testing.allocator, "");
153 var buf = try Buffer.init(testing.leak_count_allocator, "");
154 defer buf.deinit();
155
154156 testing.expect(buf.len() == 0);
155157 try buf.append("hello");
156158 try buf.append(" ");
......@@ -159,6 +161,7 @@ test "simple Buffer" {
159161 testing.expect(mem.eql(u8, mem.toSliceConst(u8, buf.toSliceConst().ptr), buf.toSliceConst()));
160162
161163 var buf2 = try Buffer.initFromBuffer(buf);
164 defer buf2.deinit();
162165 testing.expect(buf.eql(buf2.toSliceConst()));
163166
164167 testing.expect(buf.startsWith("hell"));
......@@ -169,14 +172,16 @@ test "simple Buffer" {
169172}
170173
171174test "Buffer.initSize" {
172 var buf = try Buffer.initSize(testing.allocator, 3);
175 var buf = try Buffer.initSize(testing.leak_count_allocator, 3);
176 defer buf.deinit();
173177 testing.expect(buf.len() == 3);
174178 try buf.append("hello");
175179 testing.expect(mem.eql(u8, buf.toSliceConst()[3..], "hello"));
176180}
177181
178182test "Buffer.initCapacity" {
179 var buf = try Buffer.initCapacity(testing.allocator, 10);
183 var buf = try Buffer.initCapacity(testing.leak_count_allocator, 10);
184 defer buf.deinit();
180185 testing.expect(buf.len() == 0);
181186 testing.expect(buf.capacity() >= 10);
182187 const old_cap = buf.capacity();
lib/std/debug.zig+1-1
......@@ -2193,7 +2193,7 @@ fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool)
21932193}
21942194
21952195pub const global_allocator = blk: {
2196 @compileError("Please switch to std.testing.allocator.");
2196 @compileError("Please switch to std.testing.leak_count_allocator.");
21972197};
21982198var global_fixed_allocator = std.heap.ThreadSafeFixedBufferAllocator.init(global_allocator_mem[0..]);
21992199var global_allocator_mem: [100 * 1024]u8 = undefined;
lib/std/fifo.zig+2-2
......@@ -347,7 +347,7 @@ pub fn LinearFifo(
347347}
348348
349349test "LinearFifo(u8, .Dynamic)" {
350 var fifo = LinearFifo(u8, .Dynamic).init(testing.allocator);
350 var fifo = LinearFifo(u8, .Dynamic).init(testing.leak_count_allocator);
351351 defer fifo.deinit();
352352
353353 try fifo.write("HELLO");
......@@ -422,7 +422,7 @@ test "LinearFifo" {
422422 var fifo = switch (bt) {
423423 .Static => FifoType.init(),
424424 .Slice => FifoType.init(buf[0..]),
425 .Dynamic => FifoType.init(testing.allocator),
425 .Dynamic => FifoType.init(testing.leak_count_allocator),
426426 };
427427 defer fifo.deinit();
428428
lib/std/fmt.zig+10-5
......@@ -1598,7 +1598,8 @@ test "hexToBytes" {
15981598test "formatIntValue with comptime_int" {
15991599 const value: comptime_int = 123456789123456789;
16001600
1601 var buf = try std.Buffer.init(std.testing.allocator, "");
1601 var buf = try std.Buffer.init(std.testing.leak_count_allocator, "");
1602 defer buf.deinit();
16021603 try formatIntValue(value, "", FormatOptions{}, &buf, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append);
16031604 std.testing.expect(mem.eql(u8, buf.toSlice(), "123456789123456789"));
16041605}
......@@ -1652,19 +1653,23 @@ test "formatType max_depth" {
16521653 inst.a = &inst;
16531654 inst.tu.ptr = &inst.tu;
16541655
1655 var buf0 = try std.Buffer.init(std.testing.allocator, "");
1656 var buf0 = try std.Buffer.init(std.testing.leak_count_allocator, "");
1657 defer buf0.deinit();
16561658 try formatType(inst, "", FormatOptions{}, &buf0, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 0);
16571659 std.testing.expect(mem.eql(u8, buf0.toSlice(), "S{ ... }"));
16581660
1659 var buf1 = try std.Buffer.init(std.testing.allocator, "");
1661 var buf1 = try std.Buffer.init(std.testing.leak_count_allocator, "");
1662 defer buf1.deinit();
16601663 try formatType(inst, "", FormatOptions{}, &buf1, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 1);
16611664 std.testing.expect(mem.eql(u8, buf1.toSlice(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }"));
16621665
1663 var buf2 = try std.Buffer.init(std.testing.allocator, "");
1666 var buf2 = try std.Buffer.init(std.testing.leak_count_allocator, "");
1667 defer buf2.deinit();
16641668 try formatType(inst, "", FormatOptions{}, &buf2, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 2);
16651669 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) }"));
16661670
1667 var buf3 = try std.Buffer.init(std.testing.allocator, "");
1671 var buf3 = try std.Buffer.init(std.testing.leak_count_allocator, "");
1672 defer buf3.deinit();
16681673 try formatType(inst, "", FormatOptions{}, &buf3, @TypeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 3);
16691674 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) }"));
16701675}
lib/std/fs/path.zig+87-79
......@@ -665,15 +665,16 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
665665}
666666
667667test "resolve" {
668 const cwd = try process.getCwdAlloc(testing.allocator);
668 const cwd = try process.getCwdAlloc(testing.leak_count_allocator);
669 defer testing.leak_count_allocator.free(cwd);
669670 if (builtin.os == .windows) {
670671 if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {
671672 cwd[0] = asciiUpper(cwd[0]);
672673 }
673 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{"."}), cwd));
674 try testResolveWindows(&[_][]const u8{"."}, cwd);
674675 } else {
675 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "a/b/c/", "../../.." }), cwd));
676 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{"."}), cwd));
676 try testResolvePosix(&[_][]const u8{ "a/b/c/", "../../.." }, cwd);
677 try testResolvePosix(&[_][]const u8{"."}, cwd);
677678 }
678679}
679680
......@@ -683,66 +684,71 @@ test "resolveWindows" {
683684 return error.SkipZigTest;
684685 }
685686 if (builtin.os == .windows) {
686 const cwd = try process.getCwdAlloc(testing.allocator);
687 const cwd = try process.getCwdAlloc(testing.leak_count_allocator);
688 defer testing.leak_count_allocator.free(cwd);
687689 const parsed_cwd = windowsParsePath(cwd);
688690 {
689 const result = testResolveWindows(&[_][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" });
690 const expected = try join(testing.allocator, &[_][]const u8{
691 const expected = try join(testing.leak_count_allocator, &[_][]const u8{
691692 parsed_cwd.disk_designator,
692693 "usr\\local\\lib\\zig\\std\\array_list.zig",
693694 });
695 defer testing.leak_count_allocator.free(expected);
694696 if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
695697 expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
696698 }
697 testing.expect(mem.eql(u8, result, expected));
699 try testResolveWindows(&[_][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" }, expected);
698700 }
699701 {
700 const result = testResolveWindows(&[_][]const u8{ "usr/local", "lib\\zig" });
701 const expected = try join(testing.allocator, &[_][]const u8{
702 const expected = try join(testing.leak_count_allocator, &[_][]const u8{
702703 cwd,
703704 "usr\\local\\lib\\zig",
704705 });
706 defer testing.leak_count_allocator.free(expected);
705707 if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
706708 expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
707709 }
708 testing.expect(mem.eql(u8, result, expected));
710 try testResolveWindows(&[_][]const u8{ "usr/local", "lib\\zig" }, expected);
709711 }
710712 }
711713
712 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }), "C:\\hi\\ok"));
713 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }), "C:\\blah\\a"));
714 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "C:../a" }), "C:\\blah\\a"));
715 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/ignore", "d:\\a/b\\c/d", "\\e.exe" }), "D:\\e.exe"));
716 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/ignore", "c:/some/file" }), "C:\\some\\file"));
717 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "d:/ignore", "d:some/dir//" }), "D:\\ignore\\some\\dir"));
718 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "//server/share", "..", "relative\\" }), "\\\\server\\share\\relative"));
719 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//" }), "C:\\"));
720 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//dir" }), "C:\\dir"));
721 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//server/share" }), "\\\\server\\share\\"));
722 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//server//share" }), "\\\\server\\share\\"));
723 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "///some//dir" }), "C:\\some\\dir"));
724 testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }), "C:\\foo\\tmp.3\\cycles\\root.js"));
714 try testResolveWindows(&[_][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }, "C:\\hi\\ok");
715 try testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }, "C:\\blah\\a");
716 try testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "C:../a" }, "C:\\blah\\a");
717 try testResolveWindows(&[_][]const u8{ "c:/ignore", "d:\\a/b\\c/d", "\\e.exe" }, "D:\\e.exe");
718 try testResolveWindows(&[_][]const u8{ "c:/ignore", "c:/some/file" }, "C:\\some\\file");
719 try testResolveWindows(&[_][]const u8{ "d:/ignore", "d:some/dir//" }, "D:\\ignore\\some\\dir");
720 try testResolveWindows(&[_][]const u8{ "//server/share", "..", "relative\\" }, "\\\\server\\share\\relative");
721 try testResolveWindows(&[_][]const u8{ "c:/", "//" }, "C:\\");
722 try testResolveWindows(&[_][]const u8{ "c:/", "//dir" }, "C:\\dir");
723 try testResolveWindows(&[_][]const u8{ "c:/", "//server/share" }, "\\\\server\\share\\");
724 try testResolveWindows(&[_][]const u8{ "c:/", "//server//share" }, "\\\\server\\share\\");
725 try testResolveWindows(&[_][]const u8{ "c:/", "///some//dir" }, "C:\\some\\dir");
726 try testResolveWindows(&[_][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }, "C:\\foo\\tmp.3\\cycles\\root.js");
725727}
726728
727729test "resolvePosix" {
728 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/a/b", "c" }), "/a/b/c"));
729 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/a/b", "c", "//d", "e///" }), "/d/e"));
730 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/a/b/c", "..", "../" }), "/a"));
731 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/", "..", ".." }), "/"));
732 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{"/a/b/c/"}), "/a/b/c"));
733
734 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/var/lib", "../", "file/" }), "/var/file"));
735 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/var/lib", "/../", "file/" }), "/file"));
736 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/some/dir", ".", "/absolute/" }), "/absolute"));
737 testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }), "/foo/tmp.3/cycles/root.js"));
730 try testResolvePosix(&[_][]const u8{ "/a/b", "c" }, "/a/b/c");
731 try testResolvePosix(&[_][]const u8{ "/a/b", "c", "//d", "e///" }, "/d/e");
732 try testResolvePosix(&[_][]const u8{ "/a/b/c", "..", "../" }, "/a");
733 try testResolvePosix(&[_][]const u8{ "/", "..", ".." }, "/");
734 try testResolvePosix(&[_][]const u8{"/a/b/c/"}, "/a/b/c");
735
736 try testResolvePosix(&[_][]const u8{ "/var/lib", "../", "file/" }, "/var/file");
737 try testResolvePosix(&[_][]const u8{ "/var/lib", "/../", "file/" }, "/file");
738 try testResolvePosix(&[_][]const u8{ "/some/dir", ".", "/absolute/" }, "/absolute");
739 try testResolvePosix(&[_][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }, "/foo/tmp.3/cycles/root.js");
738740}
739741
740fn testResolveWindows(paths: []const []const u8) []u8 {
741 return resolveWindows(testing.allocator, paths) catch unreachable;
742fn testResolveWindows(paths: []const []const u8, expected: []const u8) !void {
743 const actual = try resolveWindows(testing.leak_count_allocator, paths);
744 defer testing.leak_count_allocator.free(actual);
745 return testing.expect(mem.eql(u8, actual, expected));
742746}
743747
744fn testResolvePosix(paths: []const []const u8) []u8 {
745 return resolvePosix(testing.allocator, paths) catch unreachable;
748fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void {
749 const actual = try resolvePosix(testing.leak_count_allocator, paths);
750 defer testing.leak_count_allocator.free(actual);
751 return testing.expect(mem.eql(u8, actual, expected));
746752}
747753
748754/// If the path is a file in the current directory (no directory component)
......@@ -1126,51 +1132,53 @@ test "relative" {
11261132 // TODO https://github.com/ziglang/zig/issues/3288
11271133 return error.SkipZigTest;
11281134 }
1129 testRelativeWindows("c:/blah\\blah", "d:/games", "D:\\games");
1130 testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa", "..");
1131 testRelativeWindows("c:/aaaa/bbbb", "c:/cccc", "..\\..\\cccc");
1132 testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa/bbbb", "");
1133 testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa/cccc", "..\\cccc");
1134 testRelativeWindows("c:/aaaa/", "c:/aaaa/cccc", "cccc");
1135 testRelativeWindows("c:/", "c:\\aaaa\\bbbb", "aaaa\\bbbb");
1136 testRelativeWindows("c:/aaaa/bbbb", "d:\\", "D:\\");
1137 testRelativeWindows("c:/AaAa/bbbb", "c:/aaaa/bbbb", "");
1138 testRelativeWindows("c:/aaaaa/", "c:/aaaa/cccc", "..\\aaaa\\cccc");
1139 testRelativeWindows("C:\\foo\\bar\\baz\\quux", "C:\\", "..\\..\\..\\..");
1140 testRelativeWindows("C:\\foo\\test", "C:\\foo\\test\\bar\\package.json", "bar\\package.json");
1141 testRelativeWindows("C:\\foo\\bar\\baz-quux", "C:\\foo\\bar\\baz", "..\\baz");
1142 testRelativeWindows("C:\\foo\\bar\\baz", "C:\\foo\\bar\\baz-quux", "..\\baz-quux");
1143 testRelativeWindows("\\\\foo\\bar", "\\\\foo\\bar\\baz", "baz");
1144 testRelativeWindows("\\\\foo\\bar\\baz", "\\\\foo\\bar", "..");
1145 testRelativeWindows("\\\\foo\\bar\\baz-quux", "\\\\foo\\bar\\baz", "..\\baz");
1146 testRelativeWindows("\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz-quux", "..\\baz-quux");
1147 testRelativeWindows("C:\\baz-quux", "C:\\baz", "..\\baz");
1148 testRelativeWindows("C:\\baz", "C:\\baz-quux", "..\\baz-quux");
1149 testRelativeWindows("\\\\foo\\baz-quux", "\\\\foo\\baz", "..\\baz");
1150 testRelativeWindows("\\\\foo\\baz", "\\\\foo\\baz-quux", "..\\baz-quux");
1151 testRelativeWindows("C:\\baz", "\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz");
1152 testRelativeWindows("\\\\foo\\bar\\baz", "C:\\baz", "C:\\baz");
1153
1154 testRelativePosix("/var/lib", "/var", "..");
1155 testRelativePosix("/var/lib", "/bin", "../../bin");
1156 testRelativePosix("/var/lib", "/var/lib", "");
1157 testRelativePosix("/var/lib", "/var/apache", "../apache");
1158 testRelativePosix("/var/", "/var/lib", "lib");
1159 testRelativePosix("/", "/var/lib", "var/lib");
1160 testRelativePosix("/foo/test", "/foo/test/bar/package.json", "bar/package.json");
1161 testRelativePosix("/Users/a/web/b/test/mails", "/Users/a/web/b", "../..");
1162 testRelativePosix("/foo/bar/baz-quux", "/foo/bar/baz", "../baz");
1163 testRelativePosix("/foo/bar/baz", "/foo/bar/baz-quux", "../baz-quux");
1164 testRelativePosix("/baz-quux", "/baz", "../baz");
1165 testRelativePosix("/baz", "/baz-quux", "../baz-quux");
1135 try testRelativeWindows("c:/blah\\blah", "d:/games", "D:\\games");
1136 try testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa", "..");
1137 try testRelativeWindows("c:/aaaa/bbbb", "c:/cccc", "..\\..\\cccc");
1138 try testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa/bbbb", "");
1139 try testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa/cccc", "..\\cccc");
1140 try testRelativeWindows("c:/aaaa/", "c:/aaaa/cccc", "cccc");
1141 try testRelativeWindows("c:/", "c:\\aaaa\\bbbb", "aaaa\\bbbb");
1142 try testRelativeWindows("c:/aaaa/bbbb", "d:\\", "D:\\");
1143 try testRelativeWindows("c:/AaAa/bbbb", "c:/aaaa/bbbb", "");
1144 try testRelativeWindows("c:/aaaaa/", "c:/aaaa/cccc", "..\\aaaa\\cccc");
1145 try testRelativeWindows("C:\\foo\\bar\\baz\\quux", "C:\\", "..\\..\\..\\..");
1146 try testRelativeWindows("C:\\foo\\test", "C:\\foo\\test\\bar\\package.json", "bar\\package.json");
1147 try testRelativeWindows("C:\\foo\\bar\\baz-quux", "C:\\foo\\bar\\baz", "..\\baz");
1148 try testRelativeWindows("C:\\foo\\bar\\baz", "C:\\foo\\bar\\baz-quux", "..\\baz-quux");
1149 try testRelativeWindows("\\\\foo\\bar", "\\\\foo\\bar\\baz", "baz");
1150 try testRelativeWindows("\\\\foo\\bar\\baz", "\\\\foo\\bar", "..");
1151 try testRelativeWindows("\\\\foo\\bar\\baz-quux", "\\\\foo\\bar\\baz", "..\\baz");
1152 try testRelativeWindows("\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz-quux", "..\\baz-quux");
1153 try testRelativeWindows("C:\\baz-quux", "C:\\baz", "..\\baz");
1154 try testRelativeWindows("C:\\baz", "C:\\baz-quux", "..\\baz-quux");
1155 try testRelativeWindows("\\\\foo\\baz-quux", "\\\\foo\\baz", "..\\baz");
1156 try testRelativeWindows("\\\\foo\\baz", "\\\\foo\\baz-quux", "..\\baz-quux");
1157 try testRelativeWindows("C:\\baz", "\\\\foo\\bar\\baz", "\\\\foo\\bar\\baz");
1158 try testRelativeWindows("\\\\foo\\bar\\baz", "C:\\baz", "C:\\baz");
1159
1160 try testRelativePosix("/var/lib", "/var", "..");
1161 try testRelativePosix("/var/lib", "/bin", "../../bin");
1162 try testRelativePosix("/var/lib", "/var/lib", "");
1163 try testRelativePosix("/var/lib", "/var/apache", "../apache");
1164 try testRelativePosix("/var/", "/var/lib", "lib");
1165 try testRelativePosix("/", "/var/lib", "var/lib");
1166 try testRelativePosix("/foo/test", "/foo/test/bar/package.json", "bar/package.json");
1167 try testRelativePosix("/Users/a/web/b/test/mails", "/Users/a/web/b", "../..");
1168 try testRelativePosix("/foo/bar/baz-quux", "/foo/bar/baz", "../baz");
1169 try testRelativePosix("/foo/bar/baz", "/foo/bar/baz-quux", "../baz-quux");
1170 try testRelativePosix("/baz-quux", "/baz", "../baz");
1171 try testRelativePosix("/baz", "/baz-quux", "../baz-quux");
11661172}
11671173
1168fn testRelativePosix(from: []const u8, to: []const u8, expected_output: []const u8) void {
1169 const result = relativePosix(testing.allocator, from, to) catch unreachable;
1174fn testRelativePosix(from: []const u8, to: []const u8, expected_output: []const u8) !void {
1175 const result = try relativePosix(testing.leak_count_allocator, from, to);
1176 defer testing.leak_count_allocator.free(result);
11701177 testing.expectEqualSlices(u8, expected_output, result);
11711178}
11721179
1173fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []const u8) void {
1174 const result = relativeWindows(testing.allocator, from, to) catch unreachable;
1180fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []const u8) !void {
1181 const result = try relativeWindows(testing.leak_count_allocator, from, to);
1182 defer testing.leak_count_allocator.free(result);
11751183 testing.expectEqualSlices(u8, expected_output, result);
11761184}
lib/std/linked_list.zig+3-3
......@@ -143,7 +143,7 @@ pub fn SinglyLinkedList(comptime T: type) type {
143143}
144144
145145test "basic SinglyLinkedList test" {
146 const allocator = testing.allocator;
146 const allocator = testing.leak_count_allocator;
147147 var list = SinglyLinkedList(u32).init();
148148
149149 var one = try list.createNode(1, allocator);
......@@ -404,7 +404,7 @@ pub fn TailQueue(comptime T: type) type {
404404}
405405
406406test "basic TailQueue test" {
407 const allocator = testing.allocator;
407 const allocator = testing.leak_count_allocator;
408408 var list = TailQueue(u32).init();
409409
410410 var one = try list.createNode(1, allocator);
......@@ -456,7 +456,7 @@ test "basic TailQueue test" {
456456}
457457
458458test "TailQueue concatenation" {
459 const allocator = testing.allocator;
459 const allocator = testing.leak_count_allocator;
460460 var list1 = TailQueue(u32).init();
461461 var list2 = TailQueue(u32).init();
462462
lib/std/os/test.zig+1-1
......@@ -9,7 +9,7 @@ const elf = std.elf;
99const File = std.fs.File;
1010const Thread = std.Thread;
1111
12const a = std.testing.allocator;
12const a = std.testing.leak_count_allocator;
1313
1414const builtin = @import("builtin");
1515const AtomicRmwOp = builtin.AtomicRmwOp;
lib/std/priority_queue.zig+14-14
......@@ -239,7 +239,7 @@ fn greaterThan(a: u32, b: u32) bool {
239239const PQ = PriorityQueue(u32);
240240
241241test "std.PriorityQueue: add and remove min heap" {
242 var queue = PQ.init(testing.allocator, lessThan);
242 var queue = PQ.init(testing.leak_count_allocator, lessThan);
243243 defer queue.deinit();
244244
245245 try queue.add(54);
......@@ -257,7 +257,7 @@ test "std.PriorityQueue: add and remove min heap" {
257257}
258258
259259test "std.PriorityQueue: add and remove same min heap" {
260 var queue = PQ.init(testing.allocator, lessThan);
260 var queue = PQ.init(testing.leak_count_allocator, lessThan);
261261 defer queue.deinit();
262262
263263 try queue.add(1);
......@@ -275,14 +275,14 @@ test "std.PriorityQueue: add and remove same min heap" {
275275}
276276
277277test "std.PriorityQueue: removeOrNull on empty" {
278 var queue = PQ.init(testing.allocator, lessThan);
278 var queue = PQ.init(testing.leak_count_allocator, lessThan);
279279 defer queue.deinit();
280280
281281 expect(queue.removeOrNull() == null);
282282}
283283
284284test "std.PriorityQueue: edge case 3 elements" {
285 var queue = PQ.init(testing.allocator, lessThan);
285 var queue = PQ.init(testing.leak_count_allocator, lessThan);
286286 defer queue.deinit();
287287
288288 try queue.add(9);
......@@ -294,7 +294,7 @@ test "std.PriorityQueue: edge case 3 elements" {
294294}
295295
296296test "std.PriorityQueue: peek" {
297 var queue = PQ.init(testing.allocator, lessThan);
297 var queue = PQ.init(testing.leak_count_allocator, lessThan);
298298 defer queue.deinit();
299299
300300 expect(queue.peek() == null);
......@@ -306,7 +306,7 @@ test "std.PriorityQueue: peek" {
306306}
307307
308308test "std.PriorityQueue: sift up with odd indices" {
309 var queue = PQ.init(testing.allocator, lessThan);
309 var queue = PQ.init(testing.leak_count_allocator, lessThan);
310310 defer queue.deinit();
311311 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
312312 for (items) |e| {
......@@ -320,7 +320,7 @@ test "std.PriorityQueue: sift up with odd indices" {
320320}
321321
322322test "std.PriorityQueue: addSlice" {
323 var queue = PQ.init(testing.allocator, lessThan);
323 var queue = PQ.init(testing.leak_count_allocator, lessThan);
324324 defer queue.deinit();
325325 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
326326 try queue.addSlice(items[0..]);
......@@ -333,8 +333,8 @@ test "std.PriorityQueue: addSlice" {
333333
334334test "std.PriorityQueue: fromOwnedSlice" {
335335 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
336 const heap_items = try std.mem.dupe(testing.allocator, u32, items[0..]);
337 var queue = PQ.fromOwnedSlice(testing.allocator, lessThan, heap_items[0..]);
336 const heap_items = try std.mem.dupe(testing.leak_count_allocator, u32, items[0..]);
337 var queue = PQ.fromOwnedSlice(testing.leak_count_allocator, lessThan, heap_items[0..]);
338338 defer queue.deinit();
339339
340340 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" {
344344}
345345
346346test "std.PriorityQueue: add and remove max heap" {
347 var queue = PQ.init(testing.allocator, greaterThan);
347 var queue = PQ.init(testing.leak_count_allocator, greaterThan);
348348 defer queue.deinit();
349349
350350 try queue.add(54);
......@@ -362,7 +362,7 @@ test "std.PriorityQueue: add and remove max heap" {
362362}
363363
364364test "std.PriorityQueue: add and remove same max heap" {
365 var queue = PQ.init(testing.allocator, greaterThan);
365 var queue = PQ.init(testing.leak_count_allocator, greaterThan);
366366 defer queue.deinit();
367367
368368 try queue.add(1);
......@@ -380,8 +380,8 @@ test "std.PriorityQueue: add and remove same max heap" {
380380}
381381
382382test "std.PriorityQueue: iterator" {
383 var queue = PQ.init(testing.allocator, lessThan);
384 var map = std.AutoHashMap(u32, void).init(testing.allocator);
383 var queue = PQ.init(testing.leak_count_allocator, lessThan);
384 var map = std.AutoHashMap(u32, void).init(testing.leak_count_allocator);
385385 defer {
386386 queue.deinit();
387387 map.deinit();
......@@ -402,7 +402,7 @@ test "std.PriorityQueue: iterator" {
402402}
403403
404404test "std.PriorityQueue: remove at index" {
405 var queue = PQ.init(testing.allocator, lessThan);
405 var queue = PQ.init(testing.leak_count_allocator, lessThan);
406406 defer queue.deinit();
407407
408408 try queue.add(3);
lib/std/process.zig+5-4
......@@ -114,7 +114,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
114114}
115115
116116test "os.getEnvMap" {
117 var env = try getEnvMap(std.testing.allocator);
117 var env = try getEnvMap(std.testing.leak_count_allocator);
118118 defer env.deinit();
119119}
120120
......@@ -165,7 +165,7 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
165165}
166166
167167test "os.getEnvVarOwned" {
168 var ga = std.testing.allocator;
168 var ga = std.testing.leak_count_allocator;
169169 testing.expectError(error.EnvironmentVariableNotFound, getEnvVarOwned(ga, "BADENV"));
170170}
171171
......@@ -492,10 +492,11 @@ test "windows arg parsing" {
492492fn testWindowsCmdLine(input_cmd_line: [*]const u8, expected_args: []const []const u8) void {
493493 var it = ArgIteratorWindows.initWithCmdLine(input_cmd_line);
494494 for (expected_args) |expected_arg| {
495 const arg = it.next(std.testing.allocator).? catch unreachable;
495 const arg = it.next(std.testing.leak_count_allocator).? catch unreachable;
496 defer std.testing.leak_count_allocator.free(arg);
496497 testing.expectEqualSlices(u8, expected_arg, arg);
497498 }
498 testing.expect(it.next(std.testing.allocator) == null);
499 testing.expect(it.next(std.testing.leak_count_allocator) == null);
499500}
500501
501502pub const UserInfo = struct {
lib/std/special/test_runner.zig+3
......@@ -14,6 +14,7 @@ pub fn main() anyerror!void {
1414
1515 for (test_fn_list) |test_fn, i| {
1616 std.testing.allocator_instance.reset();
17
1718 var test_node = root_node.start(test_fn.name, null);
1819 test_node.activate();
1920 progress.refresh();
......@@ -36,6 +37,8 @@ pub fn main() anyerror!void {
3637 return err;
3738 },
3839 }
40
41 try std.testing.leak_count_allocator_instance.validate();
3942 }
4043 root_node.end();
4144 if (ok_count == test_fn_list.len) {
lib/std/testing.zig+42
......@@ -7,6 +7,48 @@ pub const allocator = &allocator_instance.allocator;
77pub var allocator_instance = std.heap.ThreadSafeFixedBufferAllocator.init(allocator_mem[0..]);
88var allocator_mem: [100 * 1024]u8 = undefined;
99
10pub const leak_count_allocator = &leak_count_allocator_instance.allocator;
11pub var leak_count_allocator_instance = LeakCountAllocator.init(allocator);
12const LeakCountAllocator = struct {
13 count: usize,
14 allocator: std.mem.Allocator,
15 internal_allocator: *std.mem.Allocator,
16
17 fn init(allo: *std.mem.Allocator) LeakCountAllocator {
18 return .{
19 .count = 0,
20 .allocator = .{
21 .reallocFn = realloc,
22 .shrinkFn = shrink,
23 },
24 .internal_allocator = allo,
25 };
26 }
27
28 fn realloc(allo: *std.mem.Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
29 const self = @fieldParentPtr(LeakCountAllocator, "allocator", allo);
30 if (old_mem.len == 0) {
31 self.count += 1;
32 }
33 return self.internal_allocator.reallocFn(self.internal_allocator, old_mem, old_align, new_size, new_align);
34 }
35
36 fn shrink(allo: *std.mem.Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
37 const self = @fieldParentPtr(LeakCountAllocator, "allocator", allo);
38 if (new_size == 0) {
39 self.count -= 1;
40 }
41 return self.internal_allocator.shrinkFn(self.internal_allocator, old_mem, old_align, new_size, new_align);
42 }
43
44 fn validate(self: LeakCountAllocator) !void {
45 if (self.count > 0) {
46 std.debug.warn("Detected leaked allocations without matching free: {}\n", .{self.count});
47 return error.Leak;
48 }
49 }
50};
51
1052/// This function is intended to be used only in tests. It prints diagnostics to stderr
1153/// and then aborts when actual_error_union is not expected_error.
1254pub fn expectError(expected_error: anyerror, actual_error_union: var) void {
lib/std/unicode.zig+12-6
......@@ -501,14 +501,16 @@ test "utf16leToUtf8" {
501501 {
502502 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A');
503503 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 'a');
504 const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
504 const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
505 defer std.testing.leak_count_allocator.free(utf8);
505506 testing.expect(mem.eql(u8, utf8, "Aa"));
506507 }
507508
508509 {
509510 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0x80);
510511 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xffff);
511 const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
512 const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
513 defer std.testing.leak_count_allocator.free(utf8);
512514 testing.expect(mem.eql(u8, utf8, "\xc2\x80" ++ "\xef\xbf\xbf"));
513515 }
514516
......@@ -516,7 +518,8 @@ test "utf16leToUtf8" {
516518 // the values just outside the surrogate half range
517519 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd7ff);
518520 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xe000);
519 const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
521 const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
522 defer std.testing.leak_count_allocator.free(utf8);
520523 testing.expect(mem.eql(u8, utf8, "\xed\x9f\xbf" ++ "\xee\x80\x80"));
521524 }
522525
......@@ -524,7 +527,8 @@ test "utf16leToUtf8" {
524527 // smallest surrogate pair
525528 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd800);
526529 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00);
527 const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
530 const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
531 defer std.testing.leak_count_allocator.free(utf8);
528532 testing.expect(mem.eql(u8, utf8, "\xf0\x90\x80\x80"));
529533 }
530534
......@@ -532,14 +536,16 @@ test "utf16leToUtf8" {
532536 // largest surrogate pair
533537 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff);
534538 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdfff);
535 const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
539 const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
540 defer std.testing.leak_count_allocator.free(utf8);
536541 testing.expect(mem.eql(u8, utf8, "\xf4\x8f\xbf\xbf"));
537542 }
538543
539544 {
540545 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff);
541546 mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00);
542 const utf8 = try utf16leToUtf8Alloc(std.testing.allocator, &utf16le);
547 const utf8 = try utf16leToUtf8Alloc(std.testing.leak_count_allocator, &utf16le);
548 defer std.testing.leak_count_allocator.free(utf8);
543549 testing.expect(mem.eql(u8, utf8, "\xf4\x8f\xb0\x80"));
544550 }
545551}
lib/std/zig/ast.zig+1-1
......@@ -2287,7 +2287,7 @@ pub const Node = struct {
22872287test "iterate" {
22882288 var root = Node.Root{
22892289 .base = Node{ .id = Node.Id.Root },
2290 .decls = Node.Root.DeclList.init(std.testing.allocator),
2290 .decls = Node.Root.DeclList.init(std.testing.leak_count_allocator),
22912291 .eof_token = 0,
22922292 };
22932293 var base = &root.base;
test/compare_output.zig+2-2
......@@ -445,7 +445,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
445445 \\const std = @import("std");
446446 \\const io = std.io;
447447 \\const os = std.os;
448 \\const allocator = std.testing.allocator;
448 \\const allocator = std.testing.leak_count_allocator;
449449 \\
450450 \\pub fn main() !void {
451451 \\ var args_it = std.process.args();
......@@ -486,7 +486,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
486486 \\const std = @import("std");
487487 \\const io = std.io;
488488 \\const os = std.os;
489 \\const allocator = std.testing.allocator;
489 \\const allocator = std.testing.leak_count_allocator;
490490 \\
491491 \\pub fn main() !void {
492492 \\ var args_it = std.process.args();
test/compile_errors.zig+1-1
......@@ -5765,7 +5765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57655765 \\
57665766 \\export fn entry() void {
57675767 \\ const a = MdNode.Header {
5768 \\ .text = MdText.init(&std.testing.allocator),
5768 \\ .text = MdText.init(&std.testing.leak_count_allocator),
57695769 \\ .weight = HeaderWeight.H1,
57705770 \\ };
57715771 \\}
test/stage1/behavior/const_slice_child.zig+1-1
......@@ -22,7 +22,7 @@ fn foo(args: [][]const u8) void {
2222}
2323
2424fn bar(argc: usize) void {
25 const args = testing.allocator.alloc([]const u8, argc) catch unreachable;
25 const args = testing.leak_count_allocator.alloc([]const u8, argc) catch unreachable;
2626 for (args) |_, i| {
2727 const ptr = argv[i];
2828 args[i] = ptr[0..strlen(ptr)];
test/standalone/brace_expansion/main.zig+2-2
......@@ -201,7 +201,7 @@ pub fn main() !void {
201201}
202202
203203test "invalid inputs" {
204 global_allocator = std.testing.allocator;
204 global_allocator = std.testing.leak_count_allocator;
205205
206206 expectError("}ABC", error.InvalidInput);
207207 expectError("{ABC", error.InvalidInput);
......@@ -222,7 +222,7 @@ fn expectError(test_input: []const u8, expected_err: anyerror) void {
222222}
223223
224224test "valid inputs" {
225 global_allocator = std.testing.allocator;
225 global_allocator = std.testing.leak_count_allocator;
226226
227227 expectExpansion("{x,y,z}", "x y z");
228228 expectExpansion("{A,B}{x,y}", "Ax Ay Bx By");
test/standalone/cat/main.zig+1-1
......@@ -4,7 +4,7 @@ const process = std.process;
44const fs = std.fs;
55const mem = std.mem;
66const warn = std.debug.warn;
7const allocator = std.testing.allocator;
7const allocator = std.testing.leak_count_allocator;
88
99pub fn main() !void {
1010 var args_it = process.args();
test/standalone/empty_env/main.zig+1-1
......@@ -1,6 +1,6 @@
11const std = @import("std");
22
33pub fn main() void {
4 const env_map = std.process.getEnvMap(std.testing.allocator) catch @panic("unable to get env map");
4 const env_map = std.process.getEnvMap(std.testing.leak_count_allocator) catch @panic("unable to get env map");
55 std.testing.expect(env_map.count() == 0);
66}
test/standalone/load_dynamic_library/main.zig+2-2
......@@ -1,8 +1,8 @@
11const std = @import("std");
22
33pub fn main() !void {
4 const args = try std.process.argsAlloc(std.testing.allocator);
5 defer std.process.argsFree(std.testing.allocator, args);
4 const args = try std.process.argsAlloc(std.testing.leak_count_allocator);
5 defer std.process.argsFree(std.testing.leak_count_allocator, args);
66
77 const dynlib_name = args[1];
88