github.com/linuxboot/fiano@v1.2.0/pkg/visitors/insert_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  	"os"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/linuxboot/fiano/pkg/guid"
    13  	"github.com/linuxboot/fiano/pkg/uefi"
    14  )
    15  
    16  const (
    17  	insertTestFile = "../../integration/roms/testfile.ffs"
    18  )
    19  
    20  func testRunObsoleteInsert(t *testing.T, f uefi.Firmware, insertType InsertType, testGUID guid.GUID) (*Insert, error) {
    21  	file, err := os.ReadFile(insertTestFile)
    22  	if err != nil {
    23  		t.Fatal(err)
    24  	}
    25  
    26  	ffs, err := uefi.NewFile(file)
    27  	if err != nil {
    28  		t.Fatal(err)
    29  	}
    30  	// Apply the visitor.
    31  	var pred FindPredicate
    32  	if insertType == InsertTypeDXE {
    33  		pred = FindFileTypePredicate(uefi.FVFileTypeDXECore)
    34  	} else {
    35  		pred = FindFileGUIDPredicate(testGUID)
    36  	}
    37  	insert := &Insert{
    38  		Predicate:  pred,
    39  		NewFile:    ffs,
    40  		InsertType: insertType,
    41  	}
    42  
    43  	return insert, insert.Run(f)
    44  }
    45  
    46  func TestObsoleteInsert(t *testing.T) {
    47  	var tests = []struct {
    48  		name string
    49  		InsertType
    50  	}{
    51  		{InsertTypeFront.String(), InsertTypeFront},
    52  		{InsertTypeEnd.String(), InsertTypeEnd},
    53  		{InsertTypeAfter.String(), InsertTypeAfter},
    54  		{InsertTypeBefore.String(), InsertTypeBefore},
    55  		{InsertTypeDXE.String(), InsertTypeDXE},
    56  	}
    57  	for _, test := range tests {
    58  		t.Run(test.name, func(t *testing.T) {
    59  			f := parseImage(t)
    60  
    61  			_, err := testRunObsoleteInsert(t, f, test.InsertType, *testGUID)
    62  			if err != nil {
    63  				t.Fatal(err)
    64  			}
    65  
    66  			// Now check that f has two copies of testGUID (There was one, we inserted another).
    67  			// TODO: Check for position in the future to make sure we actually insert where we want to.
    68  			find := &Find{
    69  				Predicate: FindFileGUIDPredicate(*testGUID),
    70  			}
    71  			if err = find.Run(f); err != nil {
    72  				t.Fatal(err)
    73  			}
    74  			if len(find.Matches) != 2 {
    75  				t.Errorf("Incorrect number of matches after insertion! expected 2, got %v", len(find.Matches))
    76  			}
    77  		})
    78  	}
    79  }
    80  
    81  func testInsertCLI(t *testing.T, whatType InsertWhatType, wherePreposition InsertWherePreposition) {
    82  	f := parseImage(t)
    83  
    84  	args := []string{
    85  		whatType.String(),
    86  	}
    87  	switch whatType {
    88  	case InsertWhatTypeFile:
    89  		args = append(args, insertTestFile)
    90  	case InsertWhatTypePadFile:
    91  		args = append(args, "256")
    92  	default:
    93  		t.Fatalf("unknown what-type '%s'", whatType)
    94  	}
    95  
    96  	args = append(args, wherePreposition.String(), testGUID.String())
    97  
    98  	visitor, err := genInsertFileCLI()(args)
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  
   103  	if err := visitor.Run(f); err != nil {
   104  		t.Fatal(err)
   105  	}
   106  
   107  	switch whatType {
   108  	case InsertWhatTypeFile:
   109  		find := &Find{
   110  			Predicate: FindFileGUIDPredicate(*testGUID),
   111  		}
   112  		if err = find.Run(f); err != nil {
   113  			t.Fatal(err)
   114  		}
   115  		if len(find.Matches) != 2 {
   116  			t.Errorf("incorrect number of matches after insertion! expected 2, got %v", len(find.Matches))
   117  		}
   118  	case InsertWhatTypePadFile:
   119  		find := &Find{
   120  			Predicate: func(f uefi.Firmware) bool {
   121  				file, ok := f.(*uefi.File)
   122  				if !ok {
   123  					return false
   124  				}
   125  				if file.Header.GUID.String() != "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF" {
   126  					return false
   127  				}
   128  				if len(file.Buf()) != 256 {
   129  					return false
   130  				}
   131  				return true
   132  			},
   133  		}
   134  		if err = find.Run(f); err != nil {
   135  			t.Fatal(err)
   136  		}
   137  		if len(find.Matches) != 1 {
   138  			t.Errorf("incorrect number of matches after insertion! expected 1, got %v", len(find.Matches))
   139  		}
   140  	default:
   141  		t.Fatalf("unknown what-type '%s'", whatType)
   142  	}
   143  }
   144  
   145  func TestInsert(t *testing.T) {
   146  	for whatType := InsertWhatTypeUndefined + 1; whatType < EndOfInsertWhatType; whatType++ {
   147  		t.Run(whatType.String(), func(t *testing.T) {
   148  			for wherePreposition := InsertWherePrepositionUndefined + 1; wherePreposition < EndOfInsertWherePreposition; wherePreposition++ {
   149  				t.Run(wherePreposition.String(), func(t *testing.T) {
   150  					testInsertCLI(t, whatType, wherePreposition)
   151  				})
   152  			}
   153  		})
   154  	}
   155  }
   156  
   157  func TestDoubleFindInsert(t *testing.T) {
   158  	var tests = []struct {
   159  		name string
   160  		InsertType
   161  	}{
   162  		{"insert_after double result", InsertTypeAfter},
   163  	}
   164  	for _, test := range tests {
   165  		t.Run(test.name, func(t *testing.T) {
   166  			f := parseImage(t)
   167  
   168  			insert, err := testRunObsoleteInsert(t, f, test.InsertType, *testGUID)
   169  			if err != nil {
   170  				t.Fatal(err)
   171  			}
   172  
   173  			// Run it again, it should fail
   174  			if err = insert.Run(f); err == nil {
   175  				t.Fatal("Expected error, got nil.")
   176  			}
   177  			if !strings.HasPrefix(err.Error(), "more than one match, only one match allowed! got ") {
   178  				t.Errorf("Mismatched error, got %v.", err.Error())
   179  			}
   180  
   181  		})
   182  	}
   183  }
   184  
   185  func TestNoFindInsert(t *testing.T) {
   186  	var tests = []struct {
   187  		name string
   188  		InsertType
   189  	}{
   190  		{"insert_after no file", InsertTypeAfter},
   191  	}
   192  	for _, test := range tests {
   193  		t.Run(test.name, func(t *testing.T) {
   194  			f := parseImage(t)
   195  
   196  			_, err := testRunObsoleteInsert(t, f, test.InsertType,
   197  				*guid.MustParse("DECAFBAD-0000-0000-0000-000000000000"))
   198  			// It should fail due to no such file
   199  			if err == nil {
   200  				t.Fatal("Expected error, got nil.")
   201  			}
   202  			if err.Error() != "no matches found" {
   203  				t.Errorf("Mismatched error, got %v.", err.Error())
   204  			}
   205  
   206  		})
   207  	}
   208  }