github.com/rsyabuta/packer@v1.1.4-0.20180119234903-5ef0c2280f0b/provisioner/powershell/provisioner_test.go (about) 1 package powershell 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 //"log" 9 "os" 10 "regexp" 11 "strings" 12 "testing" 13 "time" 14 15 "github.com/hashicorp/packer/packer" 16 ) 17 18 func testConfig() map[string]interface{} { 19 return map[string]interface{}{ 20 "inline": []interface{}{"foo", "bar"}, 21 } 22 } 23 24 func init() { 25 //log.SetOutput(ioutil.Discard) 26 } 27 28 func TestProvisionerPrepare_extractScript(t *testing.T) { 29 config := testConfig() 30 p := new(Provisioner) 31 _ = p.Prepare(config) 32 file, err := extractScript(p) 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){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"` { 83 t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='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){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"` { 87 t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='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 181 config["script"] = tf.Name() 182 p = new(Provisioner) 183 err = p.Prepare(config) 184 if err != nil { 185 t.Fatalf("should not have error: %s", err) 186 } 187 } 188 189 func TestProvisionerPrepare_ScriptAndInline(t *testing.T) { 190 var p Provisioner 191 config := testConfig() 192 193 delete(config, "inline") 194 delete(config, "script") 195 err := p.Prepare(config) 196 if err == nil { 197 t.Fatal("should have error") 198 } 199 200 // Test with both 201 tf, err := ioutil.TempFile("", "packer") 202 if err != nil { 203 t.Fatalf("error tempfile: %s", err) 204 } 205 defer os.Remove(tf.Name()) 206 207 config["inline"] = []interface{}{"foo"} 208 config["script"] = tf.Name() 209 err = p.Prepare(config) 210 if err == nil { 211 t.Fatal("should have error") 212 } 213 } 214 215 func TestProvisionerPrepare_ScriptAndScripts(t *testing.T) { 216 var p Provisioner 217 config := testConfig() 218 219 // Test with both 220 tf, err := ioutil.TempFile("", "packer") 221 if err != nil { 222 t.Fatalf("error tempfile: %s", err) 223 } 224 defer os.Remove(tf.Name()) 225 226 config["inline"] = []interface{}{"foo"} 227 config["scripts"] = []string{tf.Name()} 228 err = p.Prepare(config) 229 if err == nil { 230 t.Fatal("should have error") 231 } 232 } 233 234 func TestProvisionerPrepare_Scripts(t *testing.T) { 235 config := testConfig() 236 delete(config, "inline") 237 238 config["scripts"] = []string{} 239 p := new(Provisioner) 240 err := p.Prepare(config) 241 if err == nil { 242 t.Fatal("should have error") 243 } 244 245 // Test with a good one 246 tf, err := ioutil.TempFile("", "packer") 247 if err != nil { 248 t.Fatalf("error tempfile: %s", err) 249 } 250 defer os.Remove(tf.Name()) 251 252 config["scripts"] = []string{tf.Name()} 253 p = new(Provisioner) 254 err = p.Prepare(config) 255 if err != nil { 256 t.Fatalf("should not have error: %s", err) 257 } 258 } 259 260 func TestProvisionerPrepare_EnvironmentVars(t *testing.T) { 261 config := testConfig() 262 263 // Test with a bad case 264 config["environment_vars"] = []string{"badvar", "good=var"} 265 p := new(Provisioner) 266 err := p.Prepare(config) 267 if err == nil { 268 t.Fatal("should have error") 269 } 270 271 // Test with a trickier case 272 config["environment_vars"] = []string{"=bad"} 273 p = new(Provisioner) 274 err = p.Prepare(config) 275 if err == nil { 276 t.Fatal("should have error") 277 } 278 279 // Test with a good case 280 // Note: baz= is a real env variable, just empty 281 config["environment_vars"] = []string{"FOO=bar", "baz="} 282 p = new(Provisioner) 283 err = p.Prepare(config) 284 if err != nil { 285 t.Fatalf("should not have error: %s", err) 286 } 287 288 // Test when the env variable value contains an equals sign 289 config["environment_vars"] = []string{"good=withequals=true"} 290 p = new(Provisioner) 291 err = p.Prepare(config) 292 if err != nil { 293 t.Fatalf("should not have error: %s", err) 294 } 295 296 // Test when the env variable value starts with an equals sign 297 config["environment_vars"] = []string{"good==true"} 298 p = new(Provisioner) 299 err = p.Prepare(config) 300 if err != nil { 301 t.Fatalf("should not have error: %s", err) 302 } 303 304 } 305 306 func TestProvisionerQuote_EnvironmentVars(t *testing.T) { 307 config := testConfig() 308 309 config["environment_vars"] = []string{ 310 "keyone=valueone", 311 "keytwo=value\ntwo", 312 "keythree='valuethree'", 313 "keyfour='value\nfour'", 314 "keyfive='value=five'", 315 "keysix='=six'", 316 } 317 318 expected := []string{ 319 "keyone=valueone", 320 "keytwo=value\ntwo", 321 "keythree='valuethree'", 322 "keyfour='value\nfour'", 323 "keyfive='value=five'", 324 "keysix='=six'", 325 } 326 327 p := new(Provisioner) 328 p.Prepare(config) 329 330 for i, expectedValue := range expected { 331 if p.config.Vars[i] != expectedValue { 332 t.Fatalf("%s should be equal to %s", p.config.Vars[i], expectedValue) 333 } 334 } 335 } 336 337 func testUi() *packer.BasicUi { 338 return &packer.BasicUi{ 339 Reader: new(bytes.Buffer), 340 Writer: new(bytes.Buffer), 341 ErrorWriter: new(bytes.Buffer), 342 } 343 } 344 345 func testObjects() (packer.Ui, packer.Communicator) { 346 ui := testUi() 347 return ui, new(packer.MockCommunicator) 348 } 349 350 func TestProvisionerProvision_ValidExitCodes(t *testing.T) { 351 config := testConfig() 352 delete(config, "inline") 353 354 // Defaults provided by Packer 355 config["remote_path"] = "c:/Windows/Temp/inlineScript.ps1" 356 config["inline"] = []string{"whoami"} 357 ui := testUi() 358 p := new(Provisioner) 359 360 // Defaults provided by Packer 361 p.config.PackerBuildName = "vmware" 362 p.config.PackerBuilderType = "iso" 363 p.config.ValidExitCodes = []int{0, 200} 364 comm := new(packer.MockCommunicator) 365 comm.StartExitStatus = 200 366 p.Prepare(config) 367 err := p.Provision(ui, comm) 368 if err != nil { 369 t.Fatal("should not have error") 370 } 371 } 372 373 func TestProvisionerProvision_InvalidExitCodes(t *testing.T) { 374 config := testConfig() 375 delete(config, "inline") 376 377 // Defaults provided by Packer 378 config["remote_path"] = "c:/Windows/Temp/inlineScript.ps1" 379 config["inline"] = []string{"whoami"} 380 ui := testUi() 381 p := new(Provisioner) 382 383 // Defaults provided by Packer 384 p.config.PackerBuildName = "vmware" 385 p.config.PackerBuilderType = "iso" 386 p.config.ValidExitCodes = []int{0, 200} 387 comm := new(packer.MockCommunicator) 388 comm.StartExitStatus = 201 // Invalid! 389 p.Prepare(config) 390 err := p.Provision(ui, comm) 391 if err == nil { 392 t.Fatal("should have error") 393 } 394 } 395 396 func TestProvisionerProvision_Inline(t *testing.T) { 397 config := testConfig() 398 delete(config, "inline") 399 400 // Defaults provided by Packer 401 config["remote_path"] = "c:/Windows/Temp/inlineScript.ps1" 402 config["inline"] = []string{"whoami"} 403 ui := testUi() 404 p := new(Provisioner) 405 406 // Defaults provided by Packer 407 p.config.PackerBuildName = "vmware" 408 p.config.PackerBuilderType = "iso" 409 comm := new(packer.MockCommunicator) 410 p.Prepare(config) 411 err := p.Provision(ui, comm) 412 if err != nil { 413 t.Fatal("should not have error") 414 } 415 416 expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"` 417 if comm.StartCmd.Command != expectedCommand { 418 t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) 419 } 420 421 envVars := make([]string, 2) 422 envVars[0] = "FOO=BAR" 423 envVars[1] = "BAR=BAZ" 424 config["environment_vars"] = envVars 425 config["remote_path"] = "c:/Windows/Temp/inlineScript.ps1" 426 427 p.Prepare(config) 428 err = p.Provision(ui, comm) 429 if err != nil { 430 t.Fatal("should not have error") 431 } 432 433 expectedCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"` 434 if comm.StartCmd.Command != expectedCommand { 435 t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) 436 } 437 } 438 439 func TestProvisionerProvision_Scripts(t *testing.T) { 440 tempFile, _ := ioutil.TempFile("", "packer") 441 defer os.Remove(tempFile.Name()) 442 config := testConfig() 443 delete(config, "inline") 444 config["scripts"] = []string{tempFile.Name()} 445 config["packer_build_name"] = "foobuild" 446 config["packer_builder_type"] = "footype" 447 config["remote_path"] = "c:/Windows/Temp/script.ps1" 448 ui := testUi() 449 450 p := new(Provisioner) 451 comm := new(packer.MockCommunicator) 452 p.Prepare(config) 453 err := p.Provision(ui, comm) 454 if err != nil { 455 t.Fatal("should not have error") 456 } 457 458 expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` 459 if comm.StartCmd.Command != expectedCommand { 460 t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) 461 } 462 463 } 464 465 func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { 466 tempFile, _ := ioutil.TempFile("", "packer") 467 config := testConfig() 468 ui := testUi() 469 defer os.Remove(tempFile.Name()) 470 delete(config, "inline") 471 472 config["scripts"] = []string{tempFile.Name()} 473 config["packer_build_name"] = "foobuild" 474 config["packer_builder_type"] = "footype" 475 476 // Env vars - currently should not effect them 477 envVars := make([]string, 2) 478 envVars[0] = "FOO=BAR" 479 envVars[1] = "BAR=BAZ" 480 config["environment_vars"] = envVars 481 config["remote_path"] = "c:/Windows/Temp/script.ps1" 482 483 p := new(Provisioner) 484 comm := new(packer.MockCommunicator) 485 p.Prepare(config) 486 err := p.Provision(ui, comm) 487 if err != nil { 488 t.Fatal("should not have error") 489 } 490 491 expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` 492 if comm.StartCmd.Command != expectedCommand { 493 t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) 494 } 495 } 496 497 func TestProvisionerProvision_UISlurp(t *testing.T) { 498 // UI should be called n times 499 500 // UI should receive following messages / output 501 } 502 503 func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) { 504 var flattenedEnvVars string 505 config := testConfig() 506 507 userEnvVarTests := [][]string{ 508 {}, // No user env var 509 {"FOO=bar"}, // Single user env var 510 {"FOO=bar", "BAZ=qux"}, // Multiple user env vars 511 {"FOO=bar=baz"}, // User env var with value containing equals 512 {"FOO==bar"}, // User env var with value starting with equals 513 } 514 expected := []string{ 515 `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 516 `$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 517 `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 518 `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 519 `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, 520 } 521 522 p := new(Provisioner) 523 p.Prepare(config) 524 525 // Defaults provided by Packer 526 p.config.PackerBuildName = "vmware" 527 p.config.PackerBuilderType = "iso" 528 529 for i, expectedValue := range expected { 530 p.config.Vars = userEnvVarTests[i] 531 flattenedEnvVars = p.createFlattenedEnvVars(true) 532 if flattenedEnvVars != expectedValue { 533 t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars) 534 } 535 } 536 } 537 538 func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { 539 var flattenedEnvVars string 540 config := testConfig() 541 542 userEnvVarTests := [][]string{ 543 {}, // No user env var 544 {"FOO=bar"}, // Single user env var 545 {"FOO=bar", "BAZ=qux"}, // Multiple user env vars 546 {"FOO=bar=baz"}, // User env var with value containing equals 547 {"FOO==bar"}, // User env var with value starting with equals 548 } 549 expected := []string{ 550 `$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, 551 `$env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, 552 `$env:BAZ=\"qux\"; $env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, 553 `$env:FOO=\"bar=baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, 554 `$env:FOO=\"=bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, 555 } 556 557 p := new(Provisioner) 558 p.Prepare(config) 559 560 // Defaults provided by Packer 561 p.config.PackerBuildName = "vmware" 562 p.config.PackerBuilderType = "iso" 563 564 for i, expectedValue := range expected { 565 p.config.Vars = userEnvVarTests[i] 566 flattenedEnvVars = p.createFlattenedEnvVars(false) 567 if flattenedEnvVars != expectedValue { 568 t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars) 569 } 570 } 571 } 572 573 func TestProvision_createCommandText(t *testing.T) { 574 575 config := testConfig() 576 config["remote_path"] = "c:/Windows/Temp/script.ps1" 577 p := new(Provisioner) 578 comm := new(packer.MockCommunicator) 579 p.communicator = comm 580 _ = p.Prepare(config) 581 582 // Defaults provided by Packer 583 p.config.PackerBuildName = "vmware" 584 p.config.PackerBuilderType = "iso" 585 586 // Non-elevated 587 cmd, _ := p.createCommandText() 588 589 expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` 590 591 if cmd != expectedCommand { 592 t.Fatalf("Expected Non-elevated command: %s, got %s", expectedCommand, cmd) 593 } 594 595 // Elevated 596 p.config.ElevatedUser = "vagrant" 597 p.config.ElevatedPassword = "vagrant" 598 cmd, _ = p.createCommandText() 599 matched, _ := regexp.MatchString("powershell -executionpolicy bypass -file \"%TEMP%(.{1})packer-elevated-shell.*", cmd) 600 if !matched { 601 t.Fatalf("Got unexpected elevated command: %s", cmd) 602 } 603 } 604 605 func TestProvision_generateElevatedShellRunner(t *testing.T) { 606 607 // Non-elevated 608 config := testConfig() 609 p := new(Provisioner) 610 p.Prepare(config) 611 comm := new(packer.MockCommunicator) 612 p.communicator = comm 613 path, err := p.generateElevatedRunner("whoami") 614 615 if err != nil { 616 t.Fatalf("Did not expect error: %s", err.Error()) 617 } 618 619 if comm.UploadCalled != true { 620 t.Fatalf("Should have uploaded file") 621 } 622 623 matched, _ := regexp.MatchString("%TEMP%(.{1})packer-elevated-shell.*", path) 624 if !matched { 625 t.Fatalf("Got unexpected file: %s", path) 626 } 627 } 628 629 func TestRetryable(t *testing.T) { 630 config := testConfig() 631 632 count := 0 633 retryMe := func() error { 634 t.Logf("RetryMe, attempt number %d", count) 635 if count == 2 { 636 return nil 637 } 638 count++ 639 return errors.New(fmt.Sprintf("Still waiting %d more times...", 2-count)) 640 } 641 retryableSleep = 50 * time.Millisecond 642 p := new(Provisioner) 643 p.config.StartRetryTimeout = 155 * time.Millisecond 644 err := p.Prepare(config) 645 err = p.retryable(retryMe) 646 if err != nil { 647 t.Fatalf("should not have error retrying funuction") 648 } 649 650 count = 0 651 p.config.StartRetryTimeout = 10 * time.Millisecond 652 err = p.Prepare(config) 653 err = p.retryable(retryMe) 654 if err == nil { 655 t.Fatalf("should have error retrying funuction") 656 } 657 } 658 659 func TestCancel(t *testing.T) { 660 // Don't actually call Cancel() as it performs an os.Exit(0) 661 // which kills the 'go test' tool 662 }