github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/pkg/boot/esxi/esxi_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 esxi
     6  
     7  import (
     8  	"encoding/hex"
     9  	"fmt"
    10  	"reflect"
    11  	"testing"
    12  
    13  	"github.com/u-root/u-root/pkg/boot"
    14  	"github.com/u-root/u-root/pkg/boot/multiboot"
    15  	"github.com/u-root/u-root/pkg/uio"
    16  )
    17  
    18  func TestParse(t *testing.T) {
    19  	for _, tt := range []struct {
    20  		file string
    21  		want options
    22  	}{
    23  		{
    24  			file: "testdata/kernel_cmdline_mods.cfg",
    25  			want: options{
    26  				kernel: "testdata/b.b00",
    27  				args:   "zee",
    28  				modules: []string{
    29  					"testdata/b.b00 blabla",
    30  					"testdata/k.b00",
    31  					"testdata/m.m00 marg marg2",
    32  				},
    33  			},
    34  		},
    35  		{
    36  			file: "testdata/empty_mods.cfg",
    37  			want: options{
    38  				kernel: "testdata/b.b00",
    39  				args:   "zee",
    40  			},
    41  		},
    42  		{
    43  			file: "testdata/no_mods.cfg",
    44  			want: options{
    45  				kernel: "testdata/b.b00",
    46  				args:   "zee",
    47  			},
    48  		},
    49  		{
    50  			file: "testdata/no_cmdline.cfg",
    51  			want: options{
    52  				kernel: "testdata/b.b00",
    53  			},
    54  		},
    55  		{
    56  			file: "testdata/empty_cmdline.cfg",
    57  			want: options{
    58  				kernel: "testdata/b.b00",
    59  			},
    60  		},
    61  		{
    62  			file: "testdata/empty_updated.cfg",
    63  			want: options{
    64  				kernel: "testdata/b.b00",
    65  				args:   "zee",
    66  				// Explicitly stating this as the wanted value.
    67  				updated: 0,
    68  			},
    69  		},
    70  		{
    71  			file: "testdata/updated_twice.cfg",
    72  			want: options{
    73  				kernel: "testdata/b.b00",
    74  				args:   "zee",
    75  				// Explicitly stating this as the wanted value.
    76  				updated: 0,
    77  			},
    78  		},
    79  		{
    80  			file: "testdata/updated.cfg",
    81  			want: options{
    82  				kernel:  "testdata/b.b00",
    83  				args:    "zee",
    84  				updated: 4,
    85  			},
    86  		},
    87  		{
    88  			file: "testdata/empty_bootstate.cfg",
    89  			want: options{
    90  				kernel: "testdata/b.b00",
    91  				args:   "zee",
    92  				// Explicitly stating this as the wanted value.
    93  				bootstate: bootValid,
    94  			},
    95  		},
    96  		{
    97  			file: "testdata/bootstate_twice.cfg",
    98  			want: options{
    99  				kernel: "testdata/b.b00",
   100  				args:   "zee",
   101  				// Explicitly stating this as the wanted value.
   102  				bootstate: bootValid,
   103  			},
   104  		},
   105  		{
   106  			file: "testdata/bootstate.cfg",
   107  			want: options{
   108  				kernel:    "testdata/b.b00",
   109  				args:      "zee",
   110  				bootstate: bootDirty,
   111  			},
   112  		},
   113  		{
   114  			file: "testdata/bootstate_invalid.cfg",
   115  			want: options{
   116  				kernel:    "testdata/b.b00",
   117  				args:      "zee",
   118  				bootstate: bootInvalid,
   119  			},
   120  		},
   121  		{
   122  			file: "testdata/no_bootstate.cfg",
   123  			want: options{
   124  				kernel:    "testdata/b.b00",
   125  				args:      "zee",
   126  				bootstate: bootInvalid,
   127  			},
   128  		},
   129  	} {
   130  		got, err := parse(tt.file)
   131  		if err != nil {
   132  			t.Fatalf("cannot parse config at %s: %v", tt.file, err)
   133  		}
   134  
   135  		if !reflect.DeepEqual(got, tt.want) {
   136  			t.Errorf("LoadConfig(%s) = %v want %v", tt.file, got, tt.want)
   137  		}
   138  	}
   139  }
   140  
   141  // This is in the second block of testdata/dev5 and testdata/dev6.
   142  var (
   143  	dev5GUID = "aabbccddeeff0011"
   144  	dev6GUID = "00112233445566aa"
   145  	uuid5    = hex.EncodeToString([]byte(dev5GUID))
   146  	uuid6    = hex.EncodeToString([]byte(dev6GUID))
   147  	device   = "testdata/dev"
   148  )
   149  
   150  // Poor man's equal.
   151  //
   152  // the Kernel and Modules fields will be full of uio.NewLazyFiles. We just want
   153  // them to be pointing to the same file name; we can't compare the function
   154  // pointers obviously. Lazy files will always print their name.
   155  func multibootEqual(a, b []*boot.MultibootImage) bool {
   156  	return fmt.Sprintf("%v", a) == fmt.Sprintf("%v", b)
   157  }
   158  
   159  func TestDev5Valid(t *testing.T) {
   160  	want := []*boot.MultibootImage{
   161  		{
   162  			Name:    "VMware ESXi from testdata/dev5",
   163  			Kernel:  uio.NewLazyFile("testdata/k"),
   164  			Cmdline: fmt.Sprintf(" bootUUID=%s", uuid5),
   165  			Modules: []multiboot.Module{},
   166  		},
   167  	}
   168  
   169  	opts5 := &options{
   170  		kernel:    "testdata/k",
   171  		updated:   1,
   172  		bootstate: bootValid,
   173  	}
   174  
   175  	// No opts6 at all.
   176  	imgs, _ := getImages(device, opts5, nil)
   177  	if !multibootEqual(imgs, want) {
   178  		t.Fatalf("getImages(%s, %v, %v) = %v, want %v", device, opts5, nil, imgs, want)
   179  	}
   180  
   181  	// Invalid opts6. Higher updated, but invalid state.
   182  	invalidOpts6 := &options{
   183  		kernel:    "foobar",
   184  		updated:   2,
   185  		bootstate: bootInvalid,
   186  	}
   187  	imgs, _ = getImages(device, opts5, invalidOpts6)
   188  	if !multibootEqual(imgs, want) {
   189  		t.Fatalf("getImages(%s, %v, %v) = %v, want %v", device, opts5, invalidOpts6, imgs, want)
   190  	}
   191  }
   192  
   193  func TestDev6Valid(t *testing.T) {
   194  	want := []*boot.MultibootImage{
   195  		{
   196  			Name:    "VMware ESXi from testdata/dev6",
   197  			Kernel:  uio.NewLazyFile("testdata/k"),
   198  			Cmdline: fmt.Sprintf(" bootUUID=%s", uuid6),
   199  			Modules: []multiboot.Module{},
   200  		},
   201  	}
   202  
   203  	opts6 := &options{
   204  		kernel:    "testdata/k",
   205  		updated:   1,
   206  		bootstate: bootValid,
   207  	}
   208  
   209  	// No opts5 at all.
   210  	imgs, _ := getImages(device, nil, opts6)
   211  	if !multibootEqual(imgs, want) {
   212  		t.Fatalf("getImages(%s, %v, %v) = %v, want %v", device, nil, opts6, imgs, want)
   213  	}
   214  
   215  	// Invalid opts5. Higher updated, but invalid state.
   216  	invalidOpts5 := &options{
   217  		kernel:    "foobar",
   218  		updated:   2,
   219  		bootstate: bootInvalid,
   220  	}
   221  	imgs, _ = getImages(device, invalidOpts5, opts6)
   222  	if !multibootEqual(imgs, want) {
   223  		t.Fatalf("getImages(%s, %v, %v) = %v, want %v", device, invalidOpts5, opts6, imgs, want)
   224  	}
   225  }
   226  
   227  func TestImageOrder(t *testing.T) {
   228  	prevGetBlockSize := getBlockSize
   229  	defer func() {
   230  		getBlockSize = prevGetBlockSize
   231  	}()
   232  	getBlockSize = func(dev string) (int, error) {
   233  		return 512, nil
   234  	}
   235  
   236  	opt5 := &options{
   237  		kernel:    "foobar",
   238  		updated:   2,
   239  		bootstate: bootValid,
   240  	}
   241  	want5 := &boot.MultibootImage{
   242  		Name:    "VMware ESXi from testdata/dev5",
   243  		Kernel:  uio.NewLazyFile("foobar"),
   244  		Cmdline: fmt.Sprintf(" bootUUID=%s", uuid5),
   245  		Modules: []multiboot.Module{},
   246  	}
   247  
   248  	opt6 := &options{
   249  		kernel:    "testdata/k",
   250  		updated:   1,
   251  		bootstate: bootValid,
   252  	}
   253  	want6 := &boot.MultibootImage{
   254  		Name:    "VMware ESXi from testdata/dev6",
   255  		Kernel:  uio.NewLazyFile("testdata/k"),
   256  		Cmdline: fmt.Sprintf(" bootUUID=%s", uuid6),
   257  		Modules: []multiboot.Module{},
   258  	}
   259  
   260  	// Way 1.
   261  	want := []*boot.MultibootImage{want5, want6}
   262  	imgs, _ := getImages(device, opt5, opt6)
   263  	if !multibootEqual(imgs, want) {
   264  		t.Fatalf("getImages(%s, %v, %v) = %v, want %v", device, opt5, opt6, imgs, want)
   265  	}
   266  
   267  	opt5.updated = 1
   268  	opt6.updated = 2
   269  	// Vice versa priority.
   270  	want = []*boot.MultibootImage{want6, want5}
   271  	imgs, _ = getImages(device, opt5, opt6)
   272  	if !multibootEqual(imgs, want) {
   273  		t.Fatalf("getImages(%s, %v, %v) = %v, want %v", device, opt5, opt6, imgs, want)
   274  	}
   275  }