github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/boot/ebda/ebda_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 package ebda 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "strings" 11 "testing" 12 ) 13 14 func checkErrPrefix(t *testing.T, testName string, prefix string, err error) { 15 if err != nil && prefix == "" { 16 t.Errorf("test %s expected no error, got %v", testName, err) 17 } else if err == nil && prefix != "" { 18 t.Errorf("test %s expected error beginning with %s, got nil", testName, prefix) 19 } else if err != nil && prefix != "" && !strings.HasPrefix(err.Error(), prefix) { 20 t.Errorf("test %s expected error beginning with %s, got %v", testName, prefix, err) 21 } 22 } 23 24 func checkEqualsEBDA(t *testing.T, testName string, e, g *EBDA) { 25 if e != nil && g == nil { 26 t.Errorf("test %s expected EBDA %v, got nil", testName, *e) 27 } else if e == nil && g != nil { 28 t.Errorf("test %s expected no EBDA, got %v", testName, *g) 29 } else if e != nil && g != nil { 30 if e.BaseOffset != g.BaseOffset || e.Length != g.Length || !bytes.Equal(e.Data, g.Data) { 31 t.Errorf("test %s expected EBDA: \n%v,\ngot:\n%v", testName, *e, *g) 32 } 33 } 34 } 35 36 func fakeEBDA(sizeKB int) []byte { 37 b := make([]byte, sizeKB*1024) 38 if sizeKB == 0 { 39 return append(b, make([]byte, 1024)...) // Helps us test weird edge cases 40 } 41 b[0] = byte(sizeKB) 42 copy(b[16:], []byte("UROOTEBDA")) 43 return b 44 } 45 46 func fakeDevMemEBDA(offset, sizeKB int) []byte { 47 b := make([]byte, offset) 48 binOffset := uint16(offset >> 4) 49 binary.LittleEndian.PutUint16(b[EBDAAddressOffset:EBDAAddressOffset+2], binOffset) 50 b = append(b, fakeEBDA(sizeKB)...) 51 return b 52 } 53 54 func TestFindEBDAOffset(t *testing.T) { 55 for _, tt := range []struct { 56 name string 57 fakeMem []byte 58 offset int64 59 errPrefix string 60 }{ 61 { 62 name: "ReadFrom40EFail", 63 fakeMem: make([]byte, 1), 64 errPrefix: "unable to read EBDA Pointer:", 65 }, 66 { 67 name: "EmptyEBDAPointerFail", 68 fakeMem: make([]byte, EBDAAddressOffset+2), 69 errPrefix: "ebda offset is 0! unable to proceed", 70 }, 71 { 72 name: "FindEBDAOffsetSuccess", 73 fakeMem: fakeDevMemEBDA(0x9000, 1), 74 offset: 0x9000, 75 }, 76 } { 77 t.Run(tt.name, func(t *testing.T) { 78 o, err := findEBDAOffset(bytes.NewReader(tt.fakeMem)) 79 checkErrPrefix(t, tt.name, tt.errPrefix, err) 80 if o != tt.offset { 81 t.Errorf("test %s expected offset %v, got %v", tt.name, tt.offset, o) 82 } 83 }) 84 } 85 } 86 87 func TestReadEBDA(t *testing.T) { 88 for _, tt := range []struct { 89 name string 90 fakeMem []byte 91 ebda *EBDA 92 errPrefix string 93 }{ 94 { 95 name: "ReadSizeFail", 96 fakeMem: fakeDevMemEBDA(0x9000, 1)[:0x9000], // Slice before length 97 errPrefix: "error reading EBDA length, got:", 98 }, 99 { 100 name: "ReadZeroSizeFail", 101 fakeMem: fakeDevMemEBDA(0x9000, 0), // Fails because size is zero, so it tries to read to end of segment 102 errPrefix: "error reading EBDA region, tried to read from", 103 }, 104 { 105 name: "ReadEBDA", 106 fakeMem: fakeDevMemEBDA(0x9000, 1), // Fails because size is zero, so it tries to read to end of segment 107 ebda: &EBDA{ 108 BaseOffset: 0x9000, 109 Length: 1024, 110 Data: fakeEBDA(1), 111 }, 112 }, 113 } { 114 t.Run(tt.name, func(t *testing.T) { 115 g, err := ReadEBDA(bytes.NewReader(tt.fakeMem)) 116 checkErrPrefix(t, tt.name, tt.errPrefix, err) 117 checkEqualsEBDA(t, tt.name, tt.ebda, g) 118 }) 119 } 120 } 121 122 type MockByteReadWriteSeeker struct { 123 *bytes.Reader 124 } 125 126 func (MockByteReadWriteSeeker) Write(p []byte) (int, error) { 127 return len(p), nil 128 } 129 130 func TestWriteEBDA(t *testing.T) { 131 for _, tt := range []struct { 132 name string 133 fakeMem []byte 134 ebda *EBDA 135 errPrefix string 136 }{ 137 { 138 name: "NoBaseOffsetFail", 139 fakeMem: make([]byte, 1), 140 ebda: &EBDA{ 141 Length: 1024, 142 Data: fakeEBDA(1), 143 }, 144 errPrefix: "unable to read EBDA Pointer:", 145 }, 146 { 147 name: "UnalignedSizeFail", 148 fakeMem: fakeDevMemEBDA(0x9000, 1), 149 ebda: &EBDA{ 150 Length: 1023, 151 Data: fakeEBDA(1), 152 }, 153 errPrefix: "length is not an integer multiple of 1 KiB, got", 154 }, 155 { 156 name: "MismatchedSizeFail", 157 fakeMem: fakeDevMemEBDA(0x9000, 1), 158 ebda: &EBDA{ 159 BaseOffset: 0x9000, 160 Length: 1024, 161 Data: fakeEBDA(2), 162 }, 163 errPrefix: "length field is not equal to buffer length", 164 }, 165 { 166 name: "SizeTooBigFail", 167 fakeMem: fakeDevMemEBDA(0x9000, 1), 168 ebda: &EBDA{ 169 BaseOffset: 0x9000, 170 Length: 256 * 1024, 171 Data: fakeEBDA(256), 172 }, 173 errPrefix: "length is greater than 255 KiB", 174 }, 175 { 176 name: "WriteEBDA", 177 fakeMem: fakeDevMemEBDA(0x9000, 1), 178 ebda: &EBDA{ 179 BaseOffset: 0x9000, 180 Length: 1024, 181 Data: fakeEBDA(1), 182 }, 183 }, 184 } { 185 t.Run(tt.name, func(t *testing.T) { 186 err := WriteEBDA(tt.ebda, MockByteReadWriteSeeker{bytes.NewReader(tt.fakeMem)}) 187 checkErrPrefix(t, tt.name, tt.errPrefix, err) 188 }) 189 } 190 }