From 2a59ecd7eca7318e9a66d856b04dd9fa45b2d69d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 18 May 2020 17:10:02 +0200 Subject: [PATCH] Integrate getTestDir with tmpDir logic --- lib/std/io/test.zig | 47 ++++++++++++++--------- lib/std/os/test.zig | 93 +++++++++++++++++++++++++++------------------ lib/std/testing.zig | 33 ++++++++-------- 3 files changed, 100 insertions(+), 73 deletions(-) diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig index cad3e6eb88..9ed02262b4 100644 --- a/lib/std/io/test.zig +++ b/lib/std/io/test.zig @@ -11,17 +11,18 @@ const mem = std.mem; const fs = std.fs; const File = std.fs.File; -const getTestDir = std.testing.getTestDir; +const tmpDir = std.testing.tmpDir; test "write a file, read it, then delete it" { - const test_dir = getTestDir(); + var tmp = tmpDir(.{}); + defer tmp.cleanup(); var data: [1024]u8 = undefined; var prng = DefaultPrng.init(1234); prng.random.bytes(data[0..]); const tmp_file_name = "temp_test_file.txt"; { - var file = try test_dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(tmp_file_name, .{}); defer file.close(); var buf_stream = io.bufferedOutStream(file.outStream()); @@ -34,7 +35,7 @@ test "write a file, read it, then delete it" { { // Make sure the exclusive flag is honored. - if (test_dir.createFile(tmp_file_name, .{ .exclusive = true })) |file| { + if (tmp.dir.createFile(tmp_file_name, .{ .exclusive = true })) |file| { unreachable; } else |err| { std.debug.assert(err == File.OpenError.PathAlreadyExists); @@ -42,7 +43,7 @@ test "write a file, read it, then delete it" { } { - var file = try test_dir.openFile(tmp_file_name, .{}); + var file = try tmp.dir.openFile(tmp_file_name, .{}); defer file.close(); const file_size = try file.getEndPos(); @@ -58,14 +59,16 @@ test "write a file, read it, then delete it" { expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], &data)); expect(mem.eql(u8, contents[contents.len - "end".len ..], "end")); } - try test_dir.deleteFile(tmp_file_name); + try tmp.dir.deleteFile(tmp_file_name); } test "BitStreams with File Stream" { - var test_dir = getTestDir(); + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + const tmp_file_name = "temp_test_file.txt"; { - var file = try test_dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(tmp_file_name, .{}); defer file.close(); var bit_stream = io.bitOutStream(builtin.endian, file.outStream()); @@ -79,7 +82,7 @@ test "BitStreams with File Stream" { try bit_stream.flushBits(); } { - var file = try test_dir.openFile(tmp_file_name, .{}); + var file = try tmp.dir.openFile(tmp_file_name, .{}); defer file.close(); var bit_stream = io.bitInStream(builtin.endian, file.inStream()); @@ -101,16 +104,18 @@ test "BitStreams with File Stream" { expectError(error.EndOfStream, bit_stream.readBitsNoEof(u1, 1)); } - try test_dir.deleteFile(tmp_file_name); + try tmp.dir.deleteFile(tmp_file_name); } test "File seek ops" { - var test_dir = getTestDir(); + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + const tmp_file_name = "temp_test_file.txt"; - var file = try test_dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(tmp_file_name, .{}); defer { file.close(); - test_dir.deleteFile(tmp_file_name) catch {}; + tmp.dir.deleteFile(tmp_file_name) catch {}; } try file.writeAll(&([_]u8{0x55} ** 8192)); @@ -133,12 +138,14 @@ test "setEndPos" { // https://github.com/ziglang/zig/issues/5127 if (std.Target.current.cpu.arch == .mips) return error.SkipZigTest; - var test_dir = getTestDir(); + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + const tmp_file_name = "temp_test_file.txt"; - var file = try test_dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(tmp_file_name, .{}); defer { file.close(); - test_dir.deleteFile(tmp_file_name) catch {}; + tmp.dir.deleteFile(tmp_file_name) catch {}; } // Verify that the file size changes and the file offset is not moved @@ -157,12 +164,14 @@ test "setEndPos" { } test "updateTimes" { - var test_dir = getTestDir(); + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + const tmp_file_name = "just_a_temporary_file.txt"; - var file = try test_dir.createFile(tmp_file_name, .{ .read = true }); + var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true }); defer { file.close(); - test_dir.deleteFile(tmp_file_name) catch {}; + tmp.dir.deleteFile(tmp_file_name) catch {}; } var stat_old = try file.stat(); // Set atime and mtime to 5s before diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index 485b089928..cc3b4f5741 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -15,15 +15,18 @@ const a = std.testing.allocator; const builtin = @import("builtin"); const AtomicRmwOp = builtin.AtomicRmwOp; const AtomicOrder = builtin.AtomicOrder; -const getTestDir = std.testing.getTestDir; +const tmpDir = std.testing.tmpDir; +const Dir = std.fs.Dir; test "makePath, put some files in it, deleteTree" { - var test_dir = getTestDir(); - try test_dir.makePath("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c"); - try test_dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c" ++ fs.path.sep_str ++ "file.txt", "nonsense"); - try test_dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "file2.txt", "blah"); - try test_dir.deleteTree("os_test_tmp"); - if (test_dir.openDir("os_test_tmp", .{})) |dir| { + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + + try tmp.dir.makePath("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c"); + try tmp.dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c" ++ fs.path.sep_str ++ "file.txt", "nonsense"); + try tmp.dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "file2.txt", "blah"); + try tmp.dir.deleteTree("os_test_tmp"); + if (tmp.dir.openDir("os_test_tmp", .{})) |dir| { @panic("expected error"); } else |err| { expect(err == error.FileNotFound); @@ -33,17 +36,19 @@ test "makePath, put some files in it, deleteTree" { test "access file" { if (builtin.os.tag == .wasi) return error.SkipZigTest; - var test_dir = getTestDir(); - try test_dir.makePath("os_test_tmp"); - if (test_dir.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{})) |ok| { + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + + try tmp.dir.makePath("os_test_tmp"); + if (tmp.dir.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{})) |ok| { @panic("expected error"); } else |err| { expect(err == error.FileNotFound); } - try test_dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", ""); - try test_dir.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{}); - try test_dir.deleteTree("os_test_tmp"); + try tmp.dir.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", ""); + try tmp.dir.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{}); + try tmp.dir.deleteTree("os_test_tmp"); } fn testThreadIdFn(thread_id: *Thread.Id) void { @@ -51,11 +56,13 @@ fn testThreadIdFn(thread_id: *Thread.Id) void { } test "sendfile" { - var test_dir = getTestDir(); - try test_dir.makePath("os_test_tmp"); - defer test_dir.deleteTree("os_test_tmp") catch {}; + var tmp = tmpDir(.{}); + defer tmp.cleanup(); - var dir = try test_dir.openDir("os_test_tmp", .{}); + try tmp.dir.makePath("os_test_tmp"); + defer tmp.dir.deleteTree("os_test_tmp") catch {}; + + var dir = try tmp.dir.openDir("os_test_tmp", .{}); defer dir.close(); const line1 = "line1\n"; @@ -119,23 +126,24 @@ test "fs.copyFile" { const dest_file = "tmp_test_copy_file2.txt"; const dest_file2 = "tmp_test_copy_file3.txt"; - const test_dir = getTestDir(); + var tmp = tmpDir(.{}); + defer tmp.cleanup(); - try test_dir.writeFile(src_file, data); - defer test_dir.deleteFile(src_file) catch {}; + try tmp.dir.writeFile(src_file, data); + defer tmp.dir.deleteFile(src_file) catch {}; - try test_dir.copyFile(src_file, test_dir, dest_file, .{}); - defer test_dir.deleteFile(dest_file) catch {}; + try tmp.dir.copyFile(src_file, tmp.dir, dest_file, .{}); + defer tmp.dir.deleteFile(dest_file) catch {}; - try test_dir.copyFile(src_file, test_dir, dest_file2, .{ .override_mode = File.default_mode }); - defer test_dir.deleteFile(dest_file2) catch {}; + try tmp.dir.copyFile(src_file, tmp.dir, dest_file2, .{ .override_mode = File.default_mode }); + defer tmp.dir.deleteFile(dest_file2) catch {}; - try expectFileContents(dest_file, data); - try expectFileContents(dest_file2, data); + try expectFileContents(tmp.dir, dest_file, data); + try expectFileContents(tmp.dir, dest_file2, data); } -fn expectFileContents(file_path: []const u8, data: []const u8) !void { - const contents = try getTestDir().readFileAlloc(testing.allocator, file_path, 1000); +fn expectFileContents(dir: Dir, file_path: []const u8, data: []const u8) !void { + const contents = try dir.readFileAlloc(testing.allocator, file_path, 1000); defer testing.allocator.free(contents); testing.expectEqualSlices(u8, data, contents); @@ -199,18 +207,21 @@ test "AtomicFile" { \\ hello! \\ this is a test file ; - var test_dir = getTestDir(); + + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + { - var af = try test_dir.atomicFile(test_out_file, .{}); + var af = try tmp.dir.atomicFile(test_out_file, .{}); defer af.deinit(); try af.file.writeAll(test_content); try af.finish(); } - const content = try test_dir.readFileAlloc(testing.allocator, test_out_file, 9999); + const content = try tmp.dir.readFileAlloc(testing.allocator, test_out_file, 9999); defer testing.allocator.free(content); expect(mem.eql(u8, content, test_content)); - try test_dir.deleteFile(test_out_file); + try tmp.dir.deleteFile(test_out_file); } test "thread local storage" { @@ -365,6 +376,9 @@ test "mmap" { if (builtin.os.tag == .windows or builtin.os.tag == .wasi) return error.SkipZigTest; + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + // Simple mmap() call with non page-aligned size { const data = try os.mmap( @@ -393,7 +407,7 @@ test "mmap" { // Create a file used for testing mmap() calls with a file descriptor { - const file = try fs.cwd().createFile(test_out_file, .{}); + const file = try tmp.dir.createFile(test_out_file, .{}); defer file.close(); const stream = file.outStream(); @@ -406,7 +420,7 @@ test "mmap" { // Map the whole file { - const file = try fs.cwd().openFile(test_out_file, .{}); + const file = try tmp.dir.openFile(test_out_file, .{}); defer file.close(); const data = try os.mmap( @@ -430,7 +444,7 @@ test "mmap" { // Map the upper half of the file { - const file = try fs.cwd().openFile(test_out_file, .{}); + const file = try tmp.dir.openFile(test_out_file, .{}); defer file.close(); const data = try os.mmap( @@ -452,7 +466,7 @@ test "mmap" { } } - try fs.cwd().deleteFile(test_out_file); + try tmp.dir.deleteFile(test_out_file); } test "getenv" { @@ -467,12 +481,15 @@ test "fcntl" { if (builtin.os.tag == .windows or builtin.os.tag == .wasi) return error.SkipZigTest; + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + const test_out_file = "os_tmp_test"; - const file = try fs.cwd().createFile(test_out_file, .{}); + const file = try tmp.dir.createFile(test_out_file, .{}); defer { file.close(); - fs.cwd().deleteFile(test_out_file) catch {}; + tmp.dir.deleteFile(test_out_file) catch {}; } // Note: The test assumes createFile opens the file with O_CLOEXEC diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 1592923ba8..34bebad043 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -14,21 +14,6 @@ pub var failing_allocator_instance = FailingAllocator.init(&base_allocator_insta pub var base_allocator_instance = std.heap.ThreadSafeFixedBufferAllocator.init(allocator_mem[0..]); var allocator_mem: [2 * 1024 * 1024]u8 = undefined; -/// This function is intended to be used only in tests. It should be used in any testcase -/// where we intend to test WASI and should be used a replacement for `std.fs.cwd()` in WASI. -pub fn getTestDir() std.fs.Dir { - if (@import("builtin").os.tag == .wasi) { - var preopens = std.fs.wasi.PreopenList.init(allocator); - defer preopens.deinit(); - preopens.populate() catch unreachable; - - const preopen = preopens.find(".") orelse unreachable; - return std.fs.Dir{ .fd = preopen.fd }; - } else { - return std.fs.cwd(); - } -} - /// 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 { @@ -224,6 +209,21 @@ pub const TmpDir = struct { } }; +fn getCwdOrWasiPreopen() std.fs.Dir { + if (@import("builtin").os.tag == .wasi) { + var preopens = std.fs.wasi.PreopenList.init(allocator); + defer preopens.deinit(); + preopens.populate() catch + @panic("unable to make tmp dir for testing: unable to populate preopens"); + const preopen = preopens.find(".") orelse + @panic("unable to make tmp dir for testing: didn't find '.' in the preopens"); + + return std.fs.Dir{ .fd = preopen.fd }; + } else { + return std.fs.cwd(); + } +} + pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir { var random_bytes: [TmpDir.random_bytes_count]u8 = undefined; std.crypto.randomBytes(&random_bytes) catch @@ -231,7 +231,8 @@ pub fn tmpDir(opts: std.fs.Dir.OpenDirOptions) TmpDir { var sub_path: [TmpDir.sub_path_len]u8 = undefined; std.fs.base64_encoder.encode(&sub_path, &random_bytes); - var cache_dir = std.fs.cwd().makeOpenPath("zig-cache", .{}) catch + var cwd = getCwdOrWasiPreopen(); + var cache_dir = cwd.makeOpenPath("zig-cache", .{}) catch @panic("unable to make tmp dir for testing: unable to make and open zig-cache dir"); defer cache_dir.close(); var parent_dir = cache_dir.makeOpenPath("tmp", .{}) catch