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