github.com/vincentwoo/docker@v0.7.3-0.20160116130405-82401a4b13c0/cliconfig/config_test.go (about) 1 package cliconfig 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "strings" 8 "testing" 9 10 "github.com/docker/docker/pkg/homedir" 11 "github.com/docker/engine-api/types" 12 ) 13 14 func TestEmptyConfigDir(t *testing.T) { 15 tmpHome, err := ioutil.TempDir("", "config-test") 16 if err != nil { 17 t.Fatal(err) 18 } 19 defer os.RemoveAll(tmpHome) 20 21 SetConfigDir(tmpHome) 22 23 config, err := Load("") 24 if err != nil { 25 t.Fatalf("Failed loading on empty config dir: %q", err) 26 } 27 28 expectedConfigFilename := filepath.Join(tmpHome, ConfigFileName) 29 if config.Filename() != expectedConfigFilename { 30 t.Fatalf("Expected config filename %s, got %s", expectedConfigFilename, config.Filename()) 31 } 32 33 // Now save it and make sure it shows up in new form 34 saveConfigAndValidateNewFormat(t, config, tmpHome) 35 } 36 37 func TestMissingFile(t *testing.T) { 38 tmpHome, err := ioutil.TempDir("", "config-test") 39 if err != nil { 40 t.Fatal(err) 41 } 42 defer os.RemoveAll(tmpHome) 43 44 config, err := Load(tmpHome) 45 if err != nil { 46 t.Fatalf("Failed loading on missing file: %q", err) 47 } 48 49 // Now save it and make sure it shows up in new form 50 saveConfigAndValidateNewFormat(t, config, tmpHome) 51 } 52 53 func TestSaveFileToDirs(t *testing.T) { 54 tmpHome, err := ioutil.TempDir("", "config-test") 55 if err != nil { 56 t.Fatal(err) 57 } 58 defer os.RemoveAll(tmpHome) 59 60 tmpHome += "/.docker" 61 62 config, err := Load(tmpHome) 63 if err != nil { 64 t.Fatalf("Failed loading on missing file: %q", err) 65 } 66 67 // Now save it and make sure it shows up in new form 68 saveConfigAndValidateNewFormat(t, config, tmpHome) 69 } 70 71 func TestEmptyFile(t *testing.T) { 72 tmpHome, err := ioutil.TempDir("", "config-test") 73 if err != nil { 74 t.Fatal(err) 75 } 76 defer os.RemoveAll(tmpHome) 77 78 fn := filepath.Join(tmpHome, ConfigFileName) 79 if err := ioutil.WriteFile(fn, []byte(""), 0600); err != nil { 80 t.Fatal(err) 81 } 82 83 _, err = Load(tmpHome) 84 if err == nil { 85 t.Fatalf("Was supposed to fail") 86 } 87 } 88 89 func TestEmptyJson(t *testing.T) { 90 tmpHome, err := ioutil.TempDir("", "config-test") 91 if err != nil { 92 t.Fatal(err) 93 } 94 defer os.RemoveAll(tmpHome) 95 96 fn := filepath.Join(tmpHome, ConfigFileName) 97 if err := ioutil.WriteFile(fn, []byte("{}"), 0600); err != nil { 98 t.Fatal(err) 99 } 100 101 config, err := Load(tmpHome) 102 if err != nil { 103 t.Fatalf("Failed loading on empty json file: %q", err) 104 } 105 106 // Now save it and make sure it shows up in new form 107 saveConfigAndValidateNewFormat(t, config, tmpHome) 108 } 109 110 func TestOldInvalidsAuth(t *testing.T) { 111 invalids := map[string]string{ 112 `username = test`: "The Auth config file is empty", 113 `username 114 password 115 email`: "Invalid Auth config file", 116 `username = test 117 email`: "Invalid auth configuration file", 118 `username = am9lam9lOmhlbGxv 119 email`: "Invalid Auth config file", 120 } 121 122 tmpHome, err := ioutil.TempDir("", "config-test") 123 if err != nil { 124 t.Fatal(err) 125 } 126 defer os.RemoveAll(tmpHome) 127 128 homeKey := homedir.Key() 129 homeVal := homedir.Get() 130 131 defer func() { os.Setenv(homeKey, homeVal) }() 132 os.Setenv(homeKey, tmpHome) 133 134 for content, expectedError := range invalids { 135 fn := filepath.Join(tmpHome, oldConfigfile) 136 if err := ioutil.WriteFile(fn, []byte(content), 0600); err != nil { 137 t.Fatal(err) 138 } 139 140 config, err := Load(tmpHome) 141 // Use Contains instead of == since the file name will change each time 142 if err == nil || !strings.Contains(err.Error(), expectedError) { 143 t.Fatalf("Should have failed\nConfig: %v\nGot: %v\nExpected: %v", config, err, expectedError) 144 } 145 146 } 147 } 148 149 func TestOldValidAuth(t *testing.T) { 150 tmpHome, err := ioutil.TempDir("", "config-test") 151 if err != nil { 152 t.Fatal(err) 153 } 154 if err != nil { 155 t.Fatal(err) 156 } 157 defer os.RemoveAll(tmpHome) 158 159 homeKey := homedir.Key() 160 homeVal := homedir.Get() 161 162 defer func() { os.Setenv(homeKey, homeVal) }() 163 os.Setenv(homeKey, tmpHome) 164 165 fn := filepath.Join(tmpHome, oldConfigfile) 166 js := `username = am9lam9lOmhlbGxv 167 email = user@example.com` 168 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 169 t.Fatal(err) 170 } 171 172 config, err := Load(tmpHome) 173 if err != nil { 174 t.Fatal(err) 175 } 176 177 // defaultIndexserver is https://index.docker.io/v1/ 178 ac := config.AuthConfigs["https://index.docker.io/v1/"] 179 if ac.Email != "user@example.com" || ac.Username != "joejoe" || ac.Password != "hello" { 180 t.Fatalf("Missing data from parsing:\n%q", config) 181 } 182 183 // Now save it and make sure it shows up in new form 184 configStr := saveConfigAndValidateNewFormat(t, config, tmpHome) 185 186 if !strings.Contains(configStr, "user@example.com") { 187 t.Fatalf("Should have save in new form: %s", configStr) 188 } 189 } 190 191 func TestOldJsonInvalid(t *testing.T) { 192 tmpHome, err := ioutil.TempDir("", "config-test") 193 if err != nil { 194 t.Fatal(err) 195 } 196 defer os.RemoveAll(tmpHome) 197 198 homeKey := homedir.Key() 199 homeVal := homedir.Get() 200 201 defer func() { os.Setenv(homeKey, homeVal) }() 202 os.Setenv(homeKey, tmpHome) 203 204 fn := filepath.Join(tmpHome, oldConfigfile) 205 js := `{"https://index.docker.io/v1/":{"auth":"test","email":"user@example.com"}}` 206 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 207 t.Fatal(err) 208 } 209 210 config, err := Load(tmpHome) 211 // Use Contains instead of == since the file name will change each time 212 if err == nil || !strings.Contains(err.Error(), "Invalid auth configuration file") { 213 t.Fatalf("Expected an error got : %v, %v", config, err) 214 } 215 } 216 217 func TestOldJson(t *testing.T) { 218 tmpHome, err := ioutil.TempDir("", "config-test") 219 if err != nil { 220 t.Fatal(err) 221 } 222 defer os.RemoveAll(tmpHome) 223 224 homeKey := homedir.Key() 225 homeVal := homedir.Get() 226 227 defer func() { os.Setenv(homeKey, homeVal) }() 228 os.Setenv(homeKey, tmpHome) 229 230 fn := filepath.Join(tmpHome, oldConfigfile) 231 js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}` 232 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 233 t.Fatal(err) 234 } 235 236 config, err := Load(tmpHome) 237 if err != nil { 238 t.Fatalf("Failed loading on empty json file: %q", err) 239 } 240 241 ac := config.AuthConfigs["https://index.docker.io/v1/"] 242 if ac.Email != "user@example.com" || ac.Username != "joejoe" || ac.Password != "hello" { 243 t.Fatalf("Missing data from parsing:\n%q", config) 244 } 245 246 // Now save it and make sure it shows up in new form 247 configStr := saveConfigAndValidateNewFormat(t, config, tmpHome) 248 249 if !strings.Contains(configStr, "user@example.com") { 250 t.Fatalf("Should have save in new form: %s", configStr) 251 } 252 } 253 254 func TestNewJson(t *testing.T) { 255 tmpHome, err := ioutil.TempDir("", "config-test") 256 if err != nil { 257 t.Fatal(err) 258 } 259 defer os.RemoveAll(tmpHome) 260 261 fn := filepath.Join(tmpHome, ConfigFileName) 262 js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } } }` 263 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 264 t.Fatal(err) 265 } 266 267 config, err := Load(tmpHome) 268 if err != nil { 269 t.Fatalf("Failed loading on empty json file: %q", err) 270 } 271 272 ac := config.AuthConfigs["https://index.docker.io/v1/"] 273 if ac.Email != "user@example.com" || ac.Username != "joejoe" || ac.Password != "hello" { 274 t.Fatalf("Missing data from parsing:\n%q", config) 275 } 276 277 // Now save it and make sure it shows up in new form 278 configStr := saveConfigAndValidateNewFormat(t, config, tmpHome) 279 280 if !strings.Contains(configStr, "user@example.com") { 281 t.Fatalf("Should have save in new form: %s", configStr) 282 } 283 } 284 285 func TestJsonWithPsFormat(t *testing.T) { 286 tmpHome, err := ioutil.TempDir("", "config-test") 287 if err != nil { 288 t.Fatal(err) 289 } 290 defer os.RemoveAll(tmpHome) 291 292 fn := filepath.Join(tmpHome, ConfigFileName) 293 js := `{ 294 "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } }, 295 "psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}" 296 }` 297 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 298 t.Fatal(err) 299 } 300 301 config, err := Load(tmpHome) 302 if err != nil { 303 t.Fatalf("Failed loading on empty json file: %q", err) 304 } 305 306 if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` { 307 t.Fatalf("Unknown ps format: %s\n", config.PsFormat) 308 } 309 310 // Now save it and make sure it shows up in new form 311 configStr := saveConfigAndValidateNewFormat(t, config, tmpHome) 312 if !strings.Contains(configStr, `"psFormat":`) || 313 !strings.Contains(configStr, "{{.ID}}") { 314 t.Fatalf("Should have save in new form: %s", configStr) 315 } 316 } 317 318 // Save it and make sure it shows up in new form 319 func saveConfigAndValidateNewFormat(t *testing.T, config *ConfigFile, homeFolder string) string { 320 err := config.Save() 321 if err != nil { 322 t.Fatalf("Failed to save: %q", err) 323 } 324 325 buf, err := ioutil.ReadFile(filepath.Join(homeFolder, ConfigFileName)) 326 if !strings.Contains(string(buf), `"auths":`) { 327 t.Fatalf("Should have save in new form: %s", string(buf)) 328 } 329 return string(buf) 330 } 331 332 func TestConfigDir(t *testing.T) { 333 tmpHome, err := ioutil.TempDir("", "config-test") 334 if err != nil { 335 t.Fatal(err) 336 } 337 defer os.RemoveAll(tmpHome) 338 339 if ConfigDir() == tmpHome { 340 t.Fatalf("Expected ConfigDir to be different than %s by default, but was the same", tmpHome) 341 } 342 343 // Update configDir 344 SetConfigDir(tmpHome) 345 346 if ConfigDir() != tmpHome { 347 t.Fatalf("Expected ConfigDir to %s, but was %s", tmpHome, ConfigDir()) 348 } 349 } 350 351 func TestConfigFile(t *testing.T) { 352 configFilename := "configFilename" 353 configFile := NewConfigFile(configFilename) 354 355 if configFile.Filename() != configFilename { 356 t.Fatalf("Expected %s, got %s", configFilename, configFile.Filename()) 357 } 358 } 359 360 func TestJsonReaderNoFile(t *testing.T) { 361 js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } } }` 362 363 config, err := LoadFromReader(strings.NewReader(js)) 364 if err != nil { 365 t.Fatalf("Failed loading on empty json file: %q", err) 366 } 367 368 ac := config.AuthConfigs["https://index.docker.io/v1/"] 369 if ac.Email != "user@example.com" || ac.Username != "joejoe" || ac.Password != "hello" { 370 t.Fatalf("Missing data from parsing:\n%q", config) 371 } 372 373 } 374 375 func TestOldJsonReaderNoFile(t *testing.T) { 376 js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}` 377 378 config, err := LegacyLoadFromReader(strings.NewReader(js)) 379 if err != nil { 380 t.Fatalf("Failed loading on empty json file: %q", err) 381 } 382 383 ac := config.AuthConfigs["https://index.docker.io/v1/"] 384 if ac.Email != "user@example.com" || ac.Username != "joejoe" || ac.Password != "hello" { 385 t.Fatalf("Missing data from parsing:\n%q", config) 386 } 387 } 388 389 func TestJsonWithPsFormatNoFile(t *testing.T) { 390 js := `{ 391 "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } }, 392 "psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}" 393 }` 394 config, err := LoadFromReader(strings.NewReader(js)) 395 if err != nil { 396 t.Fatalf("Failed loading on empty json file: %q", err) 397 } 398 399 if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` { 400 t.Fatalf("Unknown ps format: %s\n", config.PsFormat) 401 } 402 403 } 404 405 func TestJsonSaveWithNoFile(t *testing.T) { 406 js := `{ 407 "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } }, 408 "psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}" 409 }` 410 config, err := LoadFromReader(strings.NewReader(js)) 411 err = config.Save() 412 if err == nil { 413 t.Fatalf("Expected error. File should not have been able to save with no file name.") 414 } 415 416 tmpHome, err := ioutil.TempDir("", "config-test") 417 if err != nil { 418 t.Fatalf("Failed to create a temp dir: %q", err) 419 } 420 defer os.RemoveAll(tmpHome) 421 422 fn := filepath.Join(tmpHome, ConfigFileName) 423 f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 424 err = config.SaveToWriter(f) 425 if err != nil { 426 t.Fatalf("Failed saving to file: %q", err) 427 } 428 buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName)) 429 if !strings.Contains(string(buf), `"auths":`) || 430 !strings.Contains(string(buf), "user@example.com") { 431 t.Fatalf("Should have save in new form: %s", string(buf)) 432 } 433 } 434 435 func TestLegacyJsonSaveWithNoFile(t *testing.T) { 436 437 js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}` 438 config, err := LegacyLoadFromReader(strings.NewReader(js)) 439 err = config.Save() 440 if err == nil { 441 t.Fatalf("Expected error. File should not have been able to save with no file name.") 442 } 443 444 tmpHome, err := ioutil.TempDir("", "config-test") 445 if err != nil { 446 t.Fatalf("Failed to create a temp dir: %q", err) 447 } 448 defer os.RemoveAll(tmpHome) 449 450 fn := filepath.Join(tmpHome, ConfigFileName) 451 f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 452 err = config.SaveToWriter(f) 453 if err != nil { 454 t.Fatalf("Failed saving to file: %q", err) 455 } 456 buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName)) 457 if !strings.Contains(string(buf), `"auths":`) || 458 !strings.Contains(string(buf), "user@example.com") { 459 t.Fatalf("Should have save in new form: %s", string(buf)) 460 } 461 } 462 463 func TestEncodeAuth(t *testing.T) { 464 newAuthConfig := &types.AuthConfig{Username: "ken", Password: "test", Email: "test@example.com"} 465 authStr := encodeAuth(newAuthConfig) 466 decAuthConfig := &types.AuthConfig{} 467 var err error 468 decAuthConfig.Username, decAuthConfig.Password, err = decodeAuth(authStr) 469 if err != nil { 470 t.Fatal(err) 471 } 472 if newAuthConfig.Username != decAuthConfig.Username { 473 t.Fatal("Encode Username doesn't match decoded Username") 474 } 475 if newAuthConfig.Password != decAuthConfig.Password { 476 t.Fatal("Encode Password doesn't match decoded Password") 477 } 478 if authStr != "a2VuOnRlc3Q=" { 479 t.Fatal("AuthString encoding isn't correct.") 480 } 481 }