milestone 18: collapse duplicated infrastructure into shared listener core, crud list helper, resource shells, transport race, name and line helpers, ui modules
CI / test (push) Successful in 1m22s
CI / test-aarch64 (push) Successful in 5m6s
CI / frontend (push) Successful in 45s
CI / cross (push) Successful in 7m53s
CI / docker (push) Failing after 1h10m57s

This commit is contained in:
2026-08-07 18:20:30 +02:00
parent c50c6d285a
commit 6f67940995
82 changed files with 3167 additions and 3114 deletions
+114 -104
View File
@@ -12,6 +12,16 @@ const cross_targets = [_][]const u8{
"aarch64-linux-musl",
};
/// The deploy target, read out of `cross_targets` so `test-aarch64` and `cross`
/// cannot describe different machines. Reordering the array is caught here
/// rather than by a qemu job that quietly ran the wrong architecture.
const aarch64_triple = cross_targets[1];
comptime {
if (!std.mem.startsWith(u8, aarch64_triple, "aarch64-")) {
@compileError("cross_targets[1] must be the aarch64 triple, found " ++ aarch64_triple);
}
}
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
@@ -109,31 +119,7 @@ pub fn build(b: *std.Build) void {
//
// No upstream issue matched a search of ziglang/zig for this behaviour;
// the reference is the 0.16.0 source lines above. See AGENTS.md.
const tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("src/tests.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
}),
});
tests.root_module.addOptions("build_options", options);
tests.root_module.linkLibrary(sqliteLibrary(b, target, optimize));
tests.root_module.linkLibrary(mbedtlsLibrary(b, target, optimize));
tests.root_module.addCSourceFile(.{ .file = b.path("src/platform/mbedtls_shim.c") });
addMbedtlsThreadingMacros(tests.root_module);
tests.root_module.addAnonymousImport("test_fixtures", .{
.root_source_file = b.path("tests/fixtures/fixtures.zig"),
});
tests.root_module.addAnonymousImport("docs_files", .{
.root_source_file = b.path("docs/docs.zig"),
});
// An anonymous-import root must be Zig, so the committed TypeScript golden
// is reached through a one-decl wrapper beside it.
tests.root_module.addAnonymousImport("contract_samples", .{
.root_source_file = b.path("web/src/lib/contract_samples.zig"),
});
tests.root_module.addAnonymousImport("web_assets", .{ .root_source_file = web_assets });
const tests = addTestSuite(b, target, optimize, options, web_assets);
const test_step = b.step("test", "Run the test suite");
test_step.dependOn(&b.addRunArtifact(tests).step);
@@ -142,61 +128,28 @@ pub fn build(b: *std.Build) void {
// the in-file tests). `-Dfuzz` opts into the LLVM backend, which `--fuzz`
// needs for sanitizer coverage; stock 0.16.0 also requires a patched
// test_runner.zig for fuzz mode — see specs/milestone-2.md.
const dns_mod = b.createModule(.{
.root_source_file = b.path("src/dns/dns.zig"),
.target = target,
.optimize = optimize,
});
const fuzz_mod = b.createModule(.{
.root_source_file = b.path("tests/fuzz/dns_fuzz.zig"),
.target = target,
.optimize = optimize,
});
fuzz_mod.addImport("dns", dns_mod);
const fuzz_tests = b.addTest(.{
addFuzzSuite(b, target, optimize, fuzz, test_step, .{
.name = "fuzz",
.use_llvm = if (fuzz) true else null,
.root_module = fuzz_mod,
.root = "tests/fuzz/dns_fuzz.zig",
.import_name = "dns",
.import_module = sourceModule(b, target, optimize, "src/dns/dns.zig"),
});
test_step.dependOn(&b.addRunArtifact(fuzz_tests).step);
const parsers_mod = b.createModule(.{
.root_source_file = b.path("src/filter/parsers.zig"),
.target = target,
.optimize = optimize,
});
const blocklist_fuzz_mod = b.createModule(.{
.root_source_file = b.path("tests/fuzz/blocklist_fuzz.zig"),
.target = target,
.optimize = optimize,
});
blocklist_fuzz_mod.addImport("parsers", parsers_mod);
const blocklist_fuzz_tests = b.addTest(.{
addFuzzSuite(b, target, optimize, fuzz, test_step, .{
.name = "blocklist-fuzz",
.use_llvm = if (fuzz) true else null,
.root_module = blocklist_fuzz_mod,
.root = "tests/fuzz/blocklist_fuzz.zig",
.import_name = "parsers",
.import_module = sourceModule(b, target, optimize, "src/filter/parsers.zig"),
});
test_step.dependOn(&b.addRunArtifact(blocklist_fuzz_tests).step);
// `src/web/http_util.zig` imports only std, so its fuzz module roots
// directly at the file — no aggregator needed (milestone-15 ruling 6c).
const http_util_mod = b.createModule(.{
.root_source_file = b.path("src/web/http_util.zig"),
.target = target,
.optimize = optimize,
});
const http_util_fuzz_mod = b.createModule(.{
.root_source_file = b.path("tests/fuzz/http_util_fuzz.zig"),
.target = target,
.optimize = optimize,
});
http_util_fuzz_mod.addImport("http_util", http_util_mod);
const http_util_fuzz_tests = b.addTest(.{
addFuzzSuite(b, target, optimize, fuzz, test_step, .{
.name = "http-util-fuzz",
.use_llvm = if (fuzz) true else null,
.root_module = http_util_fuzz_mod,
.root = "tests/fuzz/http_util_fuzz.zig",
.import_name = "http_util",
.import_module = sourceModule(b, target, optimize, "src/web/http_util.zig"),
});
test_step.dependOn(&b.addRunArtifact(http_util_fuzz_tests).step);
// The bench harness (milestone-12 ruling 1). The measured roots
// (matcher.zig, dns_cache.zig, compiler.zig) share files in their relative
@@ -226,18 +179,12 @@ pub fn build(b: *std.Build) void {
.target = target,
.optimize = optimize,
});
const compiler_fuzz_mod = b.createModule(.{
.root_source_file = b.path("tests/fuzz/compiler_fuzz.zig"),
.target = target,
.optimize = optimize,
});
compiler_fuzz_mod.addImport("core", bench_core_mod);
const compiler_fuzz_tests = b.addTest(.{
addFuzzSuite(b, target, optimize, fuzz, test_step, .{
.name = "compiler-fuzz",
.use_llvm = if (fuzz) true else null,
.root_module = compiler_fuzz_mod,
.root = "tests/fuzz/compiler_fuzz.zig",
.import_name = "core",
.import_module = bench_core_mod,
});
test_step.dependOn(&b.addRunArtifact(compiler_fuzz_tests).step);
const bench_mod = b.createModule(.{
.root_source_file = b.path("tools/bench.zig"),
@@ -256,32 +203,10 @@ pub fn build(b: *std.Build) void {
// -Dintegration stays out (ruling 7): qemu-user's slowdown makes the
// wall-clock-budgeted loopback TLS tests a flake source.
const aarch64_target = b.resolveTargetQuery(
std.Target.Query.parse(.{ .arch_os_abi = "aarch64-linux-musl" }) catch unreachable,
std.Target.Query.parse(.{ .arch_os_abi = aarch64_triple }) catch unreachable,
);
const aarch64_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("src/tests.zig"),
.target = aarch64_target,
.optimize = optimize,
.link_libc = true,
}),
});
const aarch64_tests = addTestSuite(b, aarch64_target, optimize, options, web_assets);
aarch64_tests.linkage = .static;
aarch64_tests.root_module.addOptions("build_options", options);
aarch64_tests.root_module.linkLibrary(sqliteLibrary(b, aarch64_target, optimize));
aarch64_tests.root_module.linkLibrary(mbedtlsLibrary(b, aarch64_target, optimize));
aarch64_tests.root_module.addCSourceFile(.{ .file = b.path("src/platform/mbedtls_shim.c") });
addMbedtlsThreadingMacros(aarch64_tests.root_module);
aarch64_tests.root_module.addAnonymousImport("test_fixtures", .{
.root_source_file = b.path("tests/fixtures/fixtures.zig"),
});
aarch64_tests.root_module.addAnonymousImport("docs_files", .{
.root_source_file = b.path("docs/docs.zig"),
});
aarch64_tests.root_module.addAnonymousImport("contract_samples", .{
.root_source_file = b.path("web/src/lib/contract_samples.zig"),
});
aarch64_tests.root_module.addAnonymousImport("web_assets", .{ .root_source_file = web_assets });
const aarch64_run = b.addRunArtifact(aarch64_tests);
aarch64_run.skip_foreign_checks = true;
b.step("test-aarch64", "Run the test suite for aarch64-linux-musl (use -fqemu)")
@@ -348,6 +273,91 @@ fn checkTestImports(b: *std.Build) void {
}
}
/// The `src/tests.zig` suite, wired for one target. The host build and the
/// aarch64 build take the same artifact; their only differences (`linkage` and
/// `skip_foreign_checks`) stay at the call sites.
fn addTestSuite(
b: *std.Build,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
options: *std.Build.Step.Options,
web_assets: std.Build.LazyPath,
) *std.Build.Step.Compile {
const tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("src/tests.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
}),
});
tests.root_module.addOptions("build_options", options);
tests.root_module.linkLibrary(sqliteLibrary(b, target, optimize));
tests.root_module.linkLibrary(mbedtlsLibrary(b, target, optimize));
tests.root_module.addCSourceFile(.{ .file = b.path("src/platform/mbedtls_shim.c") });
addMbedtlsThreadingMacros(tests.root_module);
tests.root_module.addAnonymousImport("test_fixtures", .{
.root_source_file = b.path("tests/fixtures/fixtures.zig"),
});
tests.root_module.addAnonymousImport("docs_files", .{
.root_source_file = b.path("docs/docs.zig"),
});
// An anonymous-import root must be Zig, so the committed TypeScript golden
// is reached through a one-decl wrapper beside it.
tests.root_module.addAnonymousImport("contract_samples", .{
.root_source_file = b.path("web/src/lib/contract_samples.zig"),
});
tests.root_module.addAnonymousImport("web_assets", .{ .root_source_file = web_assets });
return tests;
}
/// One fuzz test artifact: a module rooted at a `tests/fuzz/` file plus the one
/// named import through which that target reaches the code under test. The fuzz
/// suites cannot share `addTestSuite` — they take no `build_options`, no
/// anonymous imports and no C libraries, and they carry `use_llvm`, which the
/// main suite must not set.
fn addFuzzSuite(
b: *std.Build,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
fuzz: bool,
test_step: *std.Build.Step,
spec: struct {
name: []const u8,
root: []const u8,
import_name: []const u8,
import_module: *std.Build.Module,
},
) void {
const mod = b.createModule(.{
.root_source_file = b.path(spec.root),
.target = target,
.optimize = optimize,
});
mod.addImport(spec.import_name, spec.import_module);
const tests = b.addTest(.{
.name = spec.name,
.use_llvm = if (fuzz) true else null,
.root_module = mod,
});
test_step.dependOn(&b.addRunArtifact(tests).step);
}
/// A plain module over one source file, with no imports of its own: what a fuzz
/// target reaches its code under test through.
fn sourceModule(
b: *std.Build,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
path: []const u8,
) *std.Build.Module {
return b.createModule(.{
.root_source_file = b.path(path),
.target = target,
.optimize = optimize,
});
}
fn addExecutable(
b: *std.Build,
target: std.Build.ResolvedTarget,