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 }