Commit 4ceaa0595a

Andrew Kelley <andrew@ziglang.org>
2020-04-11 23:50:38
move fs tests to separate file; disable flaky test
See #5006
1 parent c236cbf
Changed files (2)
lib
lib/std/fs/test.zig
@@ -0,0 +1,169 @@
+const std = @import("../std.zig");
+const builtin = std.builtin;
+const fs = std.fs;
+const File = std.fs.File;
+
+test "openSelfExe" {
+    const self_exe_file = try std.fs.openSelfExe();
+    self_exe_file.close();
+}
+
+const FILE_LOCK_TEST_SLEEP_TIME = 5 * std.time.millisecond;
+
+test "open file with exclusive nonblocking lock twice" {
+    const dir = fs.cwd();
+    const filename = "file_nonblocking_lock_test.txt";
+
+    const file1 = try dir.createFile(filename, .{ .lock = .Exclusive, .lock_nonblocking = true });
+    defer file1.close();
+
+    const file2 = dir.createFile(filename, .{ .lock = .Exclusive, .lock_nonblocking = true });
+    std.debug.assert(std.meta.eql(file2, error.WouldBlock));
+
+    dir.deleteFile(filename) catch |err| switch (err) {
+        error.FileNotFound => {},
+        else => return err,
+    };
+}
+
+test "open file with lock twice, make sure it wasn't open at the same time" {
+    if (builtin.single_threaded) return;
+
+    const filename = "file_lock_test.txt";
+
+    var contexts = [_]FileLockTestContext{
+        .{ .filename = filename, .create = true, .lock = .Exclusive },
+        .{ .filename = filename, .create = true, .lock = .Exclusive },
+    };
+    try run_lock_file_test(&contexts);
+
+    // Check for an error
+    var was_error = false;
+    for (contexts) |context, idx| {
+        if (context.err) |err| {
+            was_error = true;
+            std.debug.warn("\nError in context {}: {}\n", .{ idx, err });
+        }
+    }
+    if (was_error) builtin.panic("There was an error in contexts", null);
+
+    std.debug.assert(!contexts[0].overlaps(&contexts[1]));
+
+    fs.cwd().deleteFile(filename) catch |err| switch (err) {
+        error.FileNotFound => {},
+        else => return err,
+    };
+}
+
+test "create file, lock and read from multiple process at once" {
+    if (builtin.single_threaded) return error.SkipZigTest;
+
+    if (true) {
+        // https://github.com/ziglang/zig/issues/5006
+        return error.SkipZigTest;
+    }
+
+    const filename = "file_read_lock_test.txt";
+    const filedata = "Hello, world!\n";
+
+    try fs.cwd().writeFile(filename, filedata);
+
+    var contexts = [_]FileLockTestContext{
+        .{ .filename = filename, .create = false, .lock = .Shared },
+        .{ .filename = filename, .create = false, .lock = .Shared },
+        .{ .filename = filename, .create = false, .lock = .Exclusive },
+    };
+
+    try run_lock_file_test(&contexts);
+
+    var was_error = false;
+    for (contexts) |context, idx| {
+        if (context.err) |err| {
+            was_error = true;
+            std.debug.warn("\nError in context {}: {}\n", .{ idx, err });
+        }
+    }
+    if (was_error) builtin.panic("There was an error in contexts", null);
+
+    std.debug.assert(contexts[0].overlaps(&contexts[1]));
+    std.debug.assert(!contexts[2].overlaps(&contexts[0]));
+    std.debug.assert(!contexts[2].overlaps(&contexts[1]));
+    if (contexts[0].bytes_read.? != filedata.len) {
+        std.debug.warn("\n bytes_read: {}, expected: {} \n", .{ contexts[0].bytes_read, filedata.len });
+    }
+    std.debug.assert(contexts[0].bytes_read.? == filedata.len);
+    std.debug.assert(contexts[1].bytes_read.? == filedata.len);
+
+    fs.cwd().deleteFile(filename) catch |err| switch (err) {
+        error.FileNotFound => {},
+        else => return err,
+    };
+}
+
+const FileLockTestContext = struct {
+    filename: []const u8,
+    pid: if (builtin.os.tag == .windows) ?void else ?std.os.pid_t = null,
+
+    // use file.createFile
+    create: bool,
+    // the type of lock to use
+    lock: File.Lock,
+
+    // Output variables
+    err: ?(File.OpenError || std.os.ReadError) = null,
+    start_time: u64 = 0,
+    end_time: u64 = 0,
+    bytes_read: ?usize = null,
+
+    fn overlaps(self: *const @This(), other: *const @This()) bool {
+        return (self.start_time < other.end_time) and (self.end_time > other.start_time);
+    }
+
+    fn run(ctx: *@This()) void {
+        var file: File = undefined;
+        if (ctx.create) {
+            file = fs.cwd().createFile(ctx.filename, .{ .lock = ctx.lock }) catch |err| {
+                ctx.err = err;
+                return;
+            };
+        } else {
+            file = fs.cwd().openFile(ctx.filename, .{ .lock = ctx.lock }) catch |err| {
+                ctx.err = err;
+                return;
+            };
+        }
+        defer file.close();
+
+        ctx.start_time = std.time.milliTimestamp();
+
+        if (!ctx.create) {
+            var buffer: [100]u8 = undefined;
+            ctx.bytes_read = 0;
+            while (true) {
+                const amt = file.read(buffer[0..]) catch |err| {
+                    ctx.err = err;
+                    return;
+                };
+                if (amt == 0) break;
+                ctx.bytes_read.? += amt;
+            }
+        }
+
+        std.time.sleep(FILE_LOCK_TEST_SLEEP_TIME);
+
+        ctx.end_time = std.time.milliTimestamp();
+    }
+};
+
+fn run_lock_file_test(contexts: []FileLockTestContext) !void {
+    var threads = std.ArrayList(*std.Thread).init(std.testing.allocator);
+    defer {
+        for (threads.toSlice()) |thread| {
+            thread.wait();
+        }
+        threads.deinit();
+    }
+    for (contexts) |*ctx, idx| {
+        try threads.append(try std.Thread.spawn(ctx, FileLockTestContext.run));
+    }
+}
lib/std/fs.zig
@@ -1584,13 +1584,6 @@ pub fn openSelfExe() OpenSelfExeError!File {
     return openFileAbsoluteZ(buf[0..self_exe_path.len :0].ptr, .{});
 }
 
-test "openSelfExe" {
-    switch (builtin.os.tag) {
-        .linux, .macosx, .ios, .windows, .freebsd, .dragonfly => (try openSelfExe()).close(),
-        else => return error.SkipZigTest, // Unsupported OS.
-    }
-}
-
 pub const SelfExePathError = os.ReadLinkError || os.SysCtlError;
 
 /// `selfExePath` except allocates the result on the heap.
@@ -1678,163 +1671,9 @@ test "" {
     _ = copyFileAbsolute;
     _ = updateFileAbsolute;
     _ = Dir.copyFile;
+    _ = @import("fs/test.zig");
     _ = @import("fs/path.zig");
     _ = @import("fs/file.zig");
     _ = @import("fs/get_app_data_dir.zig");
     _ = @import("fs/watch.zig");
 }
-
-const FILE_LOCK_TEST_SLEEP_TIME = 5 * std.time.millisecond;
-
-test "open file with exclusive nonblocking lock twice" {
-    const dir = cwd();
-    const filename = "file_nonblocking_lock_test.txt";
-
-    const file1 = try dir.createFile(filename, .{ .lock = .Exclusive, .lock_nonblocking = true });
-    defer file1.close();
-
-    const file2 = dir.createFile(filename, .{ .lock = .Exclusive, .lock_nonblocking = true });
-    std.debug.assert(std.meta.eql(file2, error.WouldBlock));
-
-    dir.deleteFile(filename) catch |err| switch (err) {
-        error.FileNotFound => {},
-        else => return err,
-    };
-}
-
-test "open file with lock twice, make sure it wasn't open at the same time" {
-    if (builtin.single_threaded) return;
-
-    const filename = "file_lock_test.txt";
-
-    var contexts = [_]FileLockTestContext{
-        .{ .filename = filename, .create = true, .lock = .Exclusive },
-        .{ .filename = filename, .create = true, .lock = .Exclusive },
-    };
-    try run_lock_file_test(&contexts);
-
-    // Check for an error
-    var was_error = false;
-    for (contexts) |context, idx| {
-        if (context.err) |err| {
-            was_error = true;
-            std.debug.warn("\nError in context {}: {}\n", .{ idx, err });
-        }
-    }
-    if (was_error) builtin.panic("There was an error in contexts", null);
-
-    std.debug.assert(!contexts[0].overlaps(&contexts[1]));
-
-    cwd().deleteFile(filename) catch |err| switch (err) {
-        error.FileNotFound => {},
-        else => return err,
-    };
-}
-
-test "create file, lock and read from multiple process at once" {
-    if (builtin.single_threaded) return;
-
-    const filename = "file_read_lock_test.txt";
-    const filedata = "Hello, world!\n";
-
-    try std.fs.cwd().writeFile(filename, filedata);
-
-    var contexts = [_]FileLockTestContext{
-        .{ .filename = filename, .create = false, .lock = .Shared },
-        .{ .filename = filename, .create = false, .lock = .Shared },
-        .{ .filename = filename, .create = false, .lock = .Exclusive },
-    };
-
-    try run_lock_file_test(&contexts);
-
-    var was_error = false;
-    for (contexts) |context, idx| {
-        if (context.err) |err| {
-            was_error = true;
-            std.debug.warn("\nError in context {}: {}\n", .{ idx, err });
-        }
-    }
-    if (was_error) builtin.panic("There was an error in contexts", null);
-
-    std.debug.assert(contexts[0].overlaps(&contexts[1]));
-    std.debug.assert(!contexts[2].overlaps(&contexts[0]));
-    std.debug.assert(!contexts[2].overlaps(&contexts[1]));
-    if (contexts[0].bytes_read.? != filedata.len) {
-        std.debug.warn("\n bytes_read: {}, expected: {} \n", .{ contexts[0].bytes_read, filedata.len });
-    }
-    std.debug.assert(contexts[0].bytes_read.? == filedata.len);
-    std.debug.assert(contexts[1].bytes_read.? == filedata.len);
-
-    cwd().deleteFile(filename) catch |err| switch (err) {
-        error.FileNotFound => {},
-        else => return err,
-    };
-}
-
-const FileLockTestContext = struct {
-    filename: []const u8,
-    pid: if (builtin.os.tag == .windows) ?void else ?std.os.pid_t = null,
-
-    // use file.createFile
-    create: bool,
-    // the type of lock to use
-    lock: File.Lock,
-
-    // Output variables
-    err: ?(File.OpenError || std.os.ReadError) = null,
-    start_time: u64 = 0,
-    end_time: u64 = 0,
-    bytes_read: ?usize = null,
-
-    fn overlaps(self: *const @This(), other: *const @This()) bool {
-        return (self.start_time < other.end_time) and (self.end_time > other.start_time);
-    }
-
-    fn run(ctx: *@This()) void {
-        var file: File = undefined;
-        if (ctx.create) {
-            file = cwd().createFile(ctx.filename, .{ .lock = ctx.lock }) catch |err| {
-                ctx.err = err;
-                return;
-            };
-        } else {
-            file = cwd().openFile(ctx.filename, .{ .lock = ctx.lock }) catch |err| {
-                ctx.err = err;
-                return;
-            };
-        }
-        defer file.close();
-
-        ctx.start_time = std.time.milliTimestamp();
-
-        if (!ctx.create) {
-            var buffer: [100]u8 = undefined;
-            ctx.bytes_read = 0;
-            while (true) {
-                const amt = file.read(buffer[0..]) catch |err| {
-                    ctx.err = err;
-                    return;
-                };
-                if (amt == 0) break;
-                ctx.bytes_read.? += amt;
-            }
-        }
-
-        std.time.sleep(FILE_LOCK_TEST_SLEEP_TIME);
-
-        ctx.end_time = std.time.milliTimestamp();
-    }
-};
-
-fn run_lock_file_test(contexts: []FileLockTestContext) !void {
-    var threads = std.ArrayList(*std.Thread).init(std.testing.allocator);
-    defer {
-        for (threads.toSlice()) |thread| {
-            thread.wait();
-        }
-        threads.deinit();
-    }
-    for (contexts) |*ctx, idx| {
-        try threads.append(try std.Thread.spawn(ctx, FileLockTestContext.run));
-    }
-}