osbase/bringup: add bringup
Introduce a library which handles the bringup of a running environment
for supervisor runnables.
Change-Id: I03c049d1bac7afdc71dfa24247923070982f07cd
Reviewed-on: https://review.monogon.dev/c/monogon/+/2930
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/osbase/bringup/test/run_test.go b/osbase/bringup/test/run_test.go
new file mode 100644
index 0000000..3252c54
--- /dev/null
+++ b/osbase/bringup/test/run_test.go
@@ -0,0 +1,90 @@
+package test
+
+import (
+ "context"
+ "testing"
+ "time"
+
+ "github.com/bazelbuild/rules_go/go/runfiles"
+
+ "source.monogon.dev/osbase/cmd"
+)
+
+var (
+ // These are filled by bazel at linking time with the canonical path of
+ // their corresponding file. Inside the init function we resolve it
+ // with the rules_go runfiles package to the real path.
+ xOvmfCodePath string
+ xOvmfVarsPath string
+ xQemuPath string
+ xSucceedKernelPath string
+ xFailedKernelPath string
+)
+
+func init() {
+ var err error
+ for _, path := range []*string{
+ &xOvmfCodePath, &xOvmfVarsPath, &xQemuPath,
+ &xSucceedKernelPath, &xFailedKernelPath,
+ } {
+ *path, err = runfiles.Rlocation(*path)
+ if err != nil {
+ panic(err)
+ }
+ }
+}
+
+// runQemu starts a new QEMU process, expecting the given output to appear
+// in any line printed. It returns true, if the expected string was found,
+// and false otherwise.
+//
+// QEMU is killed shortly after the string is found, or when the context is
+// cancelled.
+func runQemu(ctx context.Context, args []string, expectedOutput string) (bool, error) {
+ defaultArgs := []string{
+ "-machine", "q35", "-accel", "kvm", "-nographic", "-nodefaults",
+ "-m", "512",
+ "-smp", "2",
+ "-cpu", "host",
+ "-drive", "if=pflash,format=raw,snapshot=on,file=" + xOvmfCodePath,
+ "-drive", "if=pflash,format=raw,readonly=on,file=" + xOvmfVarsPath,
+ "-serial", "stdio",
+ "-no-reboot",
+ }
+ qemuArgs := append(defaultArgs, args...)
+ pf := cmd.TerminateIfFound(expectedOutput, nil)
+ return cmd.RunCommand(ctx, xQemuPath, qemuArgs, pf)
+}
+
+func TestBringupSuccess(t *testing.T) {
+ ctx, ctxC := context.WithTimeout(context.Background(), time.Second*30)
+ defer ctxC()
+
+ extraArgs := append([]string(nil), "-kernel", xSucceedKernelPath)
+
+ // Run QEMU. Expect the installer to succeed with a predefined error string.
+ expectedOutput := "_BRINGUP_LAUNCH_SUCCESS_"
+ result, err := runQemu(ctx, extraArgs, expectedOutput)
+ if err != nil {
+ t.Error(err.Error())
+ }
+ if !result {
+ t.Errorf("QEMU didn't produce the expected output %q", expectedOutput)
+ }
+}
+func TestBringupFailed(t *testing.T) {
+ ctx, ctxC := context.WithTimeout(context.Background(), time.Second*30)
+ defer ctxC()
+
+ extraArgs := append([]string(nil), "-kernel", xFailedKernelPath)
+
+ // Run QEMU. Expect the installer to fail with a predefined error string.
+ expectedOutput := "root runnable paniced"
+ result, err := runQemu(ctx, extraArgs, expectedOutput)
+ if err != nil {
+ t.Error(err.Error())
+ }
+ if !result {
+ t.Errorf("QEMU didn't produce the expected output %q", expectedOutput)
+ }
+}