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  }