github.com/amanya/packer@v0.12.1-0.20161117214323-902ac5ab2eb6/provisioner/shell/provisioner_test.go (about) 1 package shell 2 3 import ( 4 "github.com/mitchellh/packer/packer" 5 "io/ioutil" 6 "os" 7 "regexp" 8 "strings" 9 "testing" 10 ) 11 12 func testConfig() map[string]interface{} { 13 return map[string]interface{}{ 14 "inline": []interface{}{"foo", "bar"}, 15 } 16 } 17 18 func TestProvisioner_Impl(t *testing.T) { 19 var raw interface{} 20 raw = &Provisioner{} 21 if _, ok := raw.(packer.Provisioner); !ok { 22 t.Fatalf("must be a Provisioner") 23 } 24 } 25 26 func TestProvisionerPrepare_Defaults(t *testing.T) { 27 var p Provisioner 28 config := testConfig() 29 30 err := p.Prepare(config) 31 if err != nil { 32 t.Fatalf("err: %s", err) 33 } 34 35 if *p.config.ExpectDisconnect != true { 36 t.Errorf("expected ExpectDisconnect to be true") 37 } 38 39 if p.config.RemotePath == "" { 40 t.Errorf("unexpected remote path: %s", p.config.RemotePath) 41 } 42 } 43 44 func TestProvisionerPrepare_ExpectDisconnect(t *testing.T) { 45 config := testConfig() 46 p := new(Provisioner) 47 config["expect_disconnect"] = false 48 49 err := p.Prepare(config) 50 if err != nil { 51 t.Fatalf("err: %s", err) 52 } 53 54 if *p.config.ExpectDisconnect != false { 55 t.Errorf("expected ExpectDisconnect to be false") 56 } 57 58 config["expect_disconnect"] = true 59 p = new(Provisioner) 60 err = p.Prepare(config) 61 if err != nil { 62 t.Fatalf("err: %s", err) 63 } 64 65 if *p.config.ExpectDisconnect != true { 66 t.Errorf("expected ExpectDisconnect to be true") 67 } 68 69 } 70 71 func TestProvisionerPrepare_InlineShebang(t *testing.T) { 72 config := testConfig() 73 74 delete(config, "inline_shebang") 75 p := new(Provisioner) 76 err := p.Prepare(config) 77 if err != nil { 78 t.Fatalf("should not have error: %s", err) 79 } 80 81 if p.config.InlineShebang != "/bin/sh -e" { 82 t.Fatalf("bad value: %s", p.config.InlineShebang) 83 } 84 85 // Test with a good one 86 config["inline_shebang"] = "foo" 87 p = new(Provisioner) 88 err = p.Prepare(config) 89 if err != nil { 90 t.Fatalf("should not have error: %s", err) 91 } 92 93 if p.config.InlineShebang != "foo" { 94 t.Fatalf("bad value: %s", p.config.InlineShebang) 95 } 96 } 97 98 func TestProvisionerPrepare_InvalidKey(t *testing.T) { 99 var p Provisioner 100 config := testConfig() 101 102 // Add a random key 103 config["i_should_not_be_valid"] = true 104 err := p.Prepare(config) 105 if err == nil { 106 t.Fatal("should have error") 107 } 108 } 109 110 func TestProvisionerPrepare_Script(t *testing.T) { 111 config := testConfig() 112 delete(config, "inline") 113 114 config["script"] = "/this/should/not/exist" 115 p := new(Provisioner) 116 err := p.Prepare(config) 117 if err == nil { 118 t.Fatal("should have error") 119 } 120 121 // Test with a good one 122 tf, err := ioutil.TempFile("", "packer") 123 if err != nil { 124 t.Fatalf("error tempfile: %s", err) 125 } 126 defer os.Remove(tf.Name()) 127 128 config["script"] = tf.Name() 129 p = new(Provisioner) 130 err = p.Prepare(config) 131 if err != nil { 132 t.Fatalf("should not have error: %s", err) 133 } 134 } 135 136 func TestProvisionerPrepare_ScriptAndInline(t *testing.T) { 137 var p Provisioner 138 config := testConfig() 139 140 delete(config, "inline") 141 delete(config, "script") 142 err := p.Prepare(config) 143 if err == nil { 144 t.Fatal("should have error") 145 } 146 147 // Test with both 148 tf, err := ioutil.TempFile("", "packer") 149 if err != nil { 150 t.Fatalf("error tempfile: %s", err) 151 } 152 defer os.Remove(tf.Name()) 153 154 config["inline"] = []interface{}{"foo"} 155 config["script"] = tf.Name() 156 err = p.Prepare(config) 157 if err == nil { 158 t.Fatal("should have error") 159 } 160 } 161 162 func TestProvisionerPrepare_ScriptAndScripts(t *testing.T) { 163 var p Provisioner 164 config := testConfig() 165 166 // Test with both 167 tf, err := ioutil.TempFile("", "packer") 168 if err != nil { 169 t.Fatalf("error tempfile: %s", err) 170 } 171 defer os.Remove(tf.Name()) 172 173 config["inline"] = []interface{}{"foo"} 174 config["scripts"] = []string{tf.Name()} 175 err = p.Prepare(config) 176 if err == nil { 177 t.Fatal("should have error") 178 } 179 } 180 181 func TestProvisionerPrepare_Scripts(t *testing.T) { 182 config := testConfig() 183 delete(config, "inline") 184 185 config["scripts"] = []string{} 186 p := new(Provisioner) 187 err := p.Prepare(config) 188 if err == nil { 189 t.Fatal("should have error") 190 } 191 192 // Test with a good one 193 tf, err := ioutil.TempFile("", "packer") 194 if err != nil { 195 t.Fatalf("error tempfile: %s", err) 196 } 197 defer os.Remove(tf.Name()) 198 199 config["scripts"] = []string{tf.Name()} 200 p = new(Provisioner) 201 err = p.Prepare(config) 202 if err != nil { 203 t.Fatalf("should not have error: %s", err) 204 } 205 } 206 207 func TestProvisionerPrepare_EnvironmentVars(t *testing.T) { 208 config := testConfig() 209 210 // Test with a bad case 211 config["environment_vars"] = []string{"badvar", "good=var"} 212 p := new(Provisioner) 213 err := p.Prepare(config) 214 if err == nil { 215 t.Fatal("should have error") 216 } 217 218 // Test with a trickier case 219 config["environment_vars"] = []string{"=bad"} 220 p = new(Provisioner) 221 err = p.Prepare(config) 222 if err == nil { 223 t.Fatal("should have error") 224 } 225 226 // Test with a good case 227 // Note: baz= is a real env variable, just empty 228 config["environment_vars"] = []string{"FOO=bar", "baz="} 229 p = new(Provisioner) 230 err = p.Prepare(config) 231 if err != nil { 232 t.Fatalf("should not have error: %s", err) 233 } 234 } 235 236 func TestProvisionerQuote_EnvironmentVars(t *testing.T) { 237 config := testConfig() 238 239 config["environment_vars"] = []string{"keyone=valueone", "keytwo=value\ntwo"} 240 p := new(Provisioner) 241 p.Prepare(config) 242 243 expectedValue := "keyone='valueone'" 244 if p.config.Vars[0] != expectedValue { 245 t.Fatalf("%s should be equal to %s", p.config.Vars[0], expectedValue) 246 } 247 248 expectedValue = "keytwo='value\ntwo'" 249 if p.config.Vars[1] != expectedValue { 250 t.Fatalf("%s should be equal to %s", p.config.Vars[1], expectedValue) 251 } 252 } 253 254 func TestProvisioner_RemoteFolderSetSuccessfully(t *testing.T) { 255 config := testConfig() 256 257 expectedRemoteFolder := "/example/path" 258 config["remote_folder"] = expectedRemoteFolder 259 260 p := new(Provisioner) 261 err := p.Prepare(config) 262 if err != nil { 263 t.Fatalf("should not have error: %s", err) 264 } 265 266 if !strings.Contains(p.config.RemotePath, expectedRemoteFolder) { 267 t.Fatalf("remote path does not contain remote_folder") 268 } 269 } 270 271 func TestProvisioner_RemoteFolderDefaultsToTmp(t *testing.T) { 272 config := testConfig() 273 274 p := new(Provisioner) 275 err := p.Prepare(config) 276 if err != nil { 277 t.Fatalf("should not have error: %s", err) 278 } 279 280 if p.config.RemoteFolder != "/tmp" { 281 t.Fatalf("remote_folder did not default to /tmp") 282 } 283 284 if !strings.Contains(p.config.RemotePath, "/tmp") { 285 t.Fatalf("remote path does not contain remote_folder") 286 } 287 } 288 289 func TestProvisioner_RemoteFileSetSuccessfully(t *testing.T) { 290 config := testConfig() 291 292 expectedRemoteFile := "example.sh" 293 config["remote_file"] = expectedRemoteFile 294 295 p := new(Provisioner) 296 err := p.Prepare(config) 297 if err != nil { 298 t.Fatalf("should not have error: %s", err) 299 } 300 301 if !strings.Contains(p.config.RemotePath, expectedRemoteFile) { 302 t.Fatalf("remote path does not contain remote_file") 303 } 304 } 305 306 func TestProvisioner_RemoteFileDefaultsToScriptnnnn(t *testing.T) { 307 config := testConfig() 308 309 p := new(Provisioner) 310 err := p.Prepare(config) 311 if err != nil { 312 t.Fatalf("should not have error: %s", err) 313 } 314 315 remoteFileRegex := regexp.MustCompile("script_[0-9]{4}.sh") 316 317 if !remoteFileRegex.MatchString(p.config.RemoteFile) { 318 t.Fatalf("remote_file did not default to script_nnnn.sh") 319 } 320 321 if !remoteFileRegex.MatchString(p.config.RemotePath) { 322 t.Fatalf("remote_path did not match script_nnnn.sh") 323 } 324 } 325 326 func TestProvisioner_RemotePathSetViaRemotePathAndRemoteFile(t *testing.T) { 327 config := testConfig() 328 329 expectedRemoteFile := "example.sh" 330 expectedRemoteFolder := "/example/path" 331 config["remote_file"] = expectedRemoteFile 332 config["remote_folder"] = expectedRemoteFolder 333 334 p := new(Provisioner) 335 err := p.Prepare(config) 336 if err != nil { 337 t.Fatalf("should not have error: %s", err) 338 } 339 340 if p.config.RemotePath != expectedRemoteFolder+"/"+expectedRemoteFile { 341 t.Fatalf("remote path does not contain remote_file") 342 } 343 } 344 345 func TestProvisioner_RemotePathOverridesRemotePathAndRemoteFile(t *testing.T) { 346 config := testConfig() 347 348 expectedRemoteFile := "example.sh" 349 expectedRemoteFolder := "/example/path" 350 expectedRemotePath := "/example/remote/path/script.sh" 351 config["remote_file"] = expectedRemoteFile 352 config["remote_folder"] = expectedRemoteFolder 353 config["remote_path"] = expectedRemotePath 354 355 p := new(Provisioner) 356 err := p.Prepare(config) 357 if err != nil { 358 t.Fatalf("should not have error: %s", err) 359 } 360 361 if p.config.RemotePath != expectedRemotePath { 362 t.Fatalf("remote path does not contain remote_path") 363 } 364 } 365 366 func TestProvisionerRemotePathDefaultsSuccessfully(t *testing.T) { 367 config := testConfig() 368 369 p := new(Provisioner) 370 err := p.Prepare(config) 371 if err != nil { 372 t.Fatalf("should not have error: %s", err) 373 } 374 375 remotePathRegex := regexp.MustCompile("/tmp/script_[0-9]{4}.sh") 376 377 if !remotePathRegex.MatchString(p.config.RemotePath) { 378 t.Fatalf("remote path does not match the expected default regex") 379 } 380 }