github.com/linuxboot/fiano@v1.2.0/pkg/fmap/fmap_test.go (about) 1 // Copyright 2017-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 fmap 6 7 import ( 8 "bytes" 9 "crypto/sha256" 10 "fmt" 11 "reflect" 12 "strings" 13 "testing" 14 ) 15 16 // Flash map is stored in little-endian. 17 var fmapName = []byte("Fake flash" + strings.Repeat("\x00", 32-10)) 18 var area0Name = []byte("Area Number 1\x00\x00\x00Hello" + strings.Repeat("\x00", 32-21)) 19 var area1Name = []byte("Area Number 2xxxxxxxxxxxxxxxxxxx") 20 var fakeFlash = bytes.Join([][]byte{ 21 // Arbitrary data 22 bytes.Repeat([]byte{0x53, 0x11, 0x34, 0x22}, 94387), 23 24 // Signature 25 Signature, 26 // VerMajor, VerMinor 27 {1, 0}, 28 // Base 29 {0xef, 0xbe, 0xad, 0xde, 0xbe, 0xba, 0xfe, 0xca}, 30 // Size 31 {0x11, 0x22, 0x33, 0x44}, 32 // Name (32 bytes) 33 fmapName, 34 // NAreas 35 {0x02, 0x00}, 36 37 // Areas[0].Offset 38 {0xef, 0xbe, 0xad, 0xde}, 39 // Areas[0].Size 40 {0x11, 0x11, 0x11, 0x11}, 41 // Areas[0].Name (32 bytes) 42 area0Name, 43 // Areas[0].Flags 44 {0x13, 0x10}, 45 46 // Areas[1].Offset 47 {0xbe, 0xba, 0xfe, 0xca}, 48 // Areas[1].Size 49 {0x22, 0x22, 0x22, 0x22}, 50 // Areas[1].Name (32 bytes) 51 area1Name, 52 // Areas[1].Flags 53 {0x00, 0x00}, 54 }, []byte{}) 55 56 func TestReadFMap(t *testing.T) { 57 r := bytes.NewReader(fakeFlash) 58 fmap, _, err := Read(r) 59 if err != nil { 60 t.Fatal(err) 61 } 62 expected := FMap{ 63 Header: Header{ 64 VerMajor: 1, 65 VerMinor: 0, 66 Base: 0xcafebabedeadbeef, 67 Size: 0x44332211, 68 NAreas: 2, 69 }, 70 Areas: []Area{ 71 { 72 Offset: 0xdeadbeef, 73 Size: 0x11111111, 74 Flags: 0x1013, 75 }, { 76 Offset: 0xcafebabe, 77 Size: 0x22222222, 78 Flags: 0x0000, 79 }, 80 }, 81 } 82 copy(expected.Signature[:], []byte("__FMAP__")) 83 copy(expected.Name.Value[:], fmapName) 84 copy(expected.Areas[0].Name.Value[:], area0Name) 85 copy(expected.Areas[1].Name.Value[:], area1Name) 86 if !reflect.DeepEqual(*fmap, expected) { 87 t.Errorf("expected:\n%+v\ngot:\n%+v", expected, *fmap) 88 } 89 } 90 91 func TestReadMetadata(t *testing.T) { 92 r := bytes.NewReader(fakeFlash) 93 _, metadata, err := Read(r) 94 if err != nil { 95 t.Fatal(err) 96 } 97 expected := Metadata{ 98 Start: 4 * 94387, 99 } 100 if !reflect.DeepEqual(*metadata, expected) { 101 t.Errorf("expected:\n%+v\ngot:\n%+v", expected, *metadata) 102 } 103 } 104 105 func TestFieldNames(t *testing.T) { 106 r := bytes.NewReader(fakeFlash) 107 fmap, _, err := Read(r) 108 if err != nil { 109 t.Fatal(err) 110 } 111 for i, expected := range []string{"STATIC|COMPRESSED|0x1010", "0x0"} { 112 got := FlagNames(fmap.Areas[i].Flags) 113 if got != expected { 114 t.Errorf("expected:\n%s\ngot:\n%s", expected, got) 115 } 116 } 117 } 118 119 func TestNoSignature(t *testing.T) { 120 fakeFlash := bytes.Repeat([]byte{0x53, 0x11, 0x34, 0x22}, 94387) 121 r := bytes.NewReader(fakeFlash) 122 _, _, got := Read(r) 123 if want := errSigNotFound; got != want { 124 t.Errorf("Read(%v) = %v, want %v", r, got, want) 125 } 126 } 127 128 func TestTwoSignatures(t *testing.T) { 129 fakeFlash := bytes.Repeat(fakeFlash, 2) 130 r := bytes.NewReader(fakeFlash) 131 _, _, got := Read(r) 132 if want := errMultipleFound; got != want { 133 t.Errorf("Read(%v) = %v, want %v", r, got, want) 134 } 135 } 136 137 func TestTruncatedFmap(t *testing.T) { 138 r := bytes.NewReader(fakeFlash[:len(fakeFlash)-2]) 139 _, _, got := Read(r) 140 if want := errEOF; got != want { 141 t.Errorf("Read(%v) = %v, want %v", r, got, want) 142 } 143 144 } 145 146 func TestIndexOfArea(t *testing.T) { 147 r := bytes.NewReader(fakeFlash) 148 fmap, _, err := Read(r) 149 if err != nil { 150 t.Fatal(err) 151 } 152 tests := []struct { 153 name string 154 index int 155 }{ 156 {strings.TrimRight(string(area0Name), "\x00"), 0}, 157 {strings.TrimRight(string(area1Name), "\x00"), 1}, 158 {"not an area name", -1}, 159 } 160 for _, tt := range tests { 161 t.Run(tt.name, func(t *testing.T) { 162 index := fmap.IndexOfArea(tt.name) 163 if index != tt.index { 164 t.Errorf("expected index: %d, got index: %d", tt.index, index) 165 } 166 }) 167 } 168 } 169 170 func TestReadArea(t *testing.T) { 171 fmap := FMap{ 172 Header: Header{ 173 NAreas: 3, 174 }, 175 Areas: []Area{ 176 { 177 Offset: 0x0, 178 Size: 0x10, 179 }, { 180 Offset: 0x10, 181 Size: 0x20, 182 }, { 183 Offset: 0x30, 184 Size: 0x40, 185 }, 186 }, 187 } 188 fakeFlash := bytes.Repeat([]byte{0x53, 0x11, 0x34, 0x22}, 0x70) 189 r := bytes.NewReader(fakeFlash) 190 got, err := fmap.ReadArea(r, 1) 191 if err != nil { 192 t.Fatal(err) 193 } 194 expected := fakeFlash[0x10:0x30] 195 if !bytes.Equal(expected, got) { 196 t.Errorf("expected: %v; got: %v", expected, got) 197 } 198 } 199 200 func TestReadAreaByName(t *testing.T) { 201 fmap := FMap{ 202 Header: Header{ 203 NAreas: 3, 204 }, 205 Areas: []Area{ 206 { 207 Offset: 0x0, 208 Size: 0x10, 209 }, { 210 Offset: 0x10, 211 Size: 0x20, 212 }, { 213 Offset: 0x30, 214 Size: 0x40, 215 }, 216 }, 217 } 218 copy(fmap.Areas[0].Name.Value[:], []byte("Area 1\x00")) 219 copy(fmap.Areas[1].Name.Value[:], []byte("Area 2\x00")) 220 copy(fmap.Areas[2].Name.Value[:], []byte("Area 3\x00")) 221 fakeFlash := bytes.Repeat([]byte{0x53, 0x11, 0x34, 0x22}, 0x70) 222 r := bytes.NewReader(fakeFlash) 223 got, err := fmap.ReadAreaByName(r, "Area 3") 224 if err != nil { 225 t.Fatal(err) 226 } 227 expected := fakeFlash[0x30:0x70] 228 if !bytes.Equal(expected, got) { 229 t.Errorf("expected: %v; got: %v", expected, got) 230 } 231 } 232 233 type testBuffer struct { 234 buf []byte 235 } 236 237 func (b *testBuffer) WriteAt(p []byte, off int64) (n int, err error) { 238 if off+int64(len(p)) > int64(len(b.buf)) { 239 return 0, fmt.Errorf("out of bounds: %d > %d", 240 off+int64(len(p)), int64(len(b.buf))) 241 } 242 copy(b.buf[off:], p) 243 return len(p), nil 244 } 245 246 func TestWriteAreaByName(t *testing.T) { 247 fmap := FMap{ 248 Header: Header{ 249 NAreas: 3, 250 }, 251 Areas: []Area{ 252 { 253 Offset: 0x0, 254 Size: 0x10, 255 }, { 256 Offset: 0x10, 257 Size: 0x20, 258 }, { 259 Offset: 0x30, 260 Size: 0x40, 261 }, 262 }, 263 } 264 copy(fmap.Areas[0].Name.Value[:], []byte("Area 1\x00")) 265 copy(fmap.Areas[1].Name.Value[:], []byte("Area 2\x00")) 266 copy(fmap.Areas[2].Name.Value[:], []byte("Area 3\x00")) 267 fakeFlash := bytes.Repeat([]byte{0x53, 0x11, 0x34, 0x22}, 0x70) 268 w := &testBuffer{fakeFlash} 269 data := []byte("AHHHHH!!!!!!!") 270 if err := fmap.WriteAreaByName(w, "Area 2", data); err != nil { 271 t.Fatal(err) 272 } 273 got := fakeFlash[fmap.Areas[1].Offset : fmap.Areas[1].Offset+uint32(len(data))] 274 if !bytes.Equal(data, got) { 275 t.Errorf("expected: %v; got: %v", data, got) 276 } 277 } 278 279 func TestChecksum(t *testing.T) { 280 fmap := FMap{ 281 Header: Header{ 282 NAreas: 3, 283 }, 284 Areas: []Area{ 285 { 286 Offset: 0x00, 287 Size: 0x03, 288 Flags: FmapAreaStatic, 289 }, { 290 Offset: 0x03, 291 Size: 0x20, 292 Flags: 0x00, 293 }, { 294 Offset: 0x23, 295 Size: 0x04, 296 Flags: FmapAreaStatic | FmapAreaCompressed, 297 }, 298 }, 299 } 300 fakeFlash := bytes.Repeat([]byte("abcd"), 0x70) 301 r := bytes.NewReader(fakeFlash) 302 checksum, err := fmap.Checksum(r, sha256.New()) 303 if err != nil { 304 t.Fatal(err) 305 } 306 // $ echo -n abcdabc | sha256sum 307 want := "8a50a4422d673f463f8e4141d8c4b68c4f001ba16f83ad77b8a31bde53ee7273" 308 got := fmt.Sprintf("%x", checksum) 309 if want != got { 310 t.Errorf("want: %v; got: %v", want, got) 311 } 312 }