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