github.com/kaixiang/packer@v0.5.2-0.20140114230416-1f5786b0d7f1/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.SSHPort != 22 { 83 t.Errorf("bad ssh port: %d", b.config.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_DiskSize(t *testing.T) { 136 var b Builder 137 config := testConfig() 138 139 delete(config, "disk_size") 140 warns, err := b.Prepare(config) 141 if len(warns) > 0 { 142 t.Fatalf("bad: %#v", warns) 143 } 144 if err != nil { 145 t.Fatalf("bad err: %s", err) 146 } 147 148 if b.config.DiskSize != 40000 { 149 t.Fatalf("bad size: %d", b.config.DiskSize) 150 } 151 152 config["disk_size"] = 60000 153 b = Builder{} 154 warns, err = b.Prepare(config) 155 if len(warns) > 0 { 156 t.Fatalf("bad: %#v", warns) 157 } 158 if err != nil { 159 t.Fatalf("should not have error: %s", err) 160 } 161 162 if b.config.DiskSize != 60000 { 163 t.Fatalf("bad size: %s", b.config.DiskSize) 164 } 165 } 166 167 func TestBuilderPrepare_HTTPPort(t *testing.T) { 168 var b Builder 169 config := testConfig() 170 171 // Bad 172 config["http_port_min"] = 1000 173 config["http_port_max"] = 500 174 warns, err := b.Prepare(config) 175 if len(warns) > 0 { 176 t.Fatalf("bad: %#v", warns) 177 } 178 if err == nil { 179 t.Fatal("should have error") 180 } 181 182 // Bad 183 config["http_port_min"] = -500 184 b = Builder{} 185 warns, err = b.Prepare(config) 186 if len(warns) > 0 { 187 t.Fatalf("bad: %#v", warns) 188 } 189 if err == nil { 190 t.Fatal("should have error") 191 } 192 193 // Good 194 config["http_port_min"] = 500 195 config["http_port_max"] = 1000 196 b = Builder{} 197 warns, err = b.Prepare(config) 198 if len(warns) > 0 { 199 t.Fatalf("bad: %#v", warns) 200 } 201 if err != nil { 202 t.Fatalf("should not have error: %s", err) 203 } 204 } 205 206 func TestBuilderPrepare_Format(t *testing.T) { 207 var b Builder 208 config := testConfig() 209 210 // Bad 211 config["format"] = "illegal value" 212 warns, err := b.Prepare(config) 213 if len(warns) > 0 { 214 t.Fatalf("bad: %#v", warns) 215 } 216 if err == nil { 217 t.Fatal("should have error") 218 } 219 220 // Good 221 config["format"] = "qcow2" 222 b = Builder{} 223 warns, err = b.Prepare(config) 224 if len(warns) > 0 { 225 t.Fatalf("bad: %#v", warns) 226 } 227 if err != nil { 228 t.Fatalf("should not have error: %s", err) 229 } 230 231 // Good 232 config["format"] = "raw" 233 b = Builder{} 234 warns, err = b.Prepare(config) 235 if len(warns) > 0 { 236 t.Fatalf("bad: %#v", warns) 237 } 238 if err != nil { 239 t.Fatalf("should not have error: %s", err) 240 } 241 } 242 243 func TestBuilderPrepare_InvalidKey(t *testing.T) { 244 var b Builder 245 config := testConfig() 246 247 // Add a random key 248 config["i_should_not_be_valid"] = true 249 warns, err := b.Prepare(config) 250 if len(warns) > 0 { 251 t.Fatalf("bad: %#v", warns) 252 } 253 if err == nil { 254 t.Fatal("should have error") 255 } 256 } 257 258 func TestBuilderPrepare_ISOChecksum(t *testing.T) { 259 var b Builder 260 config := testConfig() 261 262 // Test bad 263 config["iso_checksum"] = "" 264 warns, err := b.Prepare(config) 265 if len(warns) > 0 { 266 t.Fatalf("bad: %#v", warns) 267 } 268 if err == nil { 269 t.Fatal("should have error") 270 } 271 272 // Test good 273 config["iso_checksum"] = "FOo" 274 b = Builder{} 275 warns, err = b.Prepare(config) 276 if len(warns) > 0 { 277 t.Fatalf("bad: %#v", warns) 278 } 279 if err != nil { 280 t.Fatalf("should not have error: %s", err) 281 } 282 283 if b.config.ISOChecksum != "foo" { 284 t.Fatalf("should've lowercased: %s", b.config.ISOChecksum) 285 } 286 } 287 288 func TestBuilderPrepare_ISOChecksumType(t *testing.T) { 289 var b Builder 290 config := testConfig() 291 292 // Test bad 293 config["iso_checksum_type"] = "" 294 warns, err := b.Prepare(config) 295 if len(warns) > 0 { 296 t.Fatalf("bad: %#v", warns) 297 } 298 if err == nil { 299 t.Fatal("should have error") 300 } 301 302 // Test good 303 config["iso_checksum_type"] = "mD5" 304 b = Builder{} 305 warns, err = b.Prepare(config) 306 if len(warns) > 0 { 307 t.Fatalf("bad: %#v", warns) 308 } 309 if err != nil { 310 t.Fatalf("should not have error: %s", err) 311 } 312 313 if b.config.ISOChecksumType != "md5" { 314 t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType) 315 } 316 317 // Test unknown 318 config["iso_checksum_type"] = "fake" 319 b = Builder{} 320 warns, err = b.Prepare(config) 321 if len(warns) > 0 { 322 t.Fatalf("bad: %#v", warns) 323 } 324 if err == nil { 325 t.Fatal("should have error") 326 } 327 } 328 329 func TestBuilderPrepare_ISOUrl(t *testing.T) { 330 var b Builder 331 config := testConfig() 332 delete(config, "iso_url") 333 delete(config, "iso_urls") 334 335 // Test both epty 336 config["iso_url"] = "" 337 b = Builder{} 338 warns, err := b.Prepare(config) 339 if len(warns) > 0 { 340 t.Fatalf("bad: %#v", warns) 341 } 342 if err == nil { 343 t.Fatal("should have error") 344 } 345 346 // Test iso_url set 347 config["iso_url"] = "http://www.packer.io" 348 b = Builder{} 349 warns, err = b.Prepare(config) 350 if len(warns) > 0 { 351 t.Fatalf("bad: %#v", warns) 352 } 353 if err != nil { 354 t.Errorf("should not have error: %s", err) 355 } 356 357 expected := []string{"http://www.packer.io"} 358 if !reflect.DeepEqual(b.config.ISOUrls, expected) { 359 t.Fatalf("bad: %#v", b.config.ISOUrls) 360 } 361 362 // Test both set 363 config["iso_url"] = "http://www.packer.io" 364 config["iso_urls"] = []string{"http://www.packer.io"} 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.Fatal("should have error") 372 } 373 374 // Test just iso_urls set 375 delete(config, "iso_url") 376 config["iso_urls"] = []string{ 377 "http://www.packer.io", 378 "http://www.hashicorp.com", 379 } 380 381 b = Builder{} 382 warns, err = b.Prepare(config) 383 if len(warns) > 0 { 384 t.Fatalf("bad: %#v", warns) 385 } 386 if err != nil { 387 t.Errorf("should not have error: %s", err) 388 } 389 390 expected = []string{ 391 "http://www.packer.io", 392 "http://www.hashicorp.com", 393 } 394 if !reflect.DeepEqual(b.config.ISOUrls, expected) { 395 t.Fatalf("bad: %#v", b.config.ISOUrls) 396 } 397 } 398 399 func TestBuilderPrepare_OutputDir(t *testing.T) { 400 var b Builder 401 config := testConfig() 402 403 // Test with existing dir 404 dir, err := ioutil.TempDir("", "packer") 405 if err != nil { 406 t.Fatalf("err: %s", err) 407 } 408 defer os.RemoveAll(dir) 409 410 config["output_directory"] = dir 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.Fatal("should have error") 418 } 419 420 // Test with a good one 421 config["output_directory"] = "i-hope-i-dont-exist" 422 b = Builder{} 423 warns, err = b.Prepare(config) 424 if len(warns) > 0 { 425 t.Fatalf("bad: %#v", warns) 426 } 427 if err != nil { 428 t.Fatalf("should not have error: %s", err) 429 } 430 } 431 432 func TestBuilderPrepare_ShutdownTimeout(t *testing.T) { 433 var b Builder 434 config := testConfig() 435 436 // Test with a bad value 437 config["shutdown_timeout"] = "this is not good" 438 warns, err := b.Prepare(config) 439 if len(warns) > 0 { 440 t.Fatalf("bad: %#v", warns) 441 } 442 if err == nil { 443 t.Fatal("should have error") 444 } 445 446 // Test with a good one 447 config["shutdown_timeout"] = "5s" 448 b = Builder{} 449 warns, err = b.Prepare(config) 450 if len(warns) > 0 { 451 t.Fatalf("bad: %#v", warns) 452 } 453 if err != nil { 454 t.Fatalf("should not have error: %s", err) 455 } 456 } 457 458 func TestBuilderPrepare_SSHHostPort(t *testing.T) { 459 var b Builder 460 config := testConfig() 461 462 // Bad 463 config["ssh_host_port_min"] = 1000 464 config["ssh_host_port_max"] = 500 465 b = Builder{} 466 warns, err := b.Prepare(config) 467 if len(warns) > 0 { 468 t.Fatalf("bad: %#v", warns) 469 } 470 if err == nil { 471 t.Fatal("should have error") 472 } 473 474 // Bad 475 config["ssh_host_port_min"] = -500 476 b = Builder{} 477 warns, err = b.Prepare(config) 478 if len(warns) > 0 { 479 t.Fatalf("bad: %#v", warns) 480 } 481 if err == nil { 482 t.Fatal("should have error") 483 } 484 485 // Good 486 config["ssh_host_port_min"] = 500 487 config["ssh_host_port_max"] = 1000 488 b = Builder{} 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("should not have error: %s", err) 495 } 496 } 497 498 func TestBuilderPrepare_sshKeyPath(t *testing.T) { 499 var b Builder 500 config := testConfig() 501 502 config["ssh_key_path"] = "" 503 b = Builder{} 504 warns, err := b.Prepare(config) 505 if len(warns) > 0 { 506 t.Fatalf("bad: %#v", warns) 507 } 508 if err != nil { 509 t.Fatalf("should not have error: %s", err) 510 } 511 512 config["ssh_key_path"] = "/i/dont/exist" 513 b = Builder{} 514 warns, err = b.Prepare(config) 515 if len(warns) > 0 { 516 t.Fatalf("bad: %#v", warns) 517 } 518 if err == nil { 519 t.Fatal("should have error") 520 } 521 522 // Test bad contents 523 tf, err := ioutil.TempFile("", "packer") 524 if err != nil { 525 t.Fatalf("err: %s", err) 526 } 527 defer os.Remove(tf.Name()) 528 defer tf.Close() 529 530 if _, err := tf.Write([]byte("HELLO!")); err != nil { 531 t.Fatalf("err: %s", err) 532 } 533 534 config["ssh_key_path"] = tf.Name() 535 b = Builder{} 536 warns, err = b.Prepare(config) 537 if len(warns) > 0 { 538 t.Fatalf("bad: %#v", warns) 539 } 540 if err == nil { 541 t.Fatal("should have error") 542 } 543 544 // Test good contents 545 tf.Seek(0, 0) 546 tf.Truncate(0) 547 tf.Write([]byte(testPem)) 548 config["ssh_key_path"] = tf.Name() 549 b = Builder{} 550 warns, err = b.Prepare(config) 551 if len(warns) > 0 { 552 t.Fatalf("bad: %#v", warns) 553 } 554 if err != nil { 555 t.Fatalf("err: %s", err) 556 } 557 } 558 559 func TestBuilderPrepare_SSHUser(t *testing.T) { 560 var b Builder 561 config := testConfig() 562 563 config["ssh_username"] = "" 564 b = Builder{} 565 warns, err := b.Prepare(config) 566 if len(warns) > 0 { 567 t.Fatalf("bad: %#v", warns) 568 } 569 if err == nil { 570 t.Fatal("should have error") 571 } 572 573 config["ssh_username"] = "exists" 574 b = Builder{} 575 warns, err = b.Prepare(config) 576 if len(warns) > 0 { 577 t.Fatalf("bad: %#v", warns) 578 } 579 if err != nil { 580 t.Fatalf("should not have error: %s", err) 581 } 582 } 583 584 func TestBuilderPrepare_SSHWaitTimeout(t *testing.T) { 585 var b Builder 586 config := testConfig() 587 588 // Test a default boot_wait 589 delete(config, "ssh_wait_timeout") 590 warns, err := b.Prepare(config) 591 if len(warns) > 0 { 592 t.Fatalf("bad: %#v", warns) 593 } 594 if err != nil { 595 t.Fatalf("err: %s", err) 596 } 597 598 if b.config.RawSSHWaitTimeout != "20m" { 599 t.Fatalf("bad value: %s", b.config.RawSSHWaitTimeout) 600 } 601 602 // Test with a bad value 603 config["ssh_wait_timeout"] = "this is not good" 604 b = Builder{} 605 warns, err = b.Prepare(config) 606 if len(warns) > 0 { 607 t.Fatalf("bad: %#v", warns) 608 } 609 if err == nil { 610 t.Fatal("should have error") 611 } 612 613 // Test with a good one 614 config["ssh_wait_timeout"] = "5s" 615 b = Builder{} 616 warns, err = b.Prepare(config) 617 if len(warns) > 0 { 618 t.Fatalf("bad: %#v", warns) 619 } 620 if err != nil { 621 t.Fatalf("should not have error: %s", err) 622 } 623 } 624 625 func TestBuilderPrepare_QemuArgs(t *testing.T) { 626 var b Builder 627 config := testConfig() 628 629 // Test with empty 630 delete(config, "qemuargs") 631 warns, err := b.Prepare(config) 632 if len(warns) > 0 { 633 t.Fatalf("bad: %#v", warns) 634 } 635 if err != nil { 636 t.Fatalf("err: %s", err) 637 } 638 639 if !reflect.DeepEqual(b.config.QemuArgs, [][]string{}) { 640 t.Fatalf("bad: %#v", b.config.QemuArgs) 641 } 642 643 // Test with a good one 644 config["qemuargs"] = [][]interface{}{ 645 []interface{}{"foo", "bar", "baz"}, 646 } 647 648 b = Builder{} 649 warns, err = b.Prepare(config) 650 if len(warns) > 0 { 651 t.Fatalf("bad: %#v", warns) 652 } 653 if err != nil { 654 t.Fatalf("should not have error: %s", err) 655 } 656 657 expected := [][]string{ 658 []string{"foo", "bar", "baz"}, 659 } 660 661 if !reflect.DeepEqual(b.config.QemuArgs, expected) { 662 t.Fatalf("bad: %#v", b.config.QemuArgs) 663 } 664 }