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  }