I’m trying to pass a temporary directory to a test. However the temporary subdir created by the build system doesn’t seem to get deleted? Am I doing something wrong?
This may be wrong so take it with a grain of salt. But as far as I understand it the tmp_dir in the build.zig is just for building the code and not running it. Meaning that it may or may not later be deleted when you run the tests.
You can have a temporary directory for tests like this:
test "tmp_dir" {
var tmp = std.testing.tmpDir(.{});
defer tmp.cleanup();
// ... Your code
}
Actually, I think @Zemogus what you originally wanted is fundamentally a better approach.
The problem with std.testing.tmpDir(.{}) and any equivalents is that the clean up is cooperative — it’s the testing process that deletes it, before it exits. That is problematic, because the code we are testing often crashes (or hangs, and is then killed by the test-running infrastructure), so no defers are run, and the are leftovers on the file system, which could eventually occupy all of the disk space (don’t ask )
It’s more reliable to make the parent process create and dispose of a temporary directory. In some sense, it is just kicking the can down the road (what if the parent dies abruptly), but in practical sense it isn’t: the parent code (build.zig) is stable, it rarely changes and is assumed to be bug free. But the code under test is buggy, that’s why we are testing it in the first place!
Alas, I don’t think you can achieve this in “userspace” in build.zig:
As far as I am aware, you can’t create a temporary directory before the step runs, and then clean it up later.
You’d want to pass that directory as a runtime argument to the tests, rather than a comptime-one, but this isn’t possible.
I think I do with that build.zig had this sort of facility, but, practically, just use std.testing.tmpDir and maybe drop .zig-cache/tmp once in a while manually.
I’m also not aware something like this exists. But one could just have a stable tmp_dir across runs and let the next run clean it up if it already exists. But this is then inherently racy, which could lead to other problems.
One could pass it via some sidechannel like a file but this also bad because of various obvious reasons.