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