github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/tools/vpdbootmanager/add_test.go (about) 1 // Copyright 2017-2021 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 main 6 7 import ( 8 "encoding/json" 9 "fmt" 10 "os" 11 "path" 12 "testing" 13 14 "github.com/mvdan/u-root-coreutils/pkg/boot/systembooter" 15 ) 16 17 func TestParseNetboot(t *testing.T) { 18 b, _, err := parseNetbootFlags("dhcpv4", "aa:bb:cc:dd:ee:ff", []string{}) 19 if err != nil { 20 t.Errorf(`parseNetbootFlags("dhcpv4", "aa:bb:cc:dd:ee:ff", []string{}) = _, _, %v, want nil`, err) 21 } 22 23 if b.Type != "netboot" || b.Method != "dhcpv4" || b.MAC != "aa:bb:cc:dd:ee:ff" || b.OverrideURL != nil || b.Retries != nil { 24 t.Errorf(`b.Type, b.Method, b.MAC, b.OverrideURL, b.Retries = %q, %q, %q, %v, %v, want "netboot, "dpcpv4", "aa:bb:cc:dd:ee:ff", nil, nil`, 25 b.Type, b.Method, b.MAC, b.OverrideURL, b.Retries) 26 } 27 } 28 29 func TestParseNetbootWithFlags(t *testing.T) { 30 flags := []string{ 31 "-override-url", 32 "http://url", 33 "-retries", 34 "1", 35 "-vpd-dir", 36 "test", 37 } 38 39 b, vpdDir, err := parseNetbootFlags("dhcpv4", "aa:bb:cc:dd:ee:ff", flags) 40 if err != nil { 41 t.Errorf(`parseNetbootFlags("dhcpv4", "aa:bb:cc:dd:ee:ff", %v) = _, _, %v, want nil`, flags, err) 42 } 43 44 if *b.OverrideURL != "http://url" || *b.Retries != 1 || vpdDir != "test" { 45 t.Errorf(`*b.OverrideURL, *b.Retries, vpdDir = %q, %d, %q, want "http://url", 1, "test"`, *b.OverrideURL, *b.Retries, vpdDir) 46 } 47 } 48 49 func TestParseLocalboot(t *testing.T) { 50 b, _, err := parseLocalbootFlags("grub", []string{}) 51 if err != nil { 52 t.Errorf(`parseLocalbootFlags("grub", []string{}) = _, _, %v, want nil`, err) 53 } 54 if b.Method != "grub" { 55 t.Errorf(`b.Method = %q, want "grub"`, b.Method) 56 } 57 58 flags := []string{ 59 "device", 60 "path", 61 } 62 b, _, err = parseLocalbootFlags("path", flags) 63 if err != nil { 64 t.Errorf(`parseLocalbootFlags("grub", %v) = _, _, %v, want nil`, flags, err) 65 } 66 if b.Method != "path" || b.DeviceGUID != "device" || b.Kernel != "path" { 67 t.Errorf(`b.Method, b.DeviceGUID, b.Kernel = %q, %q, %q`, b.Method, b.DeviceGUID, b.Kernel) 68 } 69 } 70 71 func TestParseLocalbootWithFlags(t *testing.T) { 72 flags := []string{ 73 "-kernel-args", 74 "kernel-argument-test", 75 "-ramfs", 76 "ramfs-test", 77 "-vpd-dir", 78 "test", 79 } 80 b, vpdDir, err := parseLocalbootFlags("grub", flags) 81 if err != nil { 82 t.Errorf(`parseLocalbootFlags("grub", %v) = _, _, %v, want nil`, flags, err) 83 } 84 85 if b.Method != "grub" || b.KernelArgs != "kernel-argument-test" || b.Initramfs != "ramfs-test" || vpdDir != "test" { 86 t.Errorf(`b.Method, b.KernelArgs, b.Initramfs, vpdDir = %q, %q, %q, %q, want "grub", "kernel-argument-test", "ramfs-test", "test"`, 87 b.Method, b.KernelArgs, b.Initramfs, vpdDir) 88 } 89 90 flags = []string{ 91 "device", 92 "path", 93 "-kernel-args", 94 "kernel-argument-test", 95 "-ramfs", 96 "ramfs-test", 97 "-vpd-dir", 98 "test", 99 } 100 b, vpdDir, err = parseLocalbootFlags("path", flags) 101 if err != nil { 102 t.Errorf(`parseLocalbootFlags("path", %v) = _, _, %v, want nil`, flags, err) 103 } 104 if b.Method != "path" || b.DeviceGUID != "device" || b.Kernel != "path" || b.KernelArgs != "kernel-argument-test" || 105 b.Initramfs != "ramfs-test" || vpdDir != "test" { 106 t.Errorf(`b.Method, b.DeviceGUID, b.Kernel, b.KernelArgs, b.Initramfs, vpdDir = %q, %q, %q, %q, %q, %q, want "path", "device", "path", "kernel-argument-test", "ramfs-test", "test"`, 107 b.Method, b.DeviceGUID, b.Kernel, b.KernelArgs, b.Initramfs, vpdDir) 108 } 109 } 110 111 func TestFailGracefullyMissingArg(t *testing.T) { 112 err := add("localboot", []string{}) 113 if err.Error() != "you need to provide method" { 114 t.Error("error message should be: you need to provide method") 115 } 116 117 err = add("localboot", []string{"path"}) 118 if err.Error() != "you need to pass DeviceGUID and Kernel path" { 119 t.Error("error message should be: you need to pass DeviceGUID and Kernel path") 120 } 121 122 err = add("localboot", []string{"path", "device"}) 123 if err.Error() != "you need to pass DeviceGUID and Kernel path" { 124 t.Error("error message should be: you need to pass DeviceGUID and Kernel path") 125 } 126 127 err = add("netboot", []string{}) 128 if err.Error() != "you need to pass method and MAC address" { 129 t.Error("error message should be: you need to pass method and MAC address") 130 } 131 132 err = add("netboot", []string{"dhcpv6"}) 133 if err.Error() != "you need to pass method and MAC address" { 134 t.Error("error message should be: you need to pass method and MAC address") 135 } 136 } 137 138 func TestFailGracefullyBadMACAddress(t *testing.T) { 139 err := add("netboot", []string{"dhcpv6", "test"}) 140 if err.Error() != "address test: invalid MAC address" { 141 t.Errorf(`err.Error() = %q, want "error message should be: address test: invalid MAC address"`, err.Error()) 142 } 143 } 144 145 func TestFailGracefullyBadNetworkType(t *testing.T) { 146 err := add("netboot", []string{"not-valid", "test"}) 147 if err.Error() != "method needs to be either dhcpv4 or dhcpv6" { 148 t.Errorf(`err.Error() = %q, want "error message should be: method needs to be either dhcpv4 or dhcpv6"`, err.Error()) 149 } 150 } 151 152 func TestFailGracefullyBadLocalbootType(t *testing.T) { 153 err := add("localboot", []string{"not-valid"}) 154 if err.Error() != "method needs to be grub or path" { 155 t.Errorf(`err.Error() = %q, want "error message: method needs to be grub or path"`, err.Error()) 156 } 157 } 158 159 func TestFailGracefullyUnknownEntryType(t *testing.T) { 160 err := add("test", []string{}) 161 if err.Error() != "unknown entry type" { 162 t.Errorf(`err.Error() = %q, want "unknown entry type"`, err.Error()) 163 } 164 } 165 166 func TestAddBootEntry(t *testing.T) { 167 vpdDir := t.TempDir() 168 if err := os.MkdirAll(path.Join(vpdDir, "rw"), 0o700); err != nil { 169 t.Errorf(`os.MkdirAll(path.Join(%q, "rw"), 0o700) = %v, want nil`, vpdDir, err) 170 } 171 172 if err := addBootEntry(&systembooter.LocalBooter{ 173 Method: "grub", 174 }, vpdDir); err != nil { 175 t.Errorf(`addBootEntry(&systembooter.LocalBooter{"grub"}, %q) = %v, want nil`, vpdDir, err) 176 } 177 178 file, err := os.ReadFile(path.Join(vpdDir, "rw", "Boot0001")) 179 if err != nil { 180 t.Errorf(`os.ReadFile(path.Join(%q, "rw", "Boot0001") = %v, want nil`, vpdDir, err) 181 } 182 var out systembooter.LocalBooter 183 if err = json.Unmarshal([]byte(file), &out); err != nil { 184 t.Errorf(`json.Unmarshal([]byte(%v), %v) = %v, want nil`, file, &out, err) 185 } 186 187 if out.Method != "grub" { 188 t.Errorf(`out.Method = %q, want grub`, out.Method) 189 } 190 } 191 192 func TestAddBootEntryMultiple(t *testing.T) { 193 vpdDir := t.TempDir() 194 err := os.MkdirAll(path.Join(vpdDir, "rw"), 0o700) 195 if err != nil { 196 t.Errorf(`os.MkdirAll(path.Join(%q, "rw"), 0o700) = %v, want nil`, vpdDir, err) 197 } 198 199 for i := 1; i < 5; i++ { 200 if err := addBootEntry(&systembooter.LocalBooter{ 201 Method: "grub", 202 }, vpdDir); err != nil { 203 t.Errorf(`addBootEntry(&systembooter.LocalBooter{Method: "grub"}, %q) = %v, want nil`, vpdDir, err) 204 } 205 file, err := os.ReadFile(path.Join(vpdDir, "rw", fmt.Sprintf("Boot%04d", i))) 206 if err != nil { 207 t.Errorf(`os.ReadFile(path.Join(%q, "rw", fmt.Sprintf("Boot%04d", i))) = %v, want nil`, vpdDir, i, err) 208 } 209 var out systembooter.LocalBooter 210 if err := json.Unmarshal([]byte(file), &out); err != nil { 211 t.Errorf(`json.Unmarshal([]byte(%q), %v) = %v, want nil`, file, &out, err) 212 } 213 if out.Method != "grub" { 214 t.Errorf(`out.Method = %q, want grub`, out.Method) 215 } 216 } 217 }