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