o/t/ktest: switch to proper rule
This was previously implemented as a macro, lacking proper transitions.
Reimplement it as a proper test rule.
Change-Id: I237a2fcc29ea6dfbb294ce6313c9ff457def12b8
Reviewed-on: https://review.monogon.dev/c/monogon/+/3722
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
Tested-by: Jenkins CI
diff --git a/go/net/psample/BUILD.bazel b/go/net/psample/BUILD.bazel
index 1634ba9..9eb3378 100644
--- a/go/net/psample/BUILD.bazel
+++ b/go/net/psample/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "psample",
@@ -24,6 +24,7 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
tester = ":psample_test",
)
diff --git a/metropolis/node/core/clusternet/BUILD.bazel b/metropolis/node/core/clusternet/BUILD.bazel
index 5ab1d8a..7ee8aa1 100644
--- a/metropolis/node/core/clusternet/BUILD.bazel
+++ b/metropolis/node/core/clusternet/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "clusternet",
@@ -45,7 +45,8 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
cmdline = "ramdisk_size=128",
tester = ":clusternet_test",
)
diff --git a/metropolis/node/core/localstorage/crypt/BUILD.bazel b/metropolis/node/core/localstorage/crypt/BUILD.bazel
index 39b6a53..094fd07 100644
--- a/metropolis/node/core/localstorage/crypt/BUILD.bazel
+++ b/metropolis/node/core/localstorage/crypt/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "crypt",
@@ -31,7 +31,8 @@
embed = [":crypt"],
)
-ktest(
+k_test(
+ name = "ktest",
cmdline = "ramdisk_size=4096",
tester = ":crypt_test",
)
diff --git a/metropolis/node/core/network/dhcp4c/callback/BUILD.bazel b/metropolis/node/core/network/dhcp4c/callback/BUILD.bazel
index b6659ba..7e9827d 100644
--- a/metropolis/node/core/network/dhcp4c/callback/BUILD.bazel
+++ b/metropolis/node/core/network/dhcp4c/callback/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "callback",
@@ -31,6 +31,7 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
tester = ":callback_test",
)
diff --git a/metropolis/test/lacp/BUILD.bazel b/metropolis/test/lacp/BUILD.bazel
index b5a0f7a..9c18c2a 100644
--- a/metropolis/test/lacp/BUILD.bazel
+++ b/metropolis/test/lacp/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_test(
name = "lacptest_test",
@@ -10,7 +10,8 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
tester = ":lacptest_test",
)
diff --git a/osbase/blockdev/BUILD.bazel b/osbase/blockdev/BUILD.bazel
index a720d80..f9a8534 100644
--- a/osbase/blockdev/BUILD.bazel
+++ b/osbase/blockdev/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "blockdev",
@@ -50,6 +50,7 @@
}),
)
-ktest(
+k_test(
+ name = "ktest",
tester = ":blockdev_test",
)
diff --git a/osbase/build/def.bzl b/osbase/build/def.bzl
index 57a7dab..73752f7 100644
--- a/osbase/build/def.bzl
+++ b/osbase/build/def.bzl
@@ -49,9 +49,9 @@
},
)
-def _fsspec_core_impl(ctx, tool, output_file):
+def fsspec_core_impl(ctx, tool, output_file, extra_files = [], extra_fsspecs = []):
"""
- _fsspec_core_impl implements the core of an fsspec-based rule. It takes
+ fsspec_core_impl implements the core of an fsspec-based rule. It takes
input from the `files`,`files_cc`, `symlinks` and `fsspecs` attributes
and calls `tool` with the `-out` parameter pointing to `output_file`
and paths to all fsspecs as positional arguments.
@@ -61,7 +61,7 @@
fs_files = []
inputs = []
- for label, p in ctx.attr.files.items() + ctx.attr.files_cc.items():
+ for label, p in ctx.attr.files.items() + ctx.attr.files_cc.items() + extra_files:
if not p.startswith("/"):
fail("file {} invalid: must begin with /".format(p))
@@ -97,7 +97,7 @@
extra_specs = []
- for fsspec in ctx.attr.fsspecs:
+ for fsspec in ctx.attr.fsspecs + extra_fsspecs:
if FSSpecInfo in fsspec:
fsspec_info = fsspec[FSSpecInfo]
extra_specs.append(fsspec_info.spec)
@@ -121,7 +121,7 @@
initramfs_name = ctx.label.name + ".cpio.zst"
initramfs = ctx.actions.declare_file(initramfs_name)
- _fsspec_core_impl(ctx, ctx.executable._mkcpio, initramfs)
+ fsspec_core_impl(ctx, ctx.executable._mkcpio, initramfs)
# TODO(q3k): Document why this is needed
return [DefaultInfo(runfiles = ctx.runfiles(files = [initramfs]), files = depset([initramfs]))]
@@ -184,7 +184,7 @@
fs_name = ctx.label.name + ".img"
fs_out = ctx.actions.declare_file(fs_name)
- _fsspec_core_impl(ctx, ctx.executable._mkerofs, fs_out)
+ fsspec_core_impl(ctx, ctx.executable._mkerofs, fs_out)
return [DefaultInfo(files = depset([fs_out]))]
diff --git a/osbase/erofs/BUILD.bazel b/osbase/erofs/BUILD.bazel
index d48eb1f..52f960c 100644
--- a/osbase/erofs/BUILD.bazel
+++ b/osbase/erofs/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "erofs",
@@ -30,7 +30,8 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
cmdline = "ramdisk_size=128",
tester = ":erofs_test",
)
diff --git a/osbase/fat32/BUILD.bazel b/osbase/fat32/BUILD.bazel
index 4942844..1e0e909 100644
--- a/osbase/fat32/BUILD.bazel
+++ b/osbase/fat32/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "fat32",
@@ -35,7 +35,8 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
cmdline = "ramdisk_size=266240",
tester = ":fat32_test",
)
diff --git a/osbase/fsquota/BUILD.bazel b/osbase/fsquota/BUILD.bazel
index 7c62fd7..75a3133 100644
--- a/osbase/fsquota/BUILD.bazel
+++ b/osbase/fsquota/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "fsquota",
@@ -23,7 +23,8 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
cmdline = "ramdisk_size=51200",
files_cc = {
"@xfsprogs//:mkfs": "/mkfs.xfs",
diff --git a/osbase/gpt/BUILD.bazel b/osbase/gpt/BUILD.bazel
index 67a54ee..6c561d4 100644
--- a/osbase/gpt/BUILD.bazel
+++ b/osbase/gpt/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "gpt",
@@ -31,7 +31,8 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
cmdline = "ramdisk_size=4096",
tester = ":gpt_test",
)
diff --git a/osbase/kmod/BUILD.bazel b/osbase/kmod/BUILD.bazel
index 4bf0fb5..ce37542 100644
--- a/osbase/kmod/BUILD.bazel
+++ b/osbase/kmod/BUILD.bazel
@@ -1,6 +1,6 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("//osbase/build/fwprune:def.bzl", "fsspec_linux_firmware")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "kmod",
@@ -41,7 +41,8 @@
metadata = "@linux-firmware//:metadata",
)
-ktest(
+k_test(
+ name = "ktest",
fsspecs = [
":firmware",
],
diff --git a/osbase/loop/BUILD.bazel b/osbase/loop/BUILD.bazel
index cc52c8d..eca8529 100644
--- a/osbase/loop/BUILD.bazel
+++ b/osbase/loop/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "loop",
@@ -20,6 +20,7 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
tester = ":loop_test",
)
diff --git a/osbase/test/ktest/ktest.bzl b/osbase/test/ktest/ktest.bzl
index 614832d..42e6b60 100644
--- a/osbase/test/ktest/ktest.bzl
+++ b/osbase/test/ktest/ktest.bzl
@@ -18,41 +18,118 @@
Ktest provides a macro to run tests under a normal Metropolis node kernel
"""
-load("//osbase/build:def.bzl", "node_initramfs")
+load("//osbase/build:def.bzl", "FSSpecInfo", "build_pure_transition", "build_static_transition", "fsspec_core_impl")
-def _dict_union(x, y):
- z = {}
- z.update(x)
- z.update(y)
- return z
+_KTEST_SCRIPT = """
+#!/usr/bin/env bash
-def ktest(tester, cmdline = "", files = {}, fsspecs = [], files_cc = {}):
- node_initramfs(
- name = "test_initramfs",
- fsspecs = [
- "//osbase/build:earlydev.fsspec",
- ] + fsspecs,
- files = _dict_union({
- "//osbase/test/ktest/init": "/init",
- tester: "/tester",
- }, files),
- files_cc = files_cc,
- testonly = True,
+exec "{ktest}" -initrd-path "{initrd}" -kernel-path "{kernel}" -cmdline "{cmdline}"
+"""
+
+def _ktest_impl(ctx):
+ initramfs_name = ctx.label.name + ".cpio.zst"
+ initramfs = ctx.actions.declare_file(initramfs_name)
+
+ fsspec_core_impl(ctx, ctx.executable._mkcpio, initramfs, [(ctx.attr._ktest_init[0], "/init"), (ctx.attr.tester[0], "/tester")], [ctx.attr._earlydev])
+
+ script_file = ctx.actions.declare_file(ctx.label.name + ".sh")
+
+ ctx.actions.write(
+ output = script_file,
+ content = _KTEST_SCRIPT.format(
+ ktest = ctx.executable._ktest.short_path,
+ initrd = initramfs.short_path,
+ kernel = ctx.file.kernel.short_path,
+ cmdline = ctx.attr.cmdline,
+ ),
+ is_executable = True,
)
- native.sh_test(
- name = "ktest",
- args = [
- "$(location //osbase/test/ktest)",
- "$(location :test_initramfs)",
- "$(location //osbase/test/ktest:linux-testing)",
- cmdline,
- ],
- size = "small",
- srcs = ["//osbase/test/ktest:test-script"],
- data = [
- "//osbase/test/ktest",
- ":test_initramfs",
- "//osbase/test/ktest:linux-testing",
- ],
- )
+ return [DefaultInfo(
+ executable = script_file,
+ runfiles = ctx.runfiles(
+ files = [ctx.files._ktest[0], initramfs, ctx.file.kernel, ctx.file.tester],
+ ),
+ )]
+
+k_test = rule(
+ implementation = _ktest_impl,
+ doc = """
+ Run a given test program under the Monogon kernel.
+ """,
+ attrs = {
+ "tester": attr.label(
+ mandatory = True,
+ executable = True,
+ allow_single_file = True,
+ # Runs inside the given kernel, needs to be build for Linux/static
+ cfg = build_static_transition,
+ ),
+ "files": attr.label_keyed_string_dict(
+ allow_files = True,
+ doc = """
+ Dictionary of Labels to String, placing a given Label's output file in the initramfs at the location
+ specified by the String value. The specified labels must only have a single output.
+ """,
+ # Attach pure transition to ensure all binaries added to the initramfs are pure/static binaries.
+ cfg = build_pure_transition,
+ ),
+ "files_cc": attr.label_keyed_string_dict(
+ allow_files = True,
+ doc = """
+ Special case of 'files' for compilation targets that need to be built with the musl toolchain like
+ go_binary targets which need cgo or cc_binary targets.
+ """,
+ # Attach static transition to all files_cc inputs to ensure they are built with musl and static.
+ cfg = build_static_transition,
+ ),
+ "symlinks": attr.string_dict(
+ default = {},
+ doc = """
+ Symbolic links to create. Similar format as in files and files_cc, so the target of the symlink is the
+ key and the value of it is the location of the symlink itself. Only raw strings are allowed as targets,
+ labels are not permitted. Include the file using files or files_cc, then symlink to its location.
+ """,
+ ),
+ "fsspecs": attr.label_list(
+ default = [],
+ doc = """
+ List of file system specs (osbase.build.fsspec.FSSpec) to also include in the resulting image.
+ These will be merged with all other given attributes.
+ """,
+ providers = [FSSpecInfo],
+ allow_files = True,
+ ),
+ "kernel": attr.label(
+ default = Label("//osbase/test/ktest:linux-testing"),
+ cfg = "exec",
+ allow_single_file = True,
+ ),
+ "cmdline": attr.string(
+ default = "",
+ ),
+ # Tool
+ "_ktest": attr.label(
+ default = Label("//osbase/test/ktest"),
+ cfg = "exec",
+ executable = True,
+ allow_files = True,
+ ),
+ "_ktest_init": attr.label(
+ default = Label("//osbase/test/ktest/init"),
+ cfg = build_pure_transition,
+ executable = True,
+ allow_single_file = True,
+ ),
+ "_mkcpio": attr.label(
+ default = Label("//osbase/build/mkcpio"),
+ executable = True,
+ cfg = "exec",
+ ),
+ "_earlydev": attr.label(
+ default = Label("//osbase/build:earlydev.fsspec"),
+ allow_files = True,
+ ),
+ },
+ test = True,
+)
diff --git a/osbase/test/launch/launch.go b/osbase/test/launch/launch.go
index cf165a1..df84e7d 100644
--- a/osbase/test/launch/launch.go
+++ b/osbase/test/launch/launch.go
@@ -294,7 +294,7 @@
}
var stdErrBuf bytes.Buffer
- cmd := exec.CommandContext(ctx, "qemu-system-x86_64", append(baseArgs, extraArgs...)...)
+ cmd := exec.CommandContext(ctx, "/usr/bin/qemu-system-x86_64", append(baseArgs, extraArgs...)...)
cmd.Stdout = opts.SerialPort
cmd.Stderr = &stdErrBuf
diff --git a/osbase/verity/BUILD.bazel b/osbase/verity/BUILD.bazel
index 69cd10f..c44dd2a 100644
--- a/osbase/verity/BUILD.bazel
+++ b/osbase/verity/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//osbase/test/ktest:ktest.bzl", "ktest")
+load("//osbase/test/ktest:ktest.bzl", "k_test")
go_library(
name = "verity",
@@ -19,7 +19,8 @@
],
)
-ktest(
+k_test(
+ name = "ktest",
cmdline = "ramdisk_size=16384",
tester = ":verity_test",
)