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  }