github.com/rothwerx/packer@v0.9.0/builder/qemu/builder_test.go (about) 1 package qemu 2 3 import ( 4 "github.com/mitchellh/packer/packer" 5 "io/ioutil" 6 "os" 7 "reflect" 8 "testing" 9 ) 10 11 var testPem = ` 12 -----BEGIN RSA PRIVATE KEY----- 13 MIIEpQIBAAKCAQEAxd4iamvrwRJvtNDGQSIbNvvIQN8imXTRWlRY62EvKov60vqu 14 hh+rDzFYAIIzlmrJopvOe0clqmi3mIP9dtkjPFrYflq52a2CF5q+BdwsJXuRHbJW 15 LmStZUwW1khSz93DhvhmK50nIaczW63u4EO/jJb3xj+wxR1Nkk9bxi3DDsYFt8SN 16 AzYx9kjlEYQ/+sI4/ATfmdV9h78SVotjScupd9KFzzi76gWq9gwyCBLRynTUWlyD 17 2UOfJRkOvhN6/jKzvYfVVwjPSfA9IMuooHdScmC4F6KBKJl/zf/zETM0XyzIDNmH 18 uOPbCiljq2WoRM+rY6ET84EO0kVXbfx8uxUsqQIDAQABAoIBAQCkPj9TF0IagbM3 19 5BSs/CKbAWS4dH/D4bPlxx4IRCNirc8GUg+MRb04Xz0tLuajdQDqeWpr6iLZ0RKV 20 BvreLF+TOdV7DNQ4XE4gSdJyCtCaTHeort/aordL3l0WgfI7mVk0L/yfN1PEG4YG 21 E9q1TYcyrB3/8d5JwIkjabxERLglCcP+geOEJp+QijbvFIaZR/n2irlKW4gSy6ko 22 9B0fgUnhkHysSg49ChHQBPQ+o5BbpuLrPDFMiTPTPhdfsvGGcyCGeqfBA56oHcSF 23 K02Fg8OM+Bd1lb48LAN9nWWY4WbwV+9bkN3Ym8hO4c3a/Dxf2N7LtAQqWZzFjvM3 24 /AaDvAgBAoGBAPLD+Xn1IYQPMB2XXCXfOuJewRY7RzoVWvMffJPDfm16O7wOiW5+ 25 2FmvxUDayk4PZy6wQMzGeGKnhcMMZTyaq2g/QtGfrvy7q1Lw2fB1VFlVblvqhoJa 26 nMJojjC4zgjBkXMHsRLeTmgUKyGs+fdFbfI6uejBnnf+eMVUMIdJ+6I9AoGBANCn 27 kWO9640dttyXURxNJ3lBr2H3dJOkmD6XS+u+LWqCSKQe691Y/fZ/ZL0Oc4Mhy7I6 28 hsy3kDQ5k2V0fkaNODQIFJvUqXw2pMewUk8hHc9403f4fe9cPrL12rQ8WlQw4yoC 29 v2B61vNczCCUDtGxlAaw8jzSRaSI5s6ax3K7enbdAoGBAJB1WYDfA2CoAQO6y9Sl 30 b07A/7kQ8SN5DbPaqrDrBdJziBQxukoMJQXJeGFNUFD/DXFU5Fp2R7C86vXT7HIR 31 v6m66zH+CYzOx/YE6EsUJms6UP9VIVF0Rg/RU7teXQwM01ZV32LQ8mswhTH20o/3 32 uqMHmxUMEhZpUMhrfq0isyApAoGAe1UxGTXfj9AqkIVYylPIq2HqGww7+jFmVEj1 33 9Wi6S6Sq72ffnzzFEPkIQL/UA4TsdHMnzsYKFPSbbXLIWUeMGyVTmTDA5c0e5XIR 34 lPhMOKCAzv8w4VUzMnEkTzkFY5JqFCD/ojW57KvDdNZPVB+VEcdxyAW6aKELXMAc 35 eHLc1nkCgYEApm/motCTPN32nINZ+Vvywbv64ZD+gtpeMNP3CLrbe1X9O+H52AXa 36 1jCoOldWR8i2bs2NVPcKZgdo6fFULqE4dBX7Te/uYEIuuZhYLNzRO1IKU/YaqsXG 37 3bfQ8hKYcSnTfE0gPtLDnqCIxTocaGLSHeG3TH9fTw+dA8FvWpUztI4= 38 -----END RSA PRIVATE KEY----- 39 ` 40 41 func testConfig() map[string]interface{} { 42 return map[string]interface{}{ 43 "iso_checksum": "foo", 44 "iso_checksum_type": "md5", 45 "iso_url": "http://www.google.com/", 46 "ssh_username": "foo", 47 packer.BuildNameConfigKey: "foo", 48 } 49 } 50 51 func TestBuilder_ImplementsBuilder(t *testing.T) { 52 var raw interface{} 53 raw = &Builder{} 54 if _, ok := raw.(packer.Builder); !ok { 55 t.Error("Builder must implement builder.") 56 } 57 } 58 59 func TestBuilderPrepare_Defaults(t *testing.T) { 60 var b Builder 61 config := testConfig() 62 warns, err := b.Prepare(config) 63 if len(warns) > 0 { 64 t.Fatalf("bad: %#v", warns) 65 } 66 if err != nil { 67 t.Fatalf("should not have error: %s", err) 68 } 69 70 if b.config.OutputDir != "output-foo" { 71 t.Errorf("bad output dir: %s", b.config.OutputDir) 72 } 73 74 if b.config.SSHHostPortMin != 2222 { 75 t.Errorf("bad min ssh host port: %d", b.config.SSHHostPortMin) 76 } 77 78 if b.config.SSHHostPortMax != 4444 { 79 t.Errorf("bad max ssh host port: %d", b.config.SSHHostPortMax) 80 } 81 82 if b.config.Comm.SSHPort != 22 { 83 t.Errorf("bad ssh port: %d", b.config.Comm.SSHPort) 84 } 85 86 if b.config.VMName != "packer-foo" { 87 t.Errorf("bad vm name: %s", b.config.VMName) 88 } 89 90 if b.config.Format != "qcow2" { 91 t.Errorf("bad format: %s", b.config.Format) 92 } 93 } 94 95 func TestBuilderPrepare_BootWait(t *testing.T) { 96 var b Builder 97 config := testConfig() 98 99 // Test a default boot_wait 100 delete(config, "boot_wait") 101 warns, err := b.Prepare(config) 102 if len(warns) > 0 { 103 t.Fatalf("bad: %#v", warns) 104 } 105 if err != nil { 106 t.Fatalf("err: %s", err) 107 } 108 109 if b.config.RawBootWait != "10s" { 110 t.Fatalf("bad value: %s", b.config.RawBootWait) 111 } 112 113 // Test with a bad boot_wait 114 config["boot_wait"] = "this is not good" 115 warns, err = b.Prepare(config) 116 if len(warns) > 0 { 117 t.Fatalf("bad: %#v", warns) 118 } 119 if err == nil { 120 t.Fatal("should have error") 121 } 122 123 // Test with a good one 124 config["boot_wait"] = "5s" 125 b = Builder{} 126 warns, err = b.Prepare(config) 127 if len(warns) > 0 { 128 t.Fatalf("bad: %#v", warns) 129 } 130 if err != nil { 131 t.Fatalf("should not have error: %s", err) 132 } 133 } 134 135 func TestBuilderPrepare_DiskCompaction(t *testing.T) { 136 var b Builder 137 config := testConfig() 138 139 // Bad 140 config["skip_compaction"] = false 141 config["disk_compression"] = true 142 config["format"] = "img" 143 warns, err := b.Prepare(config) 144 if len(warns) > 0 { 145 t.Fatalf("bad: %#v", warns) 146 } 147 if err == nil { 148 t.Fatal("should have error") 149 } 150 if b.config.SkipCompaction != true { 151 t.Fatalf("SkipCompaction should be true") 152 } 153 if b.config.DiskCompression != false { 154 t.Fatalf("DiskCompression should be false") 155 } 156 157 // Good 158 config["skip_compaction"] = false 159 config["disk_compression"] = true 160 config["format"] = "qcow2" 161 b = Builder{} 162 warns, err = b.Prepare(config) 163 if len(warns) > 0 { 164 t.Fatalf("bad: %#v", warns) 165 } 166 if err != nil { 167 t.Fatalf("should not have error: %s", err) 168 } 169 if b.config.SkipCompaction != false { 170 t.Fatalf("SkipCompaction should be false") 171 } 172 if b.config.DiskCompression != true { 173 t.Fatalf("DiskCompression should be true") 174 } 175 } 176 177 func TestBuilderPrepare_DiskSize(t *testing.T) { 178 var b Builder 179 config := testConfig() 180 181 delete(config, "disk_size") 182 warns, err := b.Prepare(config) 183 if len(warns) > 0 { 184 t.Fatalf("bad: %#v", warns) 185 } 186 if err != nil { 187 t.Fatalf("bad err: %s", err) 188 } 189 190 if b.config.DiskSize != 40000 { 191 t.Fatalf("bad size: %d", b.config.DiskSize) 192 } 193 194 config["disk_size"] = 60000 195 b = Builder{} 196 warns, err = b.Prepare(config) 197 if len(warns) > 0 { 198 t.Fatalf("bad: %#v", warns) 199 } 200 if err != nil { 201 t.Fatalf("should not have error: %s", err) 202 } 203 204 if b.config.DiskSize != 60000 { 205 t.Fatalf("bad size: %d", b.config.DiskSize) 206 } 207 } 208 209 func TestBuilderPrepare_Format(t *testing.T) { 210 var b Builder 211 config := testConfig() 212 213 // Bad 214 config["format"] = "illegal value" 215 warns, err := b.Prepare(config) 216 if len(warns) > 0 { 217 t.Fatalf("bad: %#v", warns) 218 } 219 if err == nil { 220 t.Fatal("should have error") 221 } 222 223 // Good 224 config["format"] = "qcow2" 225 b = Builder{} 226 warns, err = b.Prepare(config) 227 if len(warns) > 0 { 228 t.Fatalf("bad: %#v", warns) 229 } 230 if err != nil { 231 t.Fatalf("should not have error: %s", err) 232 } 233 234 // Good 235 config["format"] = "raw" 236 b = Builder{} 237 warns, err = b.Prepare(config) 238 if len(warns) > 0 { 239 t.Fatalf("bad: %#v", warns) 240 } 241 if err != nil { 242 t.Fatalf("should not have error: %s", err) 243 } 244 } 245 246 func TestBuilderPrepare_InvalidKey(t *testing.T) { 247 var b Builder 248 config := testConfig() 249 250 // Add a random key 251 config["i_should_not_be_valid"] = true 252 warns, err := b.Prepare(config) 253 if len(warns) > 0 { 254 t.Fatalf("bad: %#v", warns) 255 } 256 if err == nil { 257 t.Fatal("should have error") 258 } 259 } 260 261 func TestBuilderPrepare_OutputDir(t *testing.T) { 262 var b Builder 263 config := testConfig() 264 265 // Test with existing dir 266 dir, err := ioutil.TempDir("", "packer") 267 if err != nil { 268 t.Fatalf("err: %s", err) 269 } 270 defer os.RemoveAll(dir) 271 272 config["output_directory"] = dir 273 b = Builder{} 274 warns, err := b.Prepare(config) 275 if len(warns) > 0 { 276 t.Fatalf("bad: %#v", warns) 277 } 278 if err == nil { 279 t.Fatal("should have error") 280 } 281 282 // Test with a good one 283 config["output_directory"] = "i-hope-i-dont-exist" 284 b = Builder{} 285 warns, err = b.Prepare(config) 286 if len(warns) > 0 { 287 t.Fatalf("bad: %#v", warns) 288 } 289 if err != nil { 290 t.Fatalf("should not have error: %s", err) 291 } 292 } 293 294 func TestBuilderPrepare_ShutdownTimeout(t *testing.T) { 295 var b Builder 296 config := testConfig() 297 298 // Test with a bad value 299 config["shutdown_timeout"] = "this is not good" 300 warns, err := b.Prepare(config) 301 if len(warns) > 0 { 302 t.Fatalf("bad: %#v", warns) 303 } 304 if err == nil { 305 t.Fatal("should have error") 306 } 307 308 // Test with a good one 309 config["shutdown_timeout"] = "5s" 310 b = Builder{} 311 warns, err = b.Prepare(config) 312 if len(warns) > 0 { 313 t.Fatalf("bad: %#v", warns) 314 } 315 if err != nil { 316 t.Fatalf("should not have error: %s", err) 317 } 318 } 319 320 func TestBuilderPrepare_SSHHostPort(t *testing.T) { 321 var b Builder 322 config := testConfig() 323 324 // Bad 325 config["ssh_host_port_min"] = 1000 326 config["ssh_host_port_max"] = 500 327 b = Builder{} 328 warns, err := b.Prepare(config) 329 if len(warns) > 0 { 330 t.Fatalf("bad: %#v", warns) 331 } 332 if err == nil { 333 t.Fatal("should have error") 334 } 335 336 // Bad 337 config["ssh_host_port_min"] = -500 338 b = Builder{} 339 warns, err = b.Prepare(config) 340 if len(warns) > 0 { 341 t.Fatalf("bad: %#v", warns) 342 } 343 if err == nil { 344 t.Fatal("should have error") 345 } 346 347 // Good 348 config["ssh_host_port_min"] = 500 349 config["ssh_host_port_max"] = 1000 350 b = Builder{} 351 warns, err = b.Prepare(config) 352 if len(warns) > 0 { 353 t.Fatalf("bad: %#v", warns) 354 } 355 if err != nil { 356 t.Fatalf("should not have error: %s", err) 357 } 358 } 359 360 func TestBuilderPrepare_SSHPrivateKey(t *testing.T) { 361 var b Builder 362 config := testConfig() 363 364 config["ssh_private_key_file"] = "" 365 b = Builder{} 366 warns, err := b.Prepare(config) 367 if len(warns) > 0 { 368 t.Fatalf("bad: %#v", warns) 369 } 370 if err != nil { 371 t.Fatalf("should not have error: %s", err) 372 } 373 374 config["ssh_private_key_file"] = "/i/dont/exist" 375 b = Builder{} 376 warns, err = b.Prepare(config) 377 if len(warns) > 0 { 378 t.Fatalf("bad: %#v", warns) 379 } 380 if err == nil { 381 t.Fatal("should have error") 382 } 383 384 // Test bad contents 385 tf, err := ioutil.TempFile("", "packer") 386 if err != nil { 387 t.Fatalf("err: %s", err) 388 } 389 defer os.Remove(tf.Name()) 390 defer tf.Close() 391 392 if _, err := tf.Write([]byte("HELLO!")); err != nil { 393 t.Fatalf("err: %s", err) 394 } 395 396 config["ssh_private_key_file"] = tf.Name() 397 b = Builder{} 398 warns, err = b.Prepare(config) 399 if len(warns) > 0 { 400 t.Fatalf("bad: %#v", warns) 401 } 402 if err == nil { 403 t.Fatal("should have error") 404 } 405 406 // Test good contents 407 tf.Seek(0, 0) 408 tf.Truncate(0) 409 tf.Write([]byte(testPem)) 410 config["ssh_private_key_file"] = tf.Name() 411 b = Builder{} 412 warns, err = b.Prepare(config) 413 if len(warns) > 0 { 414 t.Fatalf("bad: %#v", warns) 415 } 416 if err != nil { 417 t.Fatalf("err: %s", err) 418 } 419 } 420 421 func TestBuilderPrepare_SSHUser(t *testing.T) { 422 var b Builder 423 config := testConfig() 424 425 config["ssh_username"] = "" 426 b = Builder{} 427 warns, err := b.Prepare(config) 428 if len(warns) > 0 { 429 t.Fatalf("bad: %#v", warns) 430 } 431 if err == nil { 432 t.Fatal("should have error") 433 } 434 435 config["ssh_username"] = "exists" 436 b = Builder{} 437 warns, err = b.Prepare(config) 438 if len(warns) > 0 { 439 t.Fatalf("bad: %#v", warns) 440 } 441 if err != nil { 442 t.Fatalf("should not have error: %s", err) 443 } 444 } 445 446 func TestBuilderPrepare_SSHWaitTimeout(t *testing.T) { 447 var b Builder 448 config := testConfig() 449 450 // Test a default boot_wait 451 delete(config, "ssh_wait_timeout") 452 warns, err := b.Prepare(config) 453 if len(warns) > 0 { 454 t.Fatalf("bad: %#v", warns) 455 } 456 if err != nil { 457 t.Fatalf("err: %s", err) 458 } 459 460 // Test with a bad value 461 config["ssh_wait_timeout"] = "this is not good" 462 b = Builder{} 463 warns, err = b.Prepare(config) 464 if len(warns) > 0 { 465 t.Fatalf("bad: %#v", warns) 466 } 467 if err == nil { 468 t.Fatal("should have error") 469 } 470 471 // Test with a good one 472 config["ssh_wait_timeout"] = "5s" 473 b = Builder{} 474 warns, err = b.Prepare(config) 475 if len(warns) > 0 { 476 t.Fatalf("bad: %#v", warns) 477 } 478 if err != nil { 479 t.Fatalf("should not have error: %s", err) 480 } 481 } 482 483 func TestBuilderPrepare_QemuArgs(t *testing.T) { 484 var b Builder 485 config := testConfig() 486 487 // Test with empty 488 delete(config, "qemuargs") 489 warns, err := b.Prepare(config) 490 if len(warns) > 0 { 491 t.Fatalf("bad: %#v", warns) 492 } 493 if err != nil { 494 t.Fatalf("err: %s", err) 495 } 496 497 if !reflect.DeepEqual(b.config.QemuArgs, [][]string{}) { 498 t.Fatalf("bad: %#v", b.config.QemuArgs) 499 } 500 501 // Test with a good one 502 config["qemuargs"] = [][]interface{}{ 503 []interface{}{"foo", "bar", "baz"}, 504 } 505 506 b = Builder{} 507 warns, err = b.Prepare(config) 508 if len(warns) > 0 { 509 t.Fatalf("bad: %#v", warns) 510 } 511 if err != nil { 512 t.Fatalf("should not have error: %s", err) 513 } 514 515 expected := [][]string{ 516 []string{"foo", "bar", "baz"}, 517 } 518 519 if !reflect.DeepEqual(b.config.QemuArgs, expected) { 520 t.Fatalf("bad: %#v", b.config.QemuArgs) 521 } 522 }