-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Build: unable to run zig build test
inside a test
#15104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Error found and PR created. |
I found the actual error. Here is an example reproducing the problem: const std = @import("std");
const debug = std.debug;
const fs = std.fs;
const os = std.os;
pub fn main() !void {
os.close(0);
var handle = try std.fs.cwd().makeOpenPath("tmp", .{});
debug.print("handle: {}\n", .{handle});
} |
@andrewrk, do you known why |
I updated the Another change that fixes the issue is to set, in |
What confuses me is this section in fn openDirFlagsZ(self: Dir, sub_path_c: [*:0]const u8, flags: u32) OpenError!Dir {
const result = if (need_async_thread)
std.event.Loop.instance.?.openatZ(self.fd, sub_path_c, flags, 0)
else
os.openatZ(self.fd, sub_path_c, flags, 0);
const fd = result catch |err| switch (err) {
error.FileTooBig => unreachable, // can't happen for directories
error.IsDir => unreachable, // we're providing O.DIRECTORY
error.NoSpaceLeft => unreachable, // not providing O.CREAT
error.PathAlreadyExists => unreachable, // not providing O.CREAT
error.FileLocksNotSupported => unreachable, // locking folders is not supported
error.WouldBlock => unreachable, // can't happen for directories
error.FileBusy => unreachable, // can't happen for directories
else => |e| return e,
};
return Dir{ .fd = fd };
}
The file descriptor is set via the first parameter here: |
Note that the function called is |
Ah ok, I was going in the wrong direction. |
When running, as an example, a `zig build test` command in a build file, what happens is the following: 1. The builder_runner is executed with stdin closed, resulting in cwd_dir.fd to be 0 in std.Build.RunStep. 2. The test is executed with stdin set to a pipe, so that spawn will fail, since cwd_dir.fs is now not a directory. Add a new is_test_command field to RunStep; it must be set to true when RunStep runs a zig test command. Update the spawnChildAndCollect function, so that when running a zig test command, stdin_behavior is set to .Ignore. Fixes ziglang#15104
After commit ede5dcf (make the build runner and test runner talk to each other), the std.Build.addTest function no longer runs tests, but the build.zig files in init-exe and init-lib where not updated. Rename main_tests to lib_tests and "Run library tests" to "Run unit tests", for consistency with init-exe. Use the new Build.addRunArtifact function, instead of the deprecated CompileStep.run method. Add a RunStep to exe_tests and lib_tests. In the addCliTests function in tests/test.zig: - set the new RunStep.is_test_command field to true, when running the `zig build test` command. See ziglang#15104. - Remove an empty line in the addCliTests function in tests/tests.zig. Closes ziglang#15009
Here is a simplified example showing the cause of the problem: const std = @import("std");
const debug = std.debug;
const fs = std.fs;
const mem = std.mem;
const process = std.process;
const ChildProcess = std.ChildProcess;
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
const self_exe = try fs.selfExePathAlloc(allocator);
const argv = try process.argsAlloc(allocator);
if (argv.len == 1) {
// parent: spawn child process with stdin closed.
var child = std.process.Child.init(&.{ self_exe, "child" }, allocator);
child.stdin_behavior = .Close;
_ = try child.spawnAndWait();
return;
}
const role: []const u8 = argv[1];
if (mem.eql(u8, role, "child")) {
// child: spawn grandchild process with cwd_dir set to a new open
// directory and stdin set to a pipe.
var cwd_dir = try fs.cwd().makeOpenPath("tmp", .{});
debug.assert(cwd_dir.fd == 0);
var child = std.process.Child.init(&.{ self_exe, "grandchild" }, allocator);
child.stdin_behavior = .Pipe;
child.cwd_dir = cwd_dir;
// spawn will change cwd_dir fd to a pipe, so spawning grandchild will
// fail with NotDir.
_ = try child.spawnAndWait();
return;
} else if (mem.eql(u8, role, "grandchild")) {
// grandchild: never executed.
unreachable;
}
unreachable;
} $ zig run artificial-example.zig
error: NotDir
/home/manlio/.local/share/sdk/zig/master/lib/std/child_process.zig:368:9: 0x214576 in waitPosix (artificial-example)
return self.term.?;
^
/home/manlio/.local/share/sdk/zig/master/lib/std/child_process.zig:247:13: 0x2145f6 in wait (artificial-example)
try self.waitPosix();
^
/home/manlio/.local/share/sdk/zig/master/lib/std/child_process.zig:209:9: 0x20f959 in spawnAndWait (artificial-example)
return self.wait();
^
/home/manlio/src/zig/src/test.localhost/zig-issues/15009/artificial-example.zig:45:13: 0x20f5d7 in main (artificial-example)
_ = try child.spawnAndWait();
^ |
After commit ede5dcf (make the build runner and test runner talk to each other), the std.Build.addTest function no longer runs tests, but the build.zig files in init-exe and init-lib where not updated. Rename main_tests to lib_tests and "Run library tests" to "Run unit tests", for consistency with init-exe. Use the new Build.addRunArtifact function, instead of the deprecated CompileStep.run method. Add a RunStep to exe_tests and lib_tests. In the addCliTests function in tests/test.zig: - set the new RunStep.is_test_command field to true, when running the `zig build test` command. See ziglang#15104. - Remove an empty line in the addCliTests function in tests/tests.zig. Closes ziglang#15009
After commit ede5dcf (make the build runner and test runner talk to each other), the std.Build.addTest function no longer runs tests, but the build.zig files in init-exe and init-lib where not updated. Rename main_tests to lib_tests and "Run library tests" to "Run unit tests", for consistency with init-exe. Use the new Build.addRunArtifact function, instead of the deprecated CompileStep.run method. Add a RunStep to exe_tests and lib_tests. In the addCliTests function in tests/test.zig: - set the new RunStep.is_test_command field to true, when running the `zig build test` command. See ziglang#15104. - Remove an empty line in the addCliTests function in tests/tests.zig. Closes ziglang#15009
Currently, these tests work because of issue ziglang#15059, but ziglang#15059 requires issue ziglang#15104 to be fixed, and it is taking a lot of time. Temporarily disable the init-lib and init-exe tests in `test/tests.addCliTests`.
Fix landed in 1728d92. |
Uh oh!
There was an error while loading. Please reload this page.
Zig Version
0.11.0-dev.2297+28d6dd75a
Steps to Reproduce and Observed Behavior
build.zig
Run test
Expected Behavior
No error.
Note that the cache directory containing the
test
executable exists, after thezig build test-bug
command terminates.Also note that running
zig build test-bug
again will result in a success. The bug only happen when the cache is empty.See also #15064.
The text was updated successfully, but these errors were encountered: