github.com/linuxboot/fiano@v1.2.0/pkg/visitors/createfv_test.go (about)

     1  // Copyright 2018 the LinuxBoot 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  package visitors
     6  
     7  import (
     8  	"testing"
     9  
    10  	"github.com/linuxboot/fiano/pkg/guid"
    11  	"github.com/linuxboot/fiano/pkg/uefi"
    12  )
    13  
    14  type testLayout struct {
    15  	Type   string
    16  	offset uint64
    17  	length uint64
    18  }
    19  
    20  func checkBRLayout(t *testing.T, br *uefi.BIOSRegion, layout []testLayout) {
    21  	// basic check
    22  	if len(br.Elements) != len(layout) {
    23  		t.Fatalf("wrong number of elements in BIOSRegion, got %d want %d", len(br.Elements), len(layout))
    24  	}
    25  
    26  	var nextoffset uint64
    27  	// check the final layout
    28  	for i, e := range br.Elements {
    29  		var offset, length uint64
    30  		switch f := e.Value.(type) {
    31  		case *uefi.FirmwareVolume:
    32  			offset = f.FVOffset
    33  			length = f.Length
    34  		case *uefi.BIOSPadding:
    35  			offset = f.Offset
    36  			length = uint64(len(f.Buf()))
    37  		default:
    38  			t.Fatalf("Unexpected Element at %d: %s", i, e.Type)
    39  		}
    40  		if e.Type != layout[i].Type {
    41  			t.Errorf("Wrong Element Type at %d, got %s, want %s", i, e.Type, layout[i].Type)
    42  		}
    43  		if offset != layout[i].offset {
    44  			t.Errorf("Wrong Element offset at %d, got %#x, want %#x", i, offset, layout[i].offset)
    45  		}
    46  		if length != layout[i].length {
    47  			t.Errorf("Wrong Element length at %d, got %#x, want %#x", i, length, layout[i].length)
    48  		}
    49  		// sanity check
    50  		if layout[i].offset != nextoffset {
    51  			t.Errorf("Next offset inconsistency got %#x, want %#x", layout[i].offset, nextoffset)
    52  		}
    53  		nextoffset = layout[i].offset + layout[i].length
    54  	}
    55  	if br.Length != nextoffset {
    56  		t.Errorf("Next offset inconsistency got %#x, want %#x", br.Length, nextoffset)
    57  	}
    58  
    59  }
    60  
    61  func TestInsertFVinBP(t *testing.T) {
    62  	// Create an empty BIOSRegion
    63  	buf := make([]byte, 0x10000)
    64  	uefi.Erase(buf, uefi.Attributes.ErasePolarity)
    65  	r, err := uefi.NewBIOSRegion(buf, nil, uefi.RegionTypeBIOS)
    66  	if err != nil {
    67  		t.Fatal(err)
    68  	}
    69  	br := r.(*uefi.BIOSRegion)
    70  
    71  	// Create an FV in the middle to check
    72  	// creation of padding before and after FV
    73  	fv, err := createEmptyFirmwareVolume(0x8000, 0x1000, nil)
    74  	if err != nil {
    75  		t.Fatal(err)
    76  	}
    77  	bp := br.Elements[0].Value.(*uefi.BIOSPadding)
    78  	err = insertFVinBP(br, 0x8000, bp, 0, fv)
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	// basic check
    83  	if len(br.Elements) != 3 {
    84  		t.Fatalf("wrong number of elements in BIOSRegion, got %d want 3", len(br.Elements))
    85  	}
    86  
    87  	// Create an FV at the beginning to check
    88  	// - no padding creation before the FV
    89  	// - no existing elements lost after the FV
    90  	fv, err = createEmptyFirmwareVolume(0, 0x1000, nil)
    91  	if err != nil {
    92  		t.Fatal(err)
    93  	}
    94  	bp = br.Elements[0].Value.(*uefi.BIOSPadding)
    95  	err = insertFVinBP(br, 0, bp, 0, fv)
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	// basic check
   100  	if len(br.Elements) != 4 {
   101  		t.Fatalf("wrong number of elements in BIOSRegion, got %d want 4", len(br.Elements))
   102  	}
   103  
   104  	// Create an FV just before first created FV to check
   105  	// - no padding creation after the FV
   106  	// - no existing elements lost before and after the FV
   107  	fv, err = createEmptyFirmwareVolume(0x7000, 0x1000, nil)
   108  	if err != nil {
   109  		t.Fatal(err)
   110  	}
   111  	bp = br.Elements[1].Value.(*uefi.BIOSPadding)
   112  	err = insertFVinBP(br, 0x7000, bp, 1, fv)
   113  	if err != nil {
   114  		t.Fatal(err)
   115  	}
   116  	// basic check
   117  	if len(br.Elements) != 5 {
   118  		t.Fatalf("wrong number of elements in BIOSRegion, got %d want 4", len(br.Elements))
   119  	}
   120  
   121  	var want = []testLayout{
   122  		{"*uefi.FirmwareVolume", 0, 0x1000},
   123  		{"*uefi.BIOSPadding", 0x1000, 0x6000},
   124  		{"*uefi.FirmwareVolume", 0x7000, 0x1000},
   125  		{"*uefi.FirmwareVolume", 0x8000, 0x1000},
   126  		{"*uefi.BIOSPadding", 0x9000, 0x7000},
   127  	}
   128  	checkBRLayout(t, br, want)
   129  }
   130  
   131  func TestCreateFV(t *testing.T) {
   132  	// Set erasepolarity to FF
   133  	uefi.Attributes.ErasePolarity = 0xFF
   134  	// Create an empty BIOSRegion
   135  	buf := make([]byte, 0x10000)
   136  	uefi.Erase(buf, uefi.Attributes.ErasePolarity)
   137  	r, err := uefi.NewBIOSRegion(buf, nil, uefi.RegionTypeBIOS)
   138  	if err != nil {
   139  		t.Fatal(err)
   140  	}
   141  	// Create the visitor
   142  	v := &CreateFV{
   143  		AbsOffset: 0x8000,
   144  		Size:      0x1000,
   145  		Name:      *guid.MustParse("DECAFBAD-0000-0000-0000-000000000000"),
   146  	}
   147  
   148  	if err := v.Run(r); err != nil {
   149  		t.Fatalf("Failed to create firmware volume, got %v", err)
   150  	}
   151  
   152  	br := r.(*uefi.BIOSRegion)
   153  	want := []testLayout{
   154  		{"*uefi.BIOSPadding", 0x0000, 0x8000},
   155  		{"*uefi.FirmwareVolume", 0x8000, 0x1000},
   156  		{"*uefi.BIOSPadding", 0x9000, 0x7000},
   157  	}
   158  	checkBRLayout(t, br, want)
   159  
   160  }