github.com/linuxboot/fiano@v1.2.0/pkg/visitors/repack_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 visitors
     6  
     7  import (
     8  	"encoding/binary"
     9  	"testing"
    10  
    11  	"github.com/linuxboot/fiano/pkg/compression"
    12  	"github.com/linuxboot/fiano/pkg/guid"
    13  	"github.com/linuxboot/fiano/pkg/log"
    14  	"github.com/linuxboot/fiano/pkg/uefi"
    15  )
    16  
    17  var (
    18  	file1GUID = guid.MustParse("01234567-89AB-CDEF-0123-456789ABCDEF")
    19  	file2GUID = guid.MustParse("DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF")
    20  
    21  	ss1 *uefi.Section
    22  	ss2 *uefi.Section
    23  	rs1 *uefi.Section
    24  	cs1 *uefi.Section
    25  	cs2 *uefi.Section
    26  
    27  	f1  *uefi.File
    28  	f2  *uefi.File
    29  	pfv *uefi.FirmwareVolume
    30  
    31  	err error
    32  )
    33  
    34  func init() {
    35  	// Level 2 sections: sections that are inside compressed sections.
    36  	ss1, err = uefi.CreateSection(uefi.SectionTypeRaw, []byte("Subsection 1 data"), nil, nil)
    37  	if err != nil {
    38  		log.Fatalf("%v", err)
    39  	}
    40  	ss2, err = uefi.CreateSection(uefi.SectionTypeRaw, []byte("Subsection 2 data"), nil, nil)
    41  	if err != nil {
    42  		log.Fatalf("%v", err)
    43  	}
    44  
    45  	// Level 1 sections: includes guid defined compression sections.
    46  	cs1, err = uefi.CreateSection(uefi.SectionTypeGUIDDefined, nil, []uefi.Firmware{ss1}, &compression.LZMAGUID)
    47  	if err != nil {
    48  		log.Fatalf("%v", err)
    49  	}
    50  	rs1, err = uefi.CreateSection(uefi.SectionTypeRaw, []byte("Raw section data"), nil, nil)
    51  	if err != nil {
    52  		log.Fatalf("%v", err)
    53  	}
    54  	cs2, err = uefi.CreateSection(uefi.SectionTypeGUIDDefined, nil, []uefi.Firmware{ss2}, &compression.LZMAGUID)
    55  	if err != nil {
    56  		log.Fatalf("%v", err)
    57  	}
    58  
    59  	// Sample Files
    60  	f1 = &uefi.File{}
    61  	f1.Header.GUID = *file1GUID
    62  	f1.Header.Type = uefi.FVFileTypeDriver
    63  	f1.Sections = []*uefi.Section{rs1, cs1}
    64  
    65  	f2 = &uefi.File{}
    66  	f2.Header.GUID = *file2GUID
    67  	f2.Header.Type = uefi.FVFileTypeDriver
    68  	f2.Sections = []*uefi.Section{cs2}
    69  
    70  	// Sample original firmware volume
    71  	pfv = &uefi.FirmwareVolume{}
    72  	pfv.FileSystemGUID = *uefi.FFS2
    73  	pfv.Signature = binary.LittleEndian.Uint32([]byte("_FVH"))
    74  	pfv.Attributes = 0x89ABCDEF
    75  	pfv.Revision = 0xFF
    76  	pfv.Blocks = []uefi.Block{{Count: 1024, Size: 4096}}
    77  	pfv.HeaderLen = 56
    78  	pfv.Files = []*uefi.File{f1, f2}
    79  }
    80  
    81  func TestRepack(t *testing.T) {
    82  	if err := repackFV(pfv); err != nil {
    83  		t.Fatalf("Failed to repack firmware volume, got %v", err)
    84  	}
    85  
    86  	// pfv should have repacked firmware volume
    87  	if fvlen := len(pfv.Files); fvlen != 1 {
    88  		t.Fatalf("There should be exactly one file in repacked FV! got %v files", fvlen)
    89  	}
    90  
    91  	f := pfv.Files[0]
    92  	if f.Header.Type != uefi.FVFileTypeVolumeImage {
    93  		t.Fatalf("File should be of type EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, got %s", f.Header.Type)
    94  	}
    95  	if flen := len(f.Sections); flen != 1 {
    96  		t.Fatalf("Wrong number of sections in file, got %v", flen)
    97  	}
    98  
    99  	cs := f.Sections[0]
   100  	if cs.Header.Type != uefi.SectionTypeGUIDDefined {
   101  		t.Fatalf("Section should be of type EFI_SECTION_GUID_DEFINED, got %s", cs.Header.Type)
   102  	}
   103  	if elen := len(cs.Encapsulated); elen != 1 {
   104  		t.Fatalf("Wrong number of encapsulated section in compressed section, got %v", elen)
   105  	}
   106  
   107  	vs, ok := cs.Encapsulated[0].Value.(*uefi.Section)
   108  	if !ok {
   109  		t.Fatal("Encapsulated section was not of type uefi.Section")
   110  	}
   111  	if vs.Header.Type != uefi.SectionTypeFirmwareVolumeImage {
   112  		t.Fatalf("Section should be of type EFI_SECTION_VOLUME_IMAGE, got %s", vs.Header.Type)
   113  	}
   114  	if elen := len(vs.Encapsulated); elen != 1 {
   115  		t.Fatalf("Wrong number of encapsulated section in volume image section, got %v", elen)
   116  	}
   117  
   118  	nfv, ok := vs.Encapsulated[0].Value.(*uefi.FirmwareVolume)
   119  	if !ok {
   120  		t.Fatal("Volume Image Section did not contain firmware volume!")
   121  	}
   122  	if fvlen := len(nfv.Files); fvlen != 2 {
   123  		t.Fatalf("There should be 2 files in repacked FV! got %v files", fvlen)
   124  	}
   125  	// Check file pointers.
   126  	if nfv.Files[0] != f1 {
   127  		t.Fatalf("file 1 mismatch: expected %v, got %v", f1, nfv.Files[0])
   128  	}
   129  	if nfv.Files[1] != f2 {
   130  		t.Fatalf("file 2 mismatch: expected %v, got %v", f2, nfv.Files[1])
   131  	}
   132  
   133  	if slen := len(f1.Sections); slen != 2 {
   134  		t.Fatalf("There should be 2 sections in file 1! got %v sections", slen)
   135  	}
   136  	if f1.Sections[0] != rs1 {
   137  		t.Fatalf("file 1 section 1 mismatch: expected %v, got %v", rs1, f1.Sections[0])
   138  	}
   139  	if f1.Sections[1] != ss1 {
   140  		t.Fatalf("file 1 section 1 mismatch: expected %v, got %v", ss1, f1.Sections[1])
   141  	}
   142  
   143  	if slen := len(f2.Sections); slen != 1 {
   144  		t.Fatalf("There should be 1 sections in file 2! got %v sections", slen)
   145  	}
   146  	if f2.Sections[0] != ss2 {
   147  		t.Fatalf("file 2 mismatch: expected %v, got %v", ss2, f2.Sections[0])
   148  	}
   149  }