KEMBAR78
tests: test unit tests by cb22 · Pull Request #3136 · tigerbeetle/tigerbeetle · GitHub
Skip to content

Conversation

cb22
Copy link
Member

@cb22 cb22 commented Aug 5, 2025

Inspired by #3124 (comment) this generates the unit_tests.zig file in build.zig.

There's a bit of logic as to what files should be included, so I thought it's more evident to go with a generated in-repo file rather than removing unit_tests.zig entirely.

Another option could be to keep unit_tests.zig as manually generated but lint it to ensure everything with a test block is included.

@cb22 cb22 force-pushed the cb22/forget-me-not branch 3 times, most recently from f530d7c to 1a795dd Compare August 5, 2025 12:14
@cb22 cb22 marked this pull request as ready for review August 5, 2025 12:21
Copy link
Member

@matklad matklad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

build.zig Outdated
Comment on lines 851 to 853
var unit_test_files = std.ArrayList([]const u8).init(b.allocator);
defer unit_test_files.deinit();
defer for (unit_test_files.items) |item| b.allocator.free(item);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make a local area here, to not bother with freeing individual items.

build.zig Outdated
defer b.allocator.free(contents);

if (std.mem.indexOf(u8, contents, "test \"") == null and
std.mem.indexOf(u8, contents, "test {") == null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zig also allows for

fn foo() void {}
test foo {}

Maybe check that trimmed line starts with test ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, this missed the test in forest.zig.

build.zig Outdated
!std.mem.startsWith(u8, entry_path, "clients/c")) continue;
if (std.mem.eql(u8, entry_path, "tigerbeetle/libtb_client.zig")) continue;

const contents = try src_dir.readFileAlloc(b.allocator, entry_path, 1024 * 1024);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, so this effectively slurps the entire source directory at the configure time. I think we'd love to avoid that, as this moves our no-op build performance from O(number of files) to O(total length of files).

Oh! Haha! let's do a snapshot test here! Inside unit_tests.zig, we can add a test that, when run, generates the source code of the unit_tests.zig file, fails if it doesn't match the actual source code, and updates itself.

@cb22 cb22 changed the title tests: generate unit_tests.zig tests: test unit tests Aug 6, 2025
@matklad
Copy link
Member

matklad commented Aug 6, 2025

As per new review policy, pushed some suggestions directly!

build.zig Outdated

const build_root = b.addOptions();
build_root.addOption([]const u8, "build_root", b.build_root.path.?);
unit_tests.root_module.addOptions("build_root", build_root);
Copy link
Member

@matklad matklad Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use std.fs.cwd()? That's what snaptest is doing, and it's been reliable for me!

const file_text = try std.fs.cwd().readFileAlloc(

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use std.fs.cwd()? That's what snaptest is doing, and it's been reliable for me!

If you run ./zig/zig test and not eg ../zig/zig build from src/, which is currently broken anyways for test (but works for normal building!)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, it definitely does use fixed cwd as of 0.14.1:

https://github.com/ziglang/zig/blob/d03a147ea0a590ca711b3db07106effc559b0fc6/lib/std/Build/Step/Run.zig#L1340-L1341

However, this seems to be changing for 0.15:

ziglang/zig#23946

I guess in any case we can use

run_unit_tests.setCwd(b.path("."));

Injecting absolute path in the binary feels weird, as it makes the actual binary not-reproducible between machines.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh hmm, must be something else cause this then:

~/g/t/tigerbeetle-3/src cb22/rename-nodes• 1.3s | 130 ❱ ../zig/zig build test
test
└─ test:integration
   └─ run test
      └─ zig test Debug x86_64-linux
         └─ options
            └─ zig build-exe vortex Debug x86_64-linux 2 errors
testing/vortex/zig_driver.zig:10:11: error: C import failed
const c = @cImport({
          ^~~~~~~~
referenced by:
    main: testing/vortex/zig_driver.zig:38:20
    main: vortex.zig:59:52
    main: /tank/mutable/synced/git/tigerbeetle/tigerbeetle-3/zig/lib/std/start.zig:660:37
    comptime: /tank/mutable/synced/git/tigerbeetle/tigerbeetle-3/zig/lib/std/start.zig:58:30
    start: /tank/mutable/synced/git/tigerbeetle/tigerbeetle-3/zig/lib/std/std.zig:97:27
    comptime: /tank/mutable/synced/git/tigerbeetle/tigerbeetle-3/zig/lib/std/std.zig:168:9
/tank/mutable/synced/git/tigerbeetle/tigerbeetle-3/.zig-cache/o/8cbe1d82feb80658a77104a8d02d3f13/cimport.h:1:10: error: 'tb_client.h' file not found

...

run_unit_tests.setCwd(b.path("."));

Ah yes, much nicer! Done, and rebased.

if (std.process.hasEnvVarConstant("SNAP_UPDATE")) {
const includes_end = std.mem.indexOf(u8, unit_tests_contents_disk, "}\n").? + 2;

// Add the rest of the real file on disk to the generated in-memory file.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if we should turn this into a true quine which doesn't read its own source code, just for cool points 🙈

cb22 and others added 5 commits August 6, 2025 13:48
Inspired by #3124 (comment)
this generates the `unit_tests.zig` file in `build.zig`.

There's a bit of logic as to what files should be included, so I thought it's
more evident to go with a generated in-repo file rather than removing
`unit_tests.zig` entirely.

Another option could be to keep `unit_tests.zig` as manually generated but lint
it to ensure everything with a `test` block is included.
@cb22 cb22 force-pushed the cb22/forget-me-not branch from 4d7ab3e to 1fbbff5 Compare August 6, 2025 11:50
matklad
matklad previously approved these changes Aug 6, 2025
@matklad
Copy link
Member

matklad commented Aug 6, 2025

failed: src/unit_tests.zig: error: 'build_root' is dead code

@cb22
Copy link
Member Author

cb22 commented Aug 6, 2025

Oops, sorted.

@cb22 cb22 enabled auto-merge August 6, 2025 11:57
@cb22 cb22 added this pull request to the merge queue Aug 6, 2025
Merged via the queue into main with commit 61eb3fb Aug 6, 2025
38 checks passed
@cb22 cb22 deleted the cb22/forget-me-not branch August 6, 2025 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants