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 }