github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/integration/generic-tests/multiboot_test.go (about) 1 // Copyright 2019 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build !race 6 // +build !race 7 8 package integration 9 10 import ( 11 "bytes" 12 "encoding/json" 13 "fmt" 14 "os" 15 "path/filepath" 16 "reflect" 17 "testing" 18 19 "github.com/mvdan/u-root-coreutils/pkg/boot/multiboot" 20 "github.com/mvdan/u-root-coreutils/pkg/qemu" 21 "github.com/mvdan/u-root-coreutils/pkg/uroot" 22 "github.com/mvdan/u-root-coreutils/pkg/vmtest" 23 ) 24 25 func testMultiboot(t *testing.T, kernel string) { 26 var serial wc 27 28 src := fmt.Sprintf("/home/circleci/%v", kernel) 29 if tk := os.Getenv("UROOT_MULTIBOOT_TEST_KERNEL_DIR"); len(tk) > 0 { 30 src = filepath.Join(tk, kernel) 31 } 32 if _, err := os.Stat(src); err != nil && os.IsNotExist(err) { 33 t.Skip("multiboot kernel is not present") 34 } 35 36 q, cleanup := vmtest.QEMUTest(t, &vmtest.Options{ 37 BuildOpts: uroot.Opts{ 38 ExtraFiles: []string{ 39 src + ":kernel", 40 }, 41 }, 42 TestCmds: []string{ 43 `kexec -l kernel -e -d --module="/kernel foo=bar" --module="/bbin/bb"`, 44 }, 45 QEMUOpts: qemu.Options{ 46 SerialOutput: &serial, 47 }, 48 }) 49 defer cleanup() 50 51 if err := q.Expect(`"status": "ok"`); err != nil { 52 t.Logf(serial.String()) 53 t.Fatalf(`expected '"status": "ok"', got error: %v`, err) 54 } 55 56 if err := q.Expect(`}`); err != nil { 57 t.Logf(serial.String()) 58 t.Fatalf(`expected '}' = end of JSON, got error: %v`, err) 59 } 60 61 output := serial.Bytes() 62 t.Logf(serial.String()) 63 64 i := bytes.Index(output, []byte(multiboot.DebugPrefix)) 65 if i == -1 { 66 t.Fatalf("%q prefix not found in output", multiboot.DebugPrefix) 67 } 68 output = output[i+len(multiboot.DebugPrefix):] 69 if i = bytes.Index(output, []byte{'\n'}); i == -1 { 70 t.Fatalf("Cannot find newline character") 71 } 72 var want multiboot.Description 73 if err := json.Unmarshal(output[:i], &want); err != nil { 74 t.Fatalf("Cannot unmarshal multiboot debug information: %v", err) 75 } 76 77 const starting = "Starting multiboot kernel" 78 if i = bytes.Index(output, []byte(starting)); i == -1 { 79 t.Fatalf("Multiboot kernel was not executed") 80 } 81 output = output[i+len(starting):] 82 83 var got multiboot.Description 84 if err := json.Unmarshal(output, &got); err != nil { 85 t.Fatalf("Cannot unmarshal multiboot information from executed kernel: %v", err) 86 } 87 if !reflect.DeepEqual(got, want) { 88 t.Errorf("kexec failed: got\n%#v, want\n%#v", got, want) 89 } 90 } 91 92 func TestMultiboot(t *testing.T) { 93 // TODO: support arm 94 if vmtest.TestArch() != "amd64" && vmtest.TestArch() != "arm64" { 95 t.Skipf("test not supported on %s", vmtest.TestArch()) 96 } 97 98 for _, kernel := range []string{"/kernel", "/kernel.gz"} { 99 t.Run(kernel, func(t *testing.T) { 100 testMultiboot(t, kernel) 101 }) 102 } 103 }