github.com/0xbf/packer@v0.7.6-0.20150209014853-4e8036b1eea5/common/config_test.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "github.com/mitchellh/mapstructure" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "reflect" 10 "runtime" 11 "strings" 12 "testing" 13 ) 14 15 func TestCheckUnusedConfig(t *testing.T) { 16 md := &mapstructure.Metadata{ 17 Unused: make([]string, 0), 18 } 19 20 err := CheckUnusedConfig(md) 21 if err != nil { 22 t.Fatalf("err: %s", err) 23 } 24 25 md.Unused = []string{"foo", "bar"} 26 err = CheckUnusedConfig(md) 27 if err == nil { 28 t.Fatal("should have error") 29 } 30 } 31 32 func TestChooseString(t *testing.T) { 33 cases := []struct { 34 Input []string 35 Output string 36 }{ 37 { 38 []string{"", "foo", ""}, 39 "foo", 40 }, 41 { 42 []string{"", "foo", "bar"}, 43 "foo", 44 }, 45 { 46 []string{"", "", ""}, 47 "", 48 }, 49 } 50 51 for _, tc := range cases { 52 result := ChooseString(tc.Input...) 53 if result != tc.Output { 54 t.Fatalf("bad: %#v", tc.Input) 55 } 56 } 57 } 58 59 func TestDecodeConfig(t *testing.T) { 60 type Local struct { 61 Foo string 62 Bar string 63 } 64 65 raws := []interface{}{ 66 map[string]interface{}{ 67 "foo": "bar", 68 }, 69 map[string]interface{}{ 70 "bar": "baz", 71 "baz": "what", 72 }, 73 } 74 75 var result Local 76 md, err := DecodeConfig(&result, raws...) 77 if err != nil { 78 t.Fatalf("err: %s", err) 79 } 80 81 if result.Foo != "bar" { 82 t.Fatalf("invalid: %#v", result.Foo) 83 } 84 85 if result.Bar != "baz" { 86 t.Fatalf("invalid: %#v", result.Bar) 87 } 88 89 if md == nil { 90 t.Fatal("metadata should not be nil") 91 } 92 93 if !reflect.DeepEqual(md.Unused, []string{"baz"}) { 94 t.Fatalf("unused: %#v", md.Unused) 95 } 96 } 97 98 // This test tests the case that a user var is used for an integer 99 // configuration. 100 func TestDecodeConfig_stringToSlice(t *testing.T) { 101 type Local struct { 102 Val []string 103 EmptyVal []string 104 } 105 106 raw := map[string]interface{}{ 107 "packer_user_variables": map[string]string{ 108 "foo": "bar", 109 }, 110 111 "val": "foo,{{user `foo`}}", 112 "emptyval": "", 113 } 114 115 var result Local 116 _, err := DecodeConfig(&result, raw) 117 if err != nil { 118 t.Fatalf("err: %s", err) 119 } 120 121 expected := []string{"foo", "bar"} 122 if !reflect.DeepEqual(result.Val, expected) { 123 t.Fatalf("invalid: %#v", result.Val) 124 } 125 if len(result.EmptyVal) > 0 { 126 t.Fatalf("invalid: %#v", result.EmptyVal) 127 } 128 } 129 130 // This test tests the case that a user var is used for an integer 131 // configuration. 132 func TestDecodeConfig_userVarConversion(t *testing.T) { 133 type Local struct { 134 Val int 135 } 136 137 raw := map[string]interface{}{ 138 "packer_user_variables": map[string]string{ 139 "foo": "42", 140 }, 141 142 "val": "{{user `foo`}}", 143 } 144 145 var result Local 146 _, err := DecodeConfig(&result, raw) 147 if err != nil { 148 t.Fatalf("err: %s", err) 149 } 150 151 if result.Val != 42 { 152 t.Fatalf("invalid: %#v", result.Val) 153 } 154 } 155 156 // This tests the way MessagePack decodes strings (into []uint8) and 157 // that we can still decode into the proper types. 158 func TestDecodeConfig_userVarConversionUInt8(t *testing.T) { 159 type Local struct { 160 Val int 161 } 162 163 raw := map[string]interface{}{ 164 "packer_user_variables": map[string]string{ 165 "foo": "42", 166 }, 167 168 "val": []uint8("{{user `foo`}}"), 169 } 170 171 var result Local 172 _, err := DecodeConfig(&result, raw) 173 if err != nil { 174 t.Fatalf("err: %s", err) 175 } 176 177 if result.Val != 42 { 178 t.Fatalf("invalid: %#v", result.Val) 179 } 180 } 181 182 func TestDownloadableURL(t *testing.T) { 183 // Invalid URL: has hex code in host 184 _, err := DownloadableURL("http://what%20.com") 185 if err == nil { 186 t.Fatal("expected err") 187 } 188 189 // Invalid: unsupported scheme 190 _, err = DownloadableURL("ftp://host.com/path") 191 if err == nil { 192 t.Fatal("expected err") 193 } 194 195 // Valid: http 196 u, err := DownloadableURL("HTTP://packer.io/path") 197 if err != nil { 198 t.Fatalf("err: %s", err) 199 } 200 201 if u != "http://packer.io/path" { 202 t.Fatalf("bad: %s", u) 203 } 204 205 // No path 206 u, err = DownloadableURL("HTTP://packer.io") 207 if err != nil { 208 t.Fatalf("err: %s", err) 209 } 210 211 if u != "http://packer.io" { 212 t.Fatalf("bad: %s", u) 213 } 214 } 215 216 func TestDownloadableURL_FilePaths(t *testing.T) { 217 tf, err := ioutil.TempFile("", "packer") 218 if err != nil { 219 t.Fatalf("tempfile err: %s", err) 220 } 221 defer os.Remove(tf.Name()) 222 tf.Close() 223 224 tfPath, err := filepath.EvalSymlinks(tf.Name()) 225 if err != nil { 226 t.Fatalf("tempfile err: %s", err) 227 } 228 229 tfPath = filepath.Clean(tfPath) 230 231 filePrefix := "file://" 232 if runtime.GOOS == "windows" { 233 filePrefix += "/" 234 } 235 236 // Relative filepath. We run this test in a func so that 237 // the defers run right away. 238 func() { 239 wd, err := os.Getwd() 240 if err != nil { 241 t.Fatalf("getwd err: %s", err) 242 } 243 244 err = os.Chdir(filepath.Dir(tfPath)) 245 if err != nil { 246 t.Fatalf("chdir err: %s", err) 247 } 248 defer os.Chdir(wd) 249 250 filename := filepath.Base(tfPath) 251 u, err := DownloadableURL(filename) 252 if err != nil { 253 t.Fatalf("err: %s", err) 254 } 255 256 expected := fmt.Sprintf("%s%s", 257 filePrefix, 258 strings.Replace(tfPath, `\`, `/`, -1)) 259 if u != expected { 260 t.Fatalf("unexpected: %#v != %#v", u, expected) 261 } 262 }() 263 264 // Test some cases with and without a schema prefix 265 for _, prefix := range []string{"", "file://"} { 266 // Nonexistent file 267 _, err = DownloadableURL(prefix + "i/dont/exist") 268 if err != nil { 269 t.Fatalf("err: %s", err) 270 } 271 272 // Good file 273 u, err := DownloadableURL(prefix + tfPath) 274 if err != nil { 275 t.Fatalf("err: %s", err) 276 } 277 278 expected := fmt.Sprintf("%s%s", 279 filePrefix, 280 strings.Replace(tfPath, `\`, `/`, -1)) 281 if u != expected { 282 t.Fatalf("unexpected: %s != %s", u, expected) 283 } 284 } 285 } 286 287 func TestScrubConfig(t *testing.T) { 288 type Inner struct { 289 Baz string 290 } 291 type Local struct { 292 Foo string 293 Bar string 294 Inner 295 } 296 c := Local{"foo", "bar", Inner{"bar"}} 297 expect := "Config: {Foo:foo Bar:<Filtered> Inner:{Baz:<Filtered>}}" 298 conf := ScrubConfig(c, c.Bar) 299 if conf != expect { 300 t.Fatalf("got %s, expected %s", conf, expect) 301 } 302 }