github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/boot/uefi/uefi_test.go (about) 1 // Copyright 2021 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 package uefi 6 7 import ( 8 "fmt" 9 "strings" 10 "testing" 11 12 "github.com/mvdan/u-root-coreutils/pkg/acpi" 13 "github.com/mvdan/u-root-coreutils/pkg/boot/kexec" 14 ) 15 16 type kexecLoadFunc func(entry uintptr, segments kexec.Segments, flags uint64) error 17 18 // TODO(chengchieh): move this function to kexec package 19 func mockKexecLoad(entry uintptr, segments kexec.Segments, flags uint64) error { 20 if len(segments) > 16 { 21 return fmt.Errorf("number of segments should be less than 16 before dedup") 22 } 23 24 segments, err := kexec.AlignAndMerge(segments) 25 if err != nil { 26 return fmt.Errorf("could not align segments: %w", err) 27 } 28 29 if !segments.PhysContains(entry) { 30 return fmt.Errorf("entry point %#v is not covered by any segment", entry) 31 } 32 return nil 33 } 34 35 func mockKexecParseMemoryMap() (kexec.MemoryMap, error) { 36 return kexec.MemoryMap{}, nil 37 } 38 39 func mockGetRSDP() (*acpi.RSDP, error) { 40 return &acpi.RSDP{}, nil 41 } 42 43 func mockGetSMBIOSBase() (int64, int64, error) { 44 return 100, 200, nil 45 } 46 47 func TestLoadFvImage(t *testing.T) { 48 fv, err := New("testdata/fv_with_sec.fd") 49 if err != nil { 50 t.Fatal(err) 51 } 52 53 defer func(old func() (kexec.MemoryMap, error)) { kexecParseMemoryMap = old }(kexecParseMemoryMap) 54 kexecParseMemoryMap = mockKexecParseMemoryMap 55 56 defer func(old func() (*acpi.RSDP, error)) { getRSDP = old }(getRSDP) 57 getRSDP = mockGetRSDP 58 59 defer func(old func() (int64, int64, error)) { getSMBIOSBase = old }(getSMBIOSBase) 60 getSMBIOSBase = mockGetSMBIOSBase 61 62 defer func(old kexecLoadFunc) { kexecLoad = old }(kexecLoad) 63 kexecLoad = mockKexecLoad 64 65 if err = fv.Load(true); err != nil { 66 t.Fatal(err) 67 } 68 } 69 70 func TestNewNotFound(t *testing.T) { 71 _, err := New("testdata/uefi_NOT_FOUND.fd") 72 want := "open testdata/uefi_NOT_FOUND.fd: no such file or directory" 73 if err.Error() != want { 74 t.Fatalf("Should be '%s', but get '%v'", want, err) 75 } 76 } 77 78 func TestNewInvalidPayload(t *testing.T) { 79 _, err := New("testdata/fv_with_invalid_sec.fd") 80 // for golang >= 1.7 81 want1 := "unrecognized PE machine" 82 // for golang < 1.7 83 want2 := "Unrecognised COFF file header" 84 if !(strings.Contains(err.Error(), want1) || strings.Contains(err.Error(), want2)) { 85 t.Fatalf("Should be '%s' or '%s', but get '%v'", want1, want2, err) 86 } 87 } 88 89 func TestLoadFvImageNotFound(t *testing.T) { 90 fv := &FVImage{name: "NOT_FOUND"} 91 err := fv.Load(true) 92 93 want := "open NOT_FOUND: no such file or directory" 94 95 if err.Error() != want { 96 t.Fatalf("Should be '%s', but get '%v'", want, err) 97 } 98 } 99 100 func TestLoadFvImageFailAtParseMemoryMap(t *testing.T) { 101 fv, err := New("testdata/fv_with_sec.fd") 102 if err != nil { 103 t.Fatal(err) 104 } 105 106 defer func(old func() (kexec.MemoryMap, error)) { kexecParseMemoryMap = old }(kexecParseMemoryMap) 107 kexecParseMemoryMap = func() (kexec.MemoryMap, error) { 108 return nil, fmt.Errorf("PARSE_MEMORY_MAP_FAILED") 109 } 110 111 err = fv.Load(true) 112 113 want := "PARSE_MEMORY_MAP_FAILED" 114 if err.Error() != want { 115 t.Fatalf("want '%s', get '%v'", want, err) 116 } 117 } 118 119 func TestLoadFvImageFailAtGetRSDP(t *testing.T) { 120 fv, err := New("testdata/fv_with_sec.fd") 121 if err != nil { 122 t.Fatal(err) 123 } 124 125 defer func(old func() (kexec.MemoryMap, error)) { kexecParseMemoryMap = old }(kexecParseMemoryMap) 126 kexecParseMemoryMap = mockKexecParseMemoryMap 127 128 defer func(old func() (*acpi.RSDP, error)) { getRSDP = old }(getRSDP) 129 getRSDP = func() (*acpi.RSDP, error) { 130 return nil, fmt.Errorf("RSDP_NOT_FOUND") 131 } 132 133 err = fv.Load(true) 134 135 want := "RSDP_NOT_FOUND" 136 if err.Error() != want { 137 t.Fatalf("want '%s', get '%v'", want, err) 138 } 139 } 140 141 func TestLoadFvImageFailAtGetSMBIOS(t *testing.T) { 142 fv, err := New("testdata/fv_with_sec.fd") 143 if err != nil { 144 t.Fatal(err) 145 } 146 147 defer func(old func() (kexec.MemoryMap, error)) { kexecParseMemoryMap = old }(kexecParseMemoryMap) 148 kexecParseMemoryMap = mockKexecParseMemoryMap 149 150 defer func(old func() (*acpi.RSDP, error)) { getRSDP = old }(getRSDP) 151 getRSDP = mockGetRSDP 152 153 defer func(old func() (int64, int64, error)) { getSMBIOSBase = old }(getSMBIOSBase) 154 getSMBIOSBase = func() (int64, int64, error) { 155 t.Log("mock getSMBIOSBase()") 156 return 100, 200, fmt.Errorf("SMBIOS_NOT_FOUND") 157 } 158 159 err = fv.Load(true) 160 161 want := "SMBIOS_NOT_FOUND" 162 if err.Error() != want { 163 t.Fatalf("want '%s', get '%v'", want, err) 164 } 165 } 166 167 func TestLoadFvImageFailAtKexec(t *testing.T) { 168 fv, err := New("testdata/fv_with_sec.fd") 169 if err != nil { 170 t.Fatal(err) 171 } 172 173 defer func(old func() (kexec.MemoryMap, error)) { kexecParseMemoryMap = old }(kexecParseMemoryMap) 174 kexecParseMemoryMap = mockKexecParseMemoryMap 175 176 defer func(old func() (*acpi.RSDP, error)) { getRSDP = old }(getRSDP) 177 getRSDP = mockGetRSDP 178 179 defer func(old func() (int64, int64, error)) { getSMBIOSBase = old }(getSMBIOSBase) 180 getSMBIOSBase = mockGetSMBIOSBase 181 182 defer func(old kexecLoadFunc) { kexecLoad = old }(kexecLoad) 183 kexecLoad = func(entry uintptr, segments kexec.Segments, flags uint64) error { 184 return fmt.Errorf("KEXEC_FAILED") 185 } 186 187 err = fv.Load(true) 188 189 want := "kexec.Load() error: KEXEC_FAILED" 190 if err.Error() != want { 191 t.Fatalf("want '%s', get '%v'", want, err) 192 } 193 }