github.com/ddnomad/packer@v1.3.2/provisioner/powershell/provisioner_test.go (about) 1 package powershell 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 "os" 9 "regexp" 10 "strings" 11 "testing" 12 "time" 13 14 "github.com/hashicorp/packer/packer" 15 ) 16 17 func testConfig() map[string]interface{} { 18 return map[string]interface{}{ 19 "inline": []interface{}{"foo", "bar"}, 20 } 21 } 22 23 func init() { 24 //log.SetOutput(ioutil.Discard) 25 } 26 27 func TestProvisionerPrepare_extractScript(t *testing.T) { 28 config := testConfig() 29 p := new(Provisioner) 30 _ = p.Prepare(config) 31 file, err := extractScript(p) 32 defer os.Remove(file) 33 if err != nil { 34 t.Fatalf("Should not be error: %s", err) 35 } 36 t.Logf("File: %s", file) 37 if strings.Index(file, os.TempDir()) != 0 { 38 t.Fatalf("Temp file should reside in %s. File location: %s", os.TempDir(), file) 39 } 40 41 // File contents should contain 2 lines concatenated by newlines: foo\nbar 42 readFile, err := ioutil.ReadFile(file) 43 expectedContents := "foo\nbar\n" 44 if err != nil { 45 t.Fatalf("Should not be error: %s", err) 46 } 47 s := string(readFile[:]) 48 if s != expectedContents { 49 t.Fatalf("Expected generated inlineScript to equal '%s', got '%s'", expectedContents, s) 50 } 51 } 52 53 func TestProvisioner_Impl(t *testing.T) { 54 var raw interface{} 55 raw = &Provisioner{} 56 if _, ok := raw.(packer.Provisioner); !ok { 57 t.Fatalf("must be a Provisioner") 58 } 59 } 60 61 func TestProvisionerPrepare_Defaults(t *testing.T) { 62 var p Provisioner 63 config := testConfig() 64 65 err := p.Prepare(config) 66 if err != nil { 67 t.Fatalf("err: %s", err) 68 } 69 70 matched, _ := regexp.MatchString("c:/Windows/Temp/script-.*.ps1", p.config.RemotePath) 71 if !matched { 72 t.Errorf("unexpected remote path: %s", p.config.RemotePath) 73 } 74 75 if p.config.ElevatedUser != "" { 76 t.Error("expected elevated_user to be empty") 77 } 78 if p.config.ElevatedPassword != "" { 79 t.Error("expected elevated_password to be empty") 80 } 81 82 if p.config.ExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"` { 83 t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"', but got '%s'`, p.config.ExecuteCommand) 84 } 85 86 if p.config.ElevatedExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"` { 87 t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"', but got '%s'`, p.config.ElevatedExecuteCommand) 88 } 89 90 if p.config.ValidExitCodes == nil { 91 t.Fatalf("ValidExitCodes should not be nil") 92 } 93 if p.config.ValidExitCodes != nil { 94 expCodes := []int{0} 95 for i, v := range p.config.ValidExitCodes { 96 if v != expCodes[i] { 97 t.Fatalf("Expected ValidExitCodes don't match actual") 98 } 99 } 100 } 101 102 if p.config.ElevatedEnvVarFormat != `$env:%s="%s"; ` { 103 t.Fatalf(`Default command should be powershell '$env:%%s="%%s"; ', but got %s`, p.config.ElevatedEnvVarFormat) 104 } 105 } 106 107 func TestProvisionerPrepare_Config(t *testing.T) { 108 config := testConfig() 109 config["elevated_user"] = "{{user `user`}}" 110 config["elevated_password"] = "{{user `password`}}" 111 config[packer.UserVariablesConfigKey] = map[string]string{ 112 "user": "myusername", 113 "password": "mypassword", 114 } 115 116 var p Provisioner 117 err := p.Prepare(config) 118 if err != nil { 119 t.Fatalf("err: %s", err) 120 } 121 122 if p.config.ElevatedUser != "myusername" { 123 t.Fatalf("Expected 'myusername' for key `elevated_user`: %s", p.config.ElevatedUser) 124 } 125 if p.config.ElevatedPassword != "mypassword" { 126 t.Fatalf("Expected 'mypassword' for key `elevated_password`: %s", p.config.ElevatedPassword) 127 } 128 129 } 130 131 func TestProvisionerPrepare_InvalidKey(t *testing.T) { 132 var p Provisioner 133 config := testConfig() 134 135 // Add a random key 136 config["i_should_not_be_valid"] = true 137 err := p.Prepare(config) 138 if err == nil { 139 t.Fatal("should have error") 140 } 141 } 142 143 func TestProvisionerPrepare_Elevated(t *testing.T) { 144 var p Provisioner 145 config := testConfig() 146 147 // Add a random key 148 config["elevated_user"] = "vagrant" 149 err := p.Prepare(config) 150 151 if err == nil { 152 t.Fatal("should have error (only provided elevated_user)") 153 } 154 155 config["elevated_password"] = "vagrant" 156 err = p.Prepare(config) 157 158 if err != nil { 159 t.Fatal("should not have error") 160 } 161 } 162 163 func TestProvisionerPrepare_Script(t *testing.T) { 164 config := testConfig() 165 delete(config, "inline") 166 167 config["script"] = "/this/should/not/exist" 168 p := new(Provisioner) 169 err := p.Prepare(config) 170 if err == nil { 171 t.Fatal("should have error") 172 } 173 174 // Test with a good one 175 tf, err := ioutil.TempFile("", "packer") 176 if err != nil { 177 t.Fatalf("error tempfile: %s", err) 178 } 179 defer os.Remove(tf.Name()) 180 defer tf.Close() 181 182 config["script"] = tf.Name() 183 p = new(Provisioner) 184 err = p.Prepare(config) 185 if err != nil { 186 t.Fatalf("should not have error: %s", err) 187 } 188 } 189 190 func TestProvisionerPrepare_ScriptAndInline(t *testing.T) { 191 var p Provisioner 192 config := testConfig() 193 194 delete(config, "inline") 195 delete(config, "script") 196 err := p.Prepare(config) 197 if err == nil { 198 t.Fatal("should have error") 199 } 200 201 // Test with both 202 tf, err := ioutil.TempFile("", "packer") 203 if err != nil { 204 t.Fatalf("error tempfile: %s", err) 205 } 206 defer os.Remove(tf.Name()) 207 defer tf.Close() 208 209 config["inline"] = []interface{}{"foo"} 210 config["script"] = tf.Name() 211 err = p.Prepare(config) 212 if err == nil { 213 t.Fatal("should have error") 214 } 215 } 216 217 func TestProvisionerPrepare_ScriptAndScripts(t *testing.T) { 218 var p Provisioner 219 config := testConfig() 220 221 // Test with both 222 tf, err := ioutil.TempFile("", "packer") 223 if err != nil { 224 t.Fatalf("error tempfile: %s", err) 225 } 226 defer os.Remove(tf.Name()) 227 defer tf.Close() 228 229 config["inline"] = []interface{}{"foo"} 230 config["scripts"] = []string{tf.Name()} 231 err = p.Prepare(config) 232 if err == nil { 233 t.Fatal("should have error") 234 } 235 } 236 237 func TestProvisionerPrepare_Scripts(t *testing.T) { 238 config := testConfig() 239 delete(config, "inline") 240 241 config["scripts"] = []string{} 242 p := new(Provisioner) 243 err := p.Prepare(config) 244 if err == nil { 245 t.Fatal("should have error") 246 } 247 248 // Test with a good one 249 tf, err := ioutil.TempFile("", "packer") 250 if err != nil { 251 t.Fatalf("error tempfile: %s", err) 252 } 253 defer os.Remove(tf.Name()) 254 defer tf.Close() 255 256 config["scripts"] = []string{tf.Name()} 257 p = new(Provisioner) 258 err = p.Prepare(config) 259 if err != nil { 260 t.Fatalf("should not have error: %s", err) 261 } 262 } 263 264 func TestProvisionerPrepare_EnvironmentVars(t *testing.T) { 265 config := testConfig() 266 267 // Test with a bad case 268 config["environment_vars"] = []string{"badvar", "good=var"} 269 p := new(Provisioner) 270 err := p.Prepare(config) 271 if err == nil { 272 t.Fatal("should have error") 273 } 274 275 // Test with a trickier case 276 config["environment_vars"] = []string{"=bad"} 277 p = new(Provisioner) 278 err = p.Prepare(config) 279 if err == nil { 280 t.Fatal("should have error") 281 } 282 283 // Test with a good case 284 // Note: baz= is a real env variable, just empty 285 config["environment_vars"] = []string{"FOO=bar", "baz="} 286 p = new(Provisioner) 287 err = p.Prepare(config) 288 if err != nil { 289 t.Fatalf("should not have error: %s", err) 290 } 291 292 // Test when the env variable value contains an equals sign 293 config["environment_vars"] = []string{"good=withequals=true"} 294 p = new(Provisioner) 295 err = p.Prepare(config) 296 if err != nil { 297 t.Fatalf("should not have error: %s", err) 298 } 299 300 // Test when the env variable value starts with an equals sign 301 config["environment_vars"] = []string{"good==true"} 302 p = new(Provisioner) 303 err = p.Prepare(config) 304 if err != nil { 305 t.Fatalf("should not have error: %s", err) 306 } 307 308 } 309 310 func TestProvisionerQuote_EnvironmentVars(t *testing.T) { 311 config := testConfig() 312 313 config["environment_vars"] = []string{ 314 "keyone=valueone", 315 "keytwo=value\ntwo", 316 "keythree='valuethree'", 317 "keyfour='value\nfour'", 318 "keyfive='value=five'", 319 "keysix='=six'", 320 } 321 322 expected := []string{ 323 "keyone=valueone", 324 "keytwo=value\ntwo", 325 "keythree='valuethree'", 326 "keyfour='value\nfour'", 327 "keyfive='value=five'", 328 "keysix='=six'", 329 } 330 331 p := new(Provisioner) 332 p.Prepare(config) 333 334 for i, expectedValue := range expected { 335 if p.config.Vars[i] != expectedValue { 336 t.Fatalf("%s should be equal to %s", p.config.Vars[i], expectedValue) 337 } 338 } 339 } 340 341 func testUi() *packer.BasicUi { 342 return &packer.BasicUi{ 343 Reader: new(bytes.Buffer), 344 Writer: new(bytes.Buffer), 345 ErrorWriter: new(bytes.Buffer), 346 } 347 } 348 349 func testObjects() (packer.Ui, packer.Communicator) { 350 ui := testUi() 351 return ui, new(packer.MockCommunicator) 352 } 353 354 func TestProvisionerProvision_ValidExitCodes(t *testing.T) { 355 config := testConfig() 356 delete(config, "inline") 357 358 // Defaults provided by Packer 359 config["remote_path"] = "c:/Windows/Temp/inlineScript.ps1" 360 config["inline"] = []string{"whoami"} 361 ui := testUi() 362 p := new(Provisioner) 363 364 // Defaults provided by Packer 365 p.config.PackerBuildName = "vmware" 366 p.config.PackerBuilderType = "iso" 367 p.config.ValidExitCodes = []int{0, 200} 368 comm := new(packer.MockCommunicator) 369 comm.StartExitStatus = 200 370 p.Prepare(config) 371 err := p.Provision(ui, comm) 372 if err != nil { 373 t.Fatal("should not have error") 374 } 375 } 376 377 func TestProvisionerProvision_InvalidExitCodes(t *testing.T) { 378 config := testConfig() 379 delete(config, "inline") 380 381 // Defaults provided by Packer 382 config["remote_path"] = "c:/Windows/Temp/inlineScript.ps1" 383 config["inline"] = []string{"whoami"} 384 ui := testUi() 385 p := new(Provisioner) 386 387 // Defaults provided by Packer 388 p.config.PackerBuildName = "vmware" 389 p.config.PackerBuilderType = "iso" 390 p.config.ValidExitCodes = []int{0, 200} 391 comm := new(packer.MockCommunicator) 392 comm.StartExitStatus = 201 // Invalid! 393 p.Prepare(config) 394 err := p.Provision(ui, comm) 395 if err == nil { 396 t.Fatal("should have error") 397 } 398 } 399 400 func TestProvisionerProvision_Inline(t *testing.T) { 401 config := testConfig() 402 delete(config, "inline") 403 404 // Defaults provided by Packer 405 config["remote_path"] = "c:/Windows/Temp/inlineScript.ps1" 406 config["inline"] = []string{"whoami"} 407 ui := testUi() 408 p := new(Provisioner) 409 410 // Defaults provided by Packer - env vars should not appear in cmd 411 p.config.PackerBuildName = "vmware" 412 p.config.PackerBuilderType = "iso" 413 comm := new(packer.MockCommunicator) 414 p.Prepare(config) 415 err := p.Provision(ui, comm) 416 if err != nil { 417 t.Fatal("should not have error") 418 } 419 420 cmd := comm.StartCmd.Command 421 re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1'; exit \$LastExitCode }"`) 422 matched := re.MatchString(cmd) 423 if !matched { 424 t.Fatalf("Got unexpected command: %s", cmd) 425 } 426 427 // User supplied env vars should not change things 428 envVars := make([]string, 2) 429 envVars[0] = "FOO=BAR" 430 envVars[1] = "BAR=BAZ" 431 config["environment_vars"] = envVars 432 config["remote_path"] = "c:/Windows/Temp/inlineScript.ps1" 433 434 p.Prepare(config) 435 err = p.Provision(ui, comm) 436 if err != nil { 437 t.Fatal("should not have error") 438 } 439 440 cmd = comm.StartCmd.Command 441 re = regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1'; exit \$LastExitCode }"`) 442 matched = re.MatchString(cmd) 443 if !matched { 444 t.Fatalf("Got unexpected command: %s", cmd) 445 } 446 } 447 448 func TestProvisionerProvision_Scripts(t *testing.T) { 449 tempFile, _ := ioutil.TempFile("", "packer") 450 defer os.Remove(tempFile.Name()) 451 defer tempFile.Close() 452 453 config := testConfig() 454 delete(config, "inline") 455 config["scripts"] = []string{tempFile.Name()} 456 config["packer_build_name"] = "foobuild" 457 config["packer_builder_type"] = "footype" 458 config["remote_path"] = "c:/Windows/Temp/script.ps1" 459 ui := testUi() 460 461 p := new(Provisioner) 462 comm := new(packer.MockCommunicator) 463 p.Prepare(config) 464 err := p.Provision(ui, comm) 465 if err != nil { 466 t.Fatal("should not have error") 467 } 468 469 cmd := comm.StartCmd.Command 470 re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1'; exit \$LastExitCode }"`) 471 matched := re.MatchString(cmd) 472 if !matched { 473 t.Fatalf("Got unexpected command: %s", cmd) 474 } 475 } 476 477 func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { 478 tempFile, _ := ioutil.TempFile("", "packer") 479 config := testConfig() 480 ui := testUi() 481 defer os.Remove(tempFile.Name()) 482 defer tempFile.Close() 483 484 delete(config, "inline") 485 486 config["scripts"] = []string{tempFile.Name()} 487 config["packer_build_name"] = "foobuild" 488 config["packer_builder_type"] = "footype" 489 490 // Env vars - currently should not effect them 491 envVars := make([]string, 2) 492 envVars[0] = "FOO=BAR" 493 envVars[1] = "BAR=BAZ" 494 config["environment_vars"] = envVars 495 config["remote_path"] = "c:/Windows/Temp/script.ps1" 496 497 p := new(Provisioner) 498 comm := new(packer.MockCommunicator) 499 p.Prepare(config) 500 err := p.Provision(ui, comm) 501 if err != nil { 502 t.Fatal("should not have error") 503 } 504 505 cmd := comm.StartCmd.Command 506 re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1'; exit \$LastExitCode }"`) 507 matched := re.MatchString(cmd) 508 if !matched { 509 t.Fatalf("Got unexpected command: %s", cmd) 510 } 511 } 512 513 func TestProvisionerProvision_UISlurp(t *testing.T) { 514 // UI should be called n times 515 516 // UI should receive following messages / output 517 } 518 519 func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) { 520 var flattenedEnvVars string 521 config := testConfig() 522 523 userEnvVarTests := [][]string{ 524 {}, // No user env var 525 {"FOO=bar"}, // Single user env var 526 {"FOO=bar", "BAZ=qux"}, // Multiple user env vars 527 {"FOO=bar=baz"}, // User env var with value containing equals 528 {"FOO==bar"}, // User env var with value starting with equals 529 // Test escaping of characters special to PowerShell 530 {"FOO=bar$baz"}, // User env var with value containing dollar 531 {"FOO=bar\"baz"}, // User env var with value containing a double quote 532 {"FOO=bar'baz"}, // User env var with value containing a single quote 533 {"FOO=bar`baz"}, // User env var with value containing a backtick 534 535 } 536 expected := []string{ 537 `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 538 `$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 539 `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 540 `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 541 `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 542 "$env:FOO=\"bar`$baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", 543 "$env:FOO=\"bar`\"baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", 544 "$env:FOO=\"bar`'baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", 545 "$env:FOO=\"bar``baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", 546 } 547 548 p := new(Provisioner) 549 p.Prepare(config) 550 551 // Defaults provided by Packer 552 p.config.PackerBuildName = "vmware" 553 p.config.PackerBuilderType = "iso" 554 555 for i, expectedValue := range expected { 556 p.config.Vars = userEnvVarTests[i] 557 flattenedEnvVars = p.createFlattenedEnvVars(true) 558 if flattenedEnvVars != expectedValue { 559 t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars) 560 } 561 } 562 } 563 564 func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { 565 var flattenedEnvVars string 566 config := testConfig() 567 568 userEnvVarTests := [][]string{ 569 {}, // No user env var 570 {"FOO=bar"}, // Single user env var 571 {"FOO=bar", "BAZ=qux"}, // Multiple user env vars 572 {"FOO=bar=baz"}, // User env var with value containing equals 573 {"FOO==bar"}, // User env var with value starting with equals 574 // Test escaping of characters special to PowerShell 575 {"FOO=bar$baz"}, // User env var with value containing dollar 576 {"FOO=bar\"baz"}, // User env var with value containing a double quote 577 {"FOO=bar'baz"}, // User env var with value containing a single quote 578 {"FOO=bar`baz"}, // User env var with value containing a backtick 579 } 580 expected := []string{ 581 `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 582 `$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 583 `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 584 `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 585 `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 586 "$env:FOO=\"bar`$baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", 587 "$env:FOO=\"bar`\"baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", 588 "$env:FOO=\"bar`'baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", 589 "$env:FOO=\"bar``baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", 590 } 591 592 p := new(Provisioner) 593 p.Prepare(config) 594 595 // Defaults provided by Packer 596 p.config.PackerBuildName = "vmware" 597 p.config.PackerBuilderType = "iso" 598 599 for i, expectedValue := range expected { 600 p.config.Vars = userEnvVarTests[i] 601 flattenedEnvVars = p.createFlattenedEnvVars(false) 602 if flattenedEnvVars != expectedValue { 603 t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars) 604 } 605 } 606 } 607 608 func TestProvision_createCommandText(t *testing.T) { 609 config := testConfig() 610 config["remote_path"] = "c:/Windows/Temp/script.ps1" 611 p := new(Provisioner) 612 comm := new(packer.MockCommunicator) 613 p.communicator = comm 614 _ = p.Prepare(config) 615 616 // Defaults provided by Packer 617 p.config.PackerBuildName = "vmware" 618 p.config.PackerBuilderType = "iso" 619 620 // Non-elevated 621 cmd, _ := p.createCommandText() 622 623 re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1'; exit \$LastExitCode }"`) 624 matched := re.MatchString(cmd) 625 if !matched { 626 t.Fatalf("Got unexpected command: %s", cmd) 627 } 628 629 // Elevated 630 p.config.ElevatedUser = "vagrant" 631 p.config.ElevatedPassword = "vagrant" 632 cmd, _ = p.createCommandText() 633 re = regexp.MustCompile(`powershell -executionpolicy bypass -file "C:/Windows/Temp/packer-elevated-shell-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1"`) 634 matched = re.MatchString(cmd) 635 if !matched { 636 t.Fatalf("Got unexpected elevated command: %s", cmd) 637 } 638 } 639 640 func TestProvision_uploadEnvVars(t *testing.T) { 641 p := new(Provisioner) 642 comm := new(packer.MockCommunicator) 643 p.communicator = comm 644 645 flattenedEnvVars := `$env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild";` 646 647 err := p.uploadEnvVars(flattenedEnvVars) 648 if err != nil { 649 t.Fatalf("Did not expect error: %s", err.Error()) 650 } 651 652 if comm.UploadCalled != true { 653 t.Fatalf("Failed to upload env var file") 654 } 655 } 656 657 func TestProvision_generateElevatedShellRunner(t *testing.T) { 658 659 // Non-elevated 660 config := testConfig() 661 p := new(Provisioner) 662 p.Prepare(config) 663 comm := new(packer.MockCommunicator) 664 p.communicator = comm 665 path, err := p.generateElevatedRunner("whoami") 666 667 if err != nil { 668 t.Fatalf("Did not expect error: %s", err.Error()) 669 } 670 671 if comm.UploadCalled != true { 672 t.Fatalf("Should have uploaded file") 673 } 674 675 matched, _ := regexp.MatchString("C:/Windows/Temp/packer-elevated-shell.*", path) 676 if !matched { 677 t.Fatalf("Got unexpected file: %s", path) 678 } 679 } 680 681 func TestRetryable(t *testing.T) { 682 config := testConfig() 683 684 count := 0 685 retryMe := func() error { 686 t.Logf("RetryMe, attempt number %d", count) 687 if count == 2 { 688 return nil 689 } 690 count++ 691 return errors.New(fmt.Sprintf("Still waiting %d more times...", 2-count)) 692 } 693 retryableSleep = 50 * time.Millisecond 694 p := new(Provisioner) 695 p.config.StartRetryTimeout = 155 * time.Millisecond 696 err := p.Prepare(config) 697 err = p.retryable(retryMe) 698 if err != nil { 699 t.Fatalf("should not have error retrying function") 700 } 701 702 count = 0 703 p.config.StartRetryTimeout = 10 * time.Millisecond 704 err = p.Prepare(config) 705 err = p.retryable(retryMe) 706 if err == nil { 707 t.Fatalf("should have error retrying function") 708 } 709 } 710 711 func TestCancel(t *testing.T) { 712 // Don't actually call Cancel() as it performs an os.Exit(0) 713 // which kills the 'go test' tool 714 }