github.com/linuxboot/fiano@v1.2.0/pkg/uefi/flash_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 uefi
     6  
     7  import (
     8  	"encoding/hex"
     9  	"fmt"
    10  	"testing"
    11  )
    12  
    13  var (
    14  	// Signature examples
    15  	emptySig      = make([]byte, 40)                            // Empty flash signature
    16  	ichSig        = append(FlashSignature, make([]byte, 20)...) // Old ICH version
    17  	pchSig        = append(make([]byte, 16), FlashSignature...) // New PCH version
    18  	misalignedSig = append(append(make([]byte, 10), FlashSignature...),
    19  		make([]byte, 20)...) // Misaligned flash signature
    20  
    21  	// FlashRegion Examples
    22  	fr1 = FlashRegion{Base: 1, Limit: 1}
    23  	fr2 = FlashRegion{Base: 2, Limit: 2}
    24  	fr3 = FlashRegion{Base: 3, Limit: 3}
    25  	// Region Examples
    26  	rr1 = &RawRegion{FRegion: &fr1, RegionType: RegionTypeUnknown}
    27  	br  = &BIOSRegion{FRegion: &fr2, RegionType: RegionTypeBIOS}
    28  	rr2 = &RawRegion{FRegion: &fr3, RegionType: RegionTypeUnknown}
    29  	// Empty buffer
    30  	emptyFlashBuf = make([]byte, 0x4000)
    31  
    32  	// FlashImage Region test examples
    33  	trr1 = MakeTyped(rr1)
    34  	trr2 = MakeTyped(rr2)
    35  	tbr  = MakeTyped(br)
    36  	f1   = FlashImage{buf: emptyFlashBuf, FlashSize: 0x4000, Regions: []*TypedFirmware{trr1, tbr, trr2}} // Full image
    37  	f2   = FlashImage{buf: emptyFlashBuf, FlashSize: 0x4000, Regions: []*TypedFirmware{tbr, trr2}}       // Front gap
    38  	f3   = FlashImage{buf: emptyFlashBuf, FlashSize: 0x4000, Regions: []*TypedFirmware{trr1, tbr}}       // Back gap
    39  	f4   = FlashImage{buf: emptyFlashBuf, FlashSize: 0x4000, Regions: []*TypedFirmware{trr1, trr1}}      // Overlap!
    40  	// Final result
    41  	regions = []*TypedFirmware{trr1, tbr, trr2}
    42  )
    43  
    44  func TestFindSignature(t *testing.T) {
    45  	var tests = []struct {
    46  		buf    []byte
    47  		offset int
    48  		msg    string
    49  	}{
    50  		{nil, -1,
    51  			fmt.Sprintf("flash signature not found: first 0 bytes are:\n%s", hex.Dump(nil))},
    52  		{[]byte{1, 2, 3}, -1,
    53  			fmt.Sprintf("flash signature not found: first 3 bytes are:\n%s", hex.Dump([]byte{1, 2, 3}))},
    54  		{emptySig, -1,
    55  			fmt.Sprintf("flash signature not found: first 20 bytes are:\n%s", hex.Dump(emptySig[:20]))},
    56  		{ichSig, 4, ""},
    57  		{pchSig, 20, ""},
    58  		{misalignedSig, -1,
    59  			fmt.Sprintf("flash signature not found: first 20 bytes are:\n%s", hex.Dump(misalignedSig[:20]))},
    60  	}
    61  	for _, test := range tests {
    62  		f := FlashImage{buf: test.buf}
    63  		offset, err := f.FindSignature()
    64  		if offset != test.offset {
    65  			t.Errorf("Offset was not correct, expected %v, got %v", test.offset, offset)
    66  		}
    67  		if err == nil && test.msg != "" {
    68  			t.Errorf("Error was not returned, expected %v", test.msg)
    69  		} else if err != nil && err.Error() != test.msg {
    70  			t.Errorf("Mismatched Error returned, expected \n%v\n got \n%v\n", test.msg, err.Error())
    71  		}
    72  	}
    73  }
    74  
    75  func TestIsPCH(t *testing.T) {
    76  	var tests = []struct {
    77  		buf []byte
    78  		out bool
    79  	}{
    80  		{emptySig, false},
    81  		{ichSig, false},
    82  		{pchSig, true},
    83  		{misalignedSig, false},
    84  	}
    85  	for _, test := range tests {
    86  		f := FlashImage{buf: test.buf}
    87  		out := f.IsPCH()
    88  		if out != test.out {
    89  			t.Errorf("IsPCH was not correct, expected %v, got %v for \n%s", test.out, out, hex.Dump(test.buf))
    90  		}
    91  	}
    92  }
    93  
    94  func TestFillRegionGaps(t *testing.T) {
    95  	var tests = []struct {
    96  		name string
    97  		f    FlashImage
    98  		out  []*TypedFirmware // expected output after gap filling
    99  		msg  string           // Error message
   100  	}{
   101  		{"FullImage", f1, regions, ""},
   102  		{"FrontRegionGap", f2, regions, ""},
   103  		{"BackRegionGap", f3, regions, ""},
   104  		{"OverlapRegion", f4, nil, "overlapping regions! region type Unknown Region (-1) overlaps with the previous region"},
   105  	}
   106  	for _, test := range tests {
   107  		t.Run(test.name, func(t *testing.T) {
   108  			err := test.f.fillRegionGaps()
   109  
   110  			// Check error regions
   111  			if err == nil && test.msg != "" {
   112  				t.Errorf("Error was not returned, expected %v", test.msg)
   113  			} else if err != nil && err.Error() != test.msg {
   114  				t.Errorf("Mismatched Error returned, expected \n%v\n got \n%v\n", test.msg, err.Error())
   115  			}
   116  			// for cases with no error
   117  			if test.msg == "" {
   118  				if len(test.out) != len(test.f.Regions) {
   119  					t.Fatalf("Mismatched Region length! Expected %d regions, got %d", len(test.out), len(test.f.Regions))
   120  				}
   121  				for i := range test.out {
   122  					ans := test.out[i].Value.(Region)
   123  					reg := test.f.Regions[i].Value.(Region)
   124  					if ans.Type() != reg.Type() {
   125  						t.Errorf("Region type mismatch, expected \n%v\n got \n%v\n", ans.Type(), reg.Type())
   126  					}
   127  					afr := ans.FlashRegion()
   128  					rfr := reg.FlashRegion()
   129  					if afr.Base != rfr.Base {
   130  						t.Errorf("Region base mismatch, expected \n%v\n got \n%v\n", afr.Base, rfr.Base)
   131  					}
   132  					if afr.Limit != rfr.Limit {
   133  						t.Errorf("Region Limit mismatch, expected \n%v\n got \n%v\n", afr.Limit, rfr.Limit)
   134  					}
   135  				}
   136  			}
   137  		})
   138  	}
   139  }