authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-18 17:10:02+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-05-18 17:10:49+02:00
log2a59ecd7eca7318e9a66d856b04dd9fa45b2d69d
tree9c3e45de923fc01c2fe9d836c7b815ef35e042bc
parentf26ab568aaf60543d9fa09b53461458e5cdaddb3

Integrate getTestDir with tmpDir logic


3 files changed, 100 insertions(+), 73 deletions(-)

lib/std/io/test.zig+28-19
...@@ -11,17 +11,18 @@ const mem = std.mem;...@@ -11,17 +11,18 @@ const mem = std.mem;
11const fs = std.fs;11const fs = std.fs;
12const File = std.fs.File;12const File = std.fs.File;
1313
14const getTestDir = std.testing.getTestDir;14const tmpDir = std.testing.tmpDir;
1515
16test "write a file, read it, then delete it" {16test "write a file, read it, then delete it" {
17 const test_dir = getTestDir();17 var tmp = tmpDir(.{});
18 defer tmp.cleanup();
1819
19 var data: [1024]u8 = undefined;20 var data: [1024]u8 = undefined;
20 var prng = DefaultPrng.init(1234);21 var prng = DefaultPrng.init(1234);
21 prng.random.bytes(data[0..]);22 prng.random.bytes(data[0..]);
22 const tmp_file_name = "temp_test_file.txt";23 const tmp_file_name = "temp_test_file.txt";
23 {24 {
24 var file = try test_dir.createFile(tmp_file_name, .{});25 var file = try tmp.dir.createFile(tmp_file_name, .{});
25 defer file.close();26 defer file.close();
2627
27 var buf_stream = io.bufferedOutStream(file.outStream());28 var buf_stream = io.bufferedOutStream(file.outStream());
...@@ -34,7 +35,7 @@ test "write a file, read it, then delete it" {...@@ -34,7 +35,7 @@ test "write a file, read it, then delete it" {
3435
35 {36 {
36 // Make sure the exclusive flag is honored.37 // Make sure the exclusive flag is honored.
37 if (test_dir.createFile(tmp_file_name, .{ .exclusive = true })) |file| {38 if (tmp.dir.createFile(tmp_file_name, .{ .exclusive = true })) |file| {
38 unreachable;39 unreachable;
39 } else |err| {40 } else |err| {
40 std.debug.assert(err == File.OpenError.PathAlreadyExists);41 std.debug.assert(err == File.OpenError.PathAlreadyExists);
...@@ -42,7 +43,7 @@ test "write a file, read it, then delete it" {...@@ -42,7 +43,7 @@ test "write a file, read it, then delete it" {
42 }43 }
4344
44 {45 {
45 var file = try test_dir.openFile(tmp_file_name, .{});46 var file = try tmp.dir.openFile(tmp_file_name, .{});
46 defer file.close();47 defer file.close();
4748
48 const file_size = try file.getEndPos();49 const file_size = try file.getEndPos();
...@@ -58,14 +59,16 @@ test "write a file, read it, then delete it" {...@@ -58,14 +59,16 @@ test "write a file, read it, then delete it" {
58 expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], &data));59 expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], &data));
59 expect(mem.eql(u8, contents[contents.len - "end".len ..], "end"));60 expect(mem.eql(u8, contents[contents.len - "end".len ..], "end"));
60 }61 }
61 try test_dir.deleteFile(tmp_file_name);62 try tmp.dir.deleteFile(tmp_file_name);
62}63}
6364
64test "BitStreams with File Stream" {65test "BitStreams with File Stream" {
65 var test_dir = getTestDir();66 var tmp = tmpDir(.{});
67 defer tmp.cleanup();
68
66 const tmp_file_name = "temp_test_file.txt";69 const tmp_file_name = "temp_test_file.txt";
67 {70 {
68 var file = try test_dir.createFile(tmp_file_name, .{});71 var file = try tmp.dir.createFile(tmp_file_name, .{});
69 defer file.close();72 defer file.close();
7073
71 var bit_stream = io.bitOutStream(builtin.endian, file.outStream());74 var bit_stream = io.bitOutStream(builtin.endian, file.outStream());
...@@ -79,7 +82,7 @@ test "BitStreams with File Stream" {...@@ -79,7 +82,7 @@ test "BitStreams with File Stream" {
79 try bit_stream.flushBits();82 try bit_stream.flushBits();
80 }83 }
81 {84 {
82 var file = try test_dir.openFile(tmp_file_name, .{});85 var file = try tmp.dir.openFile(tmp_file_name, .{});
83 defer file.close();86 defer file.close();
8487
85 var bit_stream = io.bitInStream(builtin.endian, file.inStream());88 var bit_stream = io.bitInStream(builtin.endian, file.inStream());
...@@ -101,16 +104,18 @@ test "BitStreams with File Stream" {...@@ -101,16 +104,18 @@ test "BitStreams with File Stream" {
101104
102 expectError(error.EndOfStream, bit_stream.readBitsNoEof(u1, 1));105 expectError(error.EndOfStream, bit_stream.readBitsNoEof(u1, 1));
103 }106 }
104 try test_dir.deleteFile(tmp_file_name);107 try tmp.dir.deleteFile(tmp_file_name);
105}108}
106109
107test "File seek ops" {110test "File seek ops" {
108 var test_dir = getTestDir();111 var tmp = tmpDir(.{});
112 defer tmp.cleanup();
113
109 const tmp_file_name = "temp_test_file.txt";114 const tmp_file_name = "temp_test_file.txt";
110 var file = try test_dir.createFile(tmp_file_name, .{});115 var file = try tmp.dir.createFile(tmp_file_name, .{});
111 defer {116 defer {
112 file.close();117 file.close();
113 test_dir.deleteFile(tmp_file_name) catch {};118 tmp.dir.deleteFile(tmp_file_name) catch {};
114 }119 }
115120
116 try file.writeAll(&([_]u8{0x55} ** 8192));121 try file.writeAll(&([_]u8{0x55} ** 8192));
...@@ -133,12 +138,14 @@ test "setEndPos" {...@@ -133,12 +138,14 @@ test "setEndPos" {
133 // https://github.com/ziglang/zig/issues/5127138 // https://github.com/ziglang/zig/issues/5127
134 if (std.Target.current.cpu.arch == .mips) return error.SkipZigTest;139 if (std.Target.current.cpu.arch == .mips) return error.SkipZigTest;
135140
136 var test_dir = getTestDir();141 var tmp = tmpDir(.{});
142 defer tmp.cleanup();
143
137 const tmp_file_name = "temp_test_file.txt";144 const tmp_file_name = "temp_test_file.txt";
138 var file = try test_dir.createFile(tmp_file_name, .{});145 var file = try tmp.dir.createFile(tmp_file_name, .{});
139 defer {146 defer {
140 file.close();147 file.close();
141 test_dir.deleteFile(tmp_file_name) catch {};148 tmp.dir.deleteFile(tmp_file_name) catch {};
142 }149 }
143150
144 // Verify that the file size changes and the file offset is not moved151 // Verify that the file size changes and the file offset is not moved
...@@ -157,12 +164,14 @@ test "setEndPos" {...@@ -157,12 +164,14 @@ test "setEndPos" {
157}164}
158165
159test "updateTimes" {166test "updateTimes" {
160 var test_dir = getTestDir();167 var tmp = tmpDir(.{});
168 defer tmp.cleanup();
169
161 const tmp_file_name = "just_a_temporary_file.txt";170 const tmp_file_name = "just_a_temporary_file.txt";
162 var file = try test_dir.createFile(tmp_file_name, .{ .read = true });171 var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true });
163 defer {172 defer {
164 file.close();173 file.close();
165 test_dir.deleteFile(tmp_file_name) catch {};174 tmp.dir.deleteFile(tmp_file_name) catch {};
166 }175 }
167 var stat_old = try file.stat();176 var stat_old = try file.stat();
168 // Set atime and mtime to 5s before177 // Set atime and mtime to 5s before
lib/std/os/test.zig+55-38
...@@ -15,15 +15,18 @@ const a = std.testing.allocator;...@@ -15,15 +15,18 @@ const a = std.testing.allocator;
15const builtin = @import("builtin");15const builtin = @import("builtin");
16const AtomicRmwOp = builtin.AtomicRmwOp;16const AtomicRmwOp = builtin.AtomicRmwOp;
17const AtomicOrder = builtin.AtomicOrder;17const AtomicOrder = builtin.AtomicOrder;
18const getTestDir = std.testing.getTestDir;18const tmpDir = std.testing.tmpDir;
19const Dir = std.fs.Dir;
1920
20test "makePath, put some files in it, deleteTree" {21test "makePath, put some files in it, deleteTree" {
21 var test_dir = getTestDir();22 var tmp = tmpDir(.{});
22 try test_dir.makePath("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c");23 defer tmp.cleanup();
23 try test_dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c" ++ fs.path.sep_str ++ "file.txt", "nonsense");24
24 try test_dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "file2.txt", "blah");25 try tmp.dir.makePath("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c");
25 try test_dir.deleteTree("os_test_tmp");26 try tmp.dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c" ++ fs.path.sep_str ++ "file.txt", "nonsense");
26 if (test_dir.openDir("os_test_tmp", .{})) |dir| {27 try tmp.dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "file2.txt", "blah");
28 try tmp.dir.deleteTree("os_test_tmp");
29 if (tmp.dir.openDir("os_test_tmp", .{})) |dir| {
27 @panic("expected error");30 @panic("expected error");
28 } else |err| {31 } else |err| {
29 expect(err == error.FileNotFound);32 expect(err == error.FileNotFound);
...@@ -33,17 +36,19 @@ test "makePath, put some files in it, deleteTree" {...@@ -33,17 +36,19 @@ test "makePath, put some files in it, deleteTree" {
33test "access file" {36test "access file" {
34 if (builtin.os.tag == .wasi) return error.SkipZigTest;37 if (builtin.os.tag == .wasi) return error.SkipZigTest;
3538
36 var test_dir = getTestDir();39 var tmp = tmpDir(.{});
37 try test_dir.makePath("os_test_tmp");40 defer tmp.cleanup();
38 if (test_dir.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{})) |ok| {41
42 try tmp.dir.makePath("os_test_tmp");
43 if (tmp.dir.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{})) |ok| {
39 @panic("expected error");44 @panic("expected error");
40 } else |err| {45 } else |err| {
41 expect(err == error.FileNotFound);46 expect(err == error.FileNotFound);
42 }47 }
4348
44 try test_dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", "");49 try tmp.dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", "");
45 try test_dir.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{});50 try tmp.dir.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{});
46 try test_dir.deleteTree("os_test_tmp");51 try tmp.dir.deleteTree("os_test_tmp");
47}52}
4853
49fn testThreadIdFn(thread_id: *Thread.Id) void {54fn testThreadIdFn(thread_id: *Thread.Id) void {
...@@ -51,11 +56,13 @@ fn testThreadIdFn(thread_id: *Thread.Id) void {...@@ -51,11 +56,13 @@ fn testThreadIdFn(thread_id: *Thread.Id) void {
51}56}
5257
53test "sendfile" {58test "sendfile" {
54 var test_dir = getTestDir();59 var tmp = tmpDir(.{});
55 try test_dir.makePath("os_test_tmp");60 defer tmp.cleanup();
56 defer test_dir.deleteTree("os_test_tmp") catch {};61
62 try tmp.dir.makePath("os_test_tmp");
63 defer tmp.dir.deleteTree("os_test_tmp") catch {};
5764
58 var dir = try test_dir.openDir("os_test_tmp", .{});65 var dir = try tmp.dir.openDir("os_test_tmp", .{});
59 defer dir.close();66 defer dir.close();
6067
61 const line1 = "line1\n";68 const line1 = "line1\n";
...@@ -119,23 +126,24 @@ test "fs.copyFile" {...@@ -119,23 +126,24 @@ test "fs.copyFile" {
119 const dest_file = "tmp_test_copy_file2.txt";126 const dest_file = "tmp_test_copy_file2.txt";
120 const dest_file2 = "tmp_test_copy_file3.txt";127 const dest_file2 = "tmp_test_copy_file3.txt";
121128
122 const test_dir = getTestDir();129 var tmp = tmpDir(.{});
130 defer tmp.cleanup();
123131
124 try test_dir.writeFile(src_file, data);132 try tmp.dir.writeFile(src_file, data);
125 defer test_dir.deleteFile(src_file) catch {};133 defer tmp.dir.deleteFile(src_file) catch {};
126134
127 try test_dir.copyFile(src_file, test_dir, dest_file, .{});135 try tmp.dir.copyFile(src_file, tmp.dir, dest_file, .{});
128 defer test_dir.deleteFile(dest_file) catch {};136 defer tmp.dir.deleteFile(dest_file) catch {};
129137
130 try test_dir.copyFile(src_file, test_dir, dest_file2, .{ .override_mode = File.default_mode });138 try tmp.dir.copyFile(src_file, tmp.dir, dest_file2, .{ .override_mode = File.default_mode });
131 defer test_dir.deleteFile(dest_file2) catch {};139 defer tmp.dir.deleteFile(dest_file2) catch {};
132140
133 try expectFileContents(dest_file, data);141 try expectFileContents(tmp.dir, dest_file, data);
134 try expectFileContents(dest_file2, data);142 try expectFileContents(tmp.dir, dest_file2, data);
135}143}
136144
137fn expectFileContents(file_path: []const u8, data: []const u8) !void {145fn expectFileContents(dir: Dir, file_path: []const u8, data: []const u8) !void {
138 const contents = try getTestDir().readFileAlloc(testing.allocator, file_path, 1000);146 const contents = try dir.readFileAlloc(testing.allocator, file_path, 1000);
139 defer testing.allocator.free(contents);147 defer testing.allocator.free(contents);
140148
141 testing.expectEqualSlices(u8, data, contents);149 testing.expectEqualSlices(u8, data, contents);
...@@ -199,18 +207,21 @@ test "AtomicFile" {...@@ -199,18 +207,21 @@ test "AtomicFile" {
199 \\ hello!207 \\ hello!
200 \\ this is a test file208 \\ this is a test file
201 ;209 ;
202 var test_dir = getTestDir();210
211 var tmp = tmpDir(.{});
212 defer tmp.cleanup();
213
203 {214 {
204 var af = try test_dir.atomicFile(test_out_file, .{});215 var af = try tmp.dir.atomicFile(test_out_file, .{});
205 defer af.deinit();216 defer af.deinit();
206 try af.file.writeAll(test_content);217 try af.file.writeAll(test_content);
207 try af.finish();218 try af.finish();
208 }219 }
209 const content = try test_dir.readFileAlloc(testing.allocator, test_out_file, 9999);220 const content = try tmp.dir.readFileAlloc(testing.allocator, test_out_file, 9999);
210 defer testing.allocator.free(content);221 defer testing.allocator.free(content);
211 expect(mem.eql(u8, content, test_content));222 expect(mem.eql(u8, content, test_content));
212223
213 try test_dir.deleteFile(test_out_file);224 try tmp.dir.deleteFile(test_out_file);
214}225}
215226
216test "thread local storage" {227test "thread local storage" {
...@@ -365,6 +376,9 @@ test "mmap" {...@@ -365,6 +376,9 @@ test "mmap" {
365 if (builtin.os.tag == .windows or builtin.os.tag == .wasi)376 if (builtin.os.tag == .windows or builtin.os.tag == .wasi)
366 return error.SkipZigTest;377 return error.SkipZigTest;
367378
379 var tmp = tmpDir(.{});
380 defer tmp.cleanup();
381
368 // Simple mmap() call with non page-aligned size382 // Simple mmap() call with non page-aligned size
369 {383 {
370 const data = try os.mmap(384 const data = try os.mmap(
...@@ -393,7 +407,7 @@ test "mmap" {...@@ -393,7 +407,7 @@ test "mmap" {
393407
394 // Create a file used for testing mmap() calls with a file descriptor408 // Create a file used for testing mmap() calls with a file descriptor
395 {409 {
396 const file = try fs.cwd().createFile(test_out_file, .{});410 const file = try tmp.dir.createFile(test_out_file, .{});
397 defer file.close();411 defer file.close();
398412
399 const stream = file.outStream();413 const stream = file.outStream();
...@@ -406,7 +420,7 @@ test "mmap" {...@@ -406,7 +420,7 @@ test "mmap" {
406420
407 // Map the whole file421 // Map the whole file
408 {422 {
409 const file = try fs.cwd().openFile(test_out_file, .{});423 const file = try tmp.dir.openFile(test_out_file, .{});
410 defer file.close();424 defer file.close();
411425
412 const data = try os.mmap(426 const data = try os.mmap(
...@@ -430,7 +444,7 @@ test "mmap" {...@@ -430,7 +444,7 @@ test "mmap" {
430444
431 // Map the upper half of the file445 // Map the upper half of the file
432 {446 {
433 const file = try fs.cwd().openFile(test_out_file, .{});447 const file = try tmp.dir.openFile(test_out_file, .{});
434 defer file.close();448 defer file.close();
435449
436 const data = try os.mmap(450 const data = try os.mmap(
...@@ -452,7 +466,7 @@ test "mmap" {...@@ -452,7 +466,7 @@ test "mmap" {
452 }466 }
453 }467 }
454468
455 try fs.cwd().deleteFile(test_out_file);469 try tmp.dir.deleteFile(test_out_file);
456}470}
457471
458test "getenv" {472test "getenv" {
...@@ -467,12 +481,15 @@ test "fcntl" {...@@ -467,12 +481,15 @@ test "fcntl" {
467 if (builtin.os.tag == .windows or builtin.os.tag == .wasi)481 if (builtin.os.tag == .windows or builtin.os.tag == .wasi)
468 return error.SkipZigTest;482 return error.SkipZigTest;
469483
484 var tmp = tmpDir(.{});
485 defer tmp.cleanup();
486
470 const test_out_file = "os_tmp_test";487 const test_out_file = "os_tmp_test";
471488
472 const file = try fs.cwd().createFile(test_out_file, .{});489 const file = try tmp.dir.createFile(test_out_file, .{});
473 defer {490 defer {
474 file.close();491 file.close();
475 fs.cwd().deleteFile(test_out_file) catch {};492 tmp.dir.deleteFile(test_out_file) catch {};
476 }493 }
477494
478 // Note: The test assumes createFile opens the file with O_CLOEXEC495 // Note: The test assumes createFile opens the file with O_CLOEXEC
lib/std/testing.zig+17-16
...@@ -14,21 +14,6 @@ pub var failing_allocator_instance = FailingAllocator.init(&base_allocator_insta...@@ -14,21 +14,6 @@ pub var failing_allocator_instance = FailingAllocator.init(&base_allocator_insta
14pub var base_allocator_instance = std.heap.ThreadSafeFixedBufferAllocator.init(allocator_mem[0..]);14pub var base_allocator_instance = std.heap.ThreadSafeFixedBufferAllocator.init(allocator_mem[0..]);
15var allocator_mem: [2 * 1024 * 1024]u8 = undefined;15var allocator_mem: [2 * 1024 * 1024]u8 = undefined;
1616
17/// This function is intended to be used only in tests. It should be used in any testcase
18/// where we intend to test WASI and should be used a replacement for `std.fs.cwd()` in WASI.
19pub fn getTestDir() std.fs.Dir {
20 if (@import("builtin").os.tag == .wasi) {
21 var preopens = std.fs.wasi.PreopenList.init(allocator);
22 defer preopens.deinit();
23 preopens.populate() catch unreachable;
24
25 const preopen = preopens.find(".") orelse unreachable;
26 return std.fs.Dir{ .fd = preopen.fd };
27 } else {
28 return std.fs.cwd();
29 }
30}
31
32/// This function is intended to be used only in tests. It prints diagnostics to stderr17/// This function is intended to be used only in tests. It prints diagnostics to stderr
33/// and then aborts when actual_error_union is not expected_error.18/// and then aborts when actual_error_union is not expected_error.
34pub fn expectError(expected_error: anyerror, actual_error_union: var) void {19pub fn expectError(expected_error: anyerror, actual_error_union: var) void {
...@@ -224,6 +209,21 @@ pub const TmpDir = struct {...@@ -224,6 +209,21 @@ pub const TmpDir = struct {
224 }209 }
225};210};
226211
212fn getCwdOrWasiPreopen() std.fs.Dir {
213 if (@import("builtin").os.tag == .wasi) {
214 var preopens = std.fs.wasi.PreopenList.init(allocator);
215 defer preopens.deinit();
216 preopens.populate() catch
217 @panic("unable to make tmp dir for testing: unable to populate preopens");
218 const preopen = preopens.find(".") orelse
219 @panic("unable to make tmp dir for testing: didn't find '.' in the preopens");
220
221 return std.fs.Dir{ .fd = preopen.fd };
222 } else {
223 return std.fs.cwd();
224 }
225}
226
227pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir {227pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir {
228 var random_bytes: [TmpDir.random_bytes_count]u8 = undefined;228 var random_bytes: [TmpDir.random_bytes_count]u8 = undefined;
229 std.crypto.randomBytes(&random_bytes) catch229 std.crypto.randomBytes(&random_bytes) catch
...@@ -231,7 +231,8 @@ pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir {...@@ -231,7 +231,8 @@ pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir {
231 var sub_path: [TmpDir.sub_path_len]u8 = undefined;231 var sub_path: [TmpDir.sub_path_len]u8 = undefined;
232 std.fs.base64_encoder.encode(&sub_path, &random_bytes);232 std.fs.base64_encoder.encode(&sub_path, &random_bytes);
233233
234 var cache_dir = std.fs.cwd().makeOpenPath("zig-cache", .{}) catch234 var cwd = getCwdOrWasiPreopen();
235 var cache_dir = cwd.makeOpenPath("zig-cache", .{}) catch
235 @panic("unable to make tmp dir for testing: unable to make and open zig-cache dir");236 @panic("unable to make tmp dir for testing: unable to make and open zig-cache dir");
236 defer cache_dir.close();237 defer cache_dir.close();
237 var parent_dir = cache_dir.makeOpenPath("tmp", .{}) catch238 var parent_dir = cache_dir.makeOpenPath("tmp", .{}) catch