github.com/portworx/docker@v1.12.1/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/cliconfig/configfile" 11 "github.com/docker/docker/pkg/homedir" 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`: "Invalid Auth config file", 115 `username = test 116 email`: "Invalid auth configuration file", 117 } 118 119 tmpHome, err := ioutil.TempDir("", "config-test") 120 if err != nil { 121 t.Fatal(err) 122 } 123 defer os.RemoveAll(tmpHome) 124 125 homeKey := homedir.Key() 126 homeVal := homedir.Get() 127 128 defer func() { os.Setenv(homeKey, homeVal) }() 129 os.Setenv(homeKey, tmpHome) 130 131 for content, expectedError := range invalids { 132 fn := filepath.Join(tmpHome, oldConfigfile) 133 if err := ioutil.WriteFile(fn, []byte(content), 0600); err != nil { 134 t.Fatal(err) 135 } 136 137 config, err := Load(tmpHome) 138 // Use Contains instead of == since the file name will change each time 139 if err == nil || !strings.Contains(err.Error(), expectedError) { 140 t.Fatalf("Should have failed\nConfig: %v\nGot: %v\nExpected: %v", config, err, expectedError) 141 } 142 143 } 144 } 145 146 func TestOldValidAuth(t *testing.T) { 147 tmpHome, err := ioutil.TempDir("", "config-test") 148 if err != nil { 149 t.Fatal(err) 150 } 151 if err != nil { 152 t.Fatal(err) 153 } 154 defer os.RemoveAll(tmpHome) 155 156 homeKey := homedir.Key() 157 homeVal := homedir.Get() 158 159 defer func() { os.Setenv(homeKey, homeVal) }() 160 os.Setenv(homeKey, tmpHome) 161 162 fn := filepath.Join(tmpHome, oldConfigfile) 163 js := `username = am9lam9lOmhlbGxv 164 email = user@example.com` 165 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 166 t.Fatal(err) 167 } 168 169 config, err := Load(tmpHome) 170 if err != nil { 171 t.Fatal(err) 172 } 173 174 // defaultIndexserver is https://index.docker.io/v1/ 175 ac := config.AuthConfigs["https://index.docker.io/v1/"] 176 if ac.Username != "joejoe" || ac.Password != "hello" { 177 t.Fatalf("Missing data from parsing:\n%q", config) 178 } 179 180 // Now save it and make sure it shows up in new form 181 configStr := saveConfigAndValidateNewFormat(t, config, tmpHome) 182 183 expConfStr := `{ 184 "auths": { 185 "https://index.docker.io/v1/": { 186 "auth": "am9lam9lOmhlbGxv" 187 } 188 } 189 }` 190 191 if configStr != expConfStr { 192 t.Fatalf("Should have save in new form: \n%s\n not \n%s", configStr, expConfStr) 193 } 194 } 195 196 func TestOldJsonInvalid(t *testing.T) { 197 tmpHome, err := ioutil.TempDir("", "config-test") 198 if err != nil { 199 t.Fatal(err) 200 } 201 defer os.RemoveAll(tmpHome) 202 203 homeKey := homedir.Key() 204 homeVal := homedir.Get() 205 206 defer func() { os.Setenv(homeKey, homeVal) }() 207 os.Setenv(homeKey, tmpHome) 208 209 fn := filepath.Join(tmpHome, oldConfigfile) 210 js := `{"https://index.docker.io/v1/":{"auth":"test","email":"user@example.com"}}` 211 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 212 t.Fatal(err) 213 } 214 215 config, err := Load(tmpHome) 216 // Use Contains instead of == since the file name will change each time 217 if err == nil || !strings.Contains(err.Error(), "Invalid auth configuration file") { 218 t.Fatalf("Expected an error got : %v, %v", config, err) 219 } 220 } 221 222 func TestOldJson(t *testing.T) { 223 tmpHome, err := ioutil.TempDir("", "config-test") 224 if err != nil { 225 t.Fatal(err) 226 } 227 defer os.RemoveAll(tmpHome) 228 229 homeKey := homedir.Key() 230 homeVal := homedir.Get() 231 232 defer func() { os.Setenv(homeKey, homeVal) }() 233 os.Setenv(homeKey, tmpHome) 234 235 fn := filepath.Join(tmpHome, oldConfigfile) 236 js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}` 237 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 238 t.Fatal(err) 239 } 240 241 config, err := Load(tmpHome) 242 if err != nil { 243 t.Fatalf("Failed loading on empty json file: %q", err) 244 } 245 246 ac := config.AuthConfigs["https://index.docker.io/v1/"] 247 if ac.Username != "joejoe" || ac.Password != "hello" { 248 t.Fatalf("Missing data from parsing:\n%q", config) 249 } 250 251 // Now save it and make sure it shows up in new form 252 configStr := saveConfigAndValidateNewFormat(t, config, tmpHome) 253 254 expConfStr := `{ 255 "auths": { 256 "https://index.docker.io/v1/": { 257 "auth": "am9lam9lOmhlbGxv", 258 "email": "user@example.com" 259 } 260 } 261 }` 262 263 if configStr != expConfStr { 264 t.Fatalf("Should have save in new form: \n'%s'\n not \n'%s'\n", configStr, expConfStr) 265 } 266 } 267 268 func TestNewJson(t *testing.T) { 269 tmpHome, err := ioutil.TempDir("", "config-test") 270 if err != nil { 271 t.Fatal(err) 272 } 273 defer os.RemoveAll(tmpHome) 274 275 fn := filepath.Join(tmpHome, ConfigFileName) 276 js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } } }` 277 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 278 t.Fatal(err) 279 } 280 281 config, err := Load(tmpHome) 282 if err != nil { 283 t.Fatalf("Failed loading on empty json file: %q", err) 284 } 285 286 ac := config.AuthConfigs["https://index.docker.io/v1/"] 287 if ac.Username != "joejoe" || ac.Password != "hello" { 288 t.Fatalf("Missing data from parsing:\n%q", config) 289 } 290 291 // Now save it and make sure it shows up in new form 292 configStr := saveConfigAndValidateNewFormat(t, config, tmpHome) 293 294 expConfStr := `{ 295 "auths": { 296 "https://index.docker.io/v1/": { 297 "auth": "am9lam9lOmhlbGxv" 298 } 299 } 300 }` 301 302 if configStr != expConfStr { 303 t.Fatalf("Should have save in new form: \n%s\n not \n%s", configStr, expConfStr) 304 } 305 } 306 307 func TestNewJsonNoEmail(t *testing.T) { 308 tmpHome, err := ioutil.TempDir("", "config-test") 309 if err != nil { 310 t.Fatal(err) 311 } 312 defer os.RemoveAll(tmpHome) 313 314 fn := filepath.Join(tmpHome, ConfigFileName) 315 js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } } }` 316 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 317 t.Fatal(err) 318 } 319 320 config, err := Load(tmpHome) 321 if err != nil { 322 t.Fatalf("Failed loading on empty json file: %q", err) 323 } 324 325 ac := config.AuthConfigs["https://index.docker.io/v1/"] 326 if ac.Username != "joejoe" || ac.Password != "hello" { 327 t.Fatalf("Missing data from parsing:\n%q", config) 328 } 329 330 // Now save it and make sure it shows up in new form 331 configStr := saveConfigAndValidateNewFormat(t, config, tmpHome) 332 333 expConfStr := `{ 334 "auths": { 335 "https://index.docker.io/v1/": { 336 "auth": "am9lam9lOmhlbGxv" 337 } 338 } 339 }` 340 341 if configStr != expConfStr { 342 t.Fatalf("Should have save in new form: \n%s\n not \n%s", configStr, expConfStr) 343 } 344 } 345 346 func TestJsonWithPsFormat(t *testing.T) { 347 tmpHome, err := ioutil.TempDir("", "config-test") 348 if err != nil { 349 t.Fatal(err) 350 } 351 defer os.RemoveAll(tmpHome) 352 353 fn := filepath.Join(tmpHome, ConfigFileName) 354 js := `{ 355 "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } }, 356 "psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}" 357 }` 358 if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil { 359 t.Fatal(err) 360 } 361 362 config, err := Load(tmpHome) 363 if err != nil { 364 t.Fatalf("Failed loading on empty json file: %q", err) 365 } 366 367 if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` { 368 t.Fatalf("Unknown ps format: %s\n", config.PsFormat) 369 } 370 371 // Now save it and make sure it shows up in new form 372 configStr := saveConfigAndValidateNewFormat(t, config, tmpHome) 373 if !strings.Contains(configStr, `"psFormat":`) || 374 !strings.Contains(configStr, "{{.ID}}") { 375 t.Fatalf("Should have save in new form: %s", configStr) 376 } 377 } 378 379 // Save it and make sure it shows up in new form 380 func saveConfigAndValidateNewFormat(t *testing.T, config *configfile.ConfigFile, homeFolder string) string { 381 if err := config.Save(); err != nil { 382 t.Fatalf("Failed to save: %q", err) 383 } 384 385 buf, err := ioutil.ReadFile(filepath.Join(homeFolder, ConfigFileName)) 386 if err != nil { 387 t.Fatal(err) 388 } 389 if !strings.Contains(string(buf), `"auths":`) { 390 t.Fatalf("Should have save in new form: %s", string(buf)) 391 } 392 return string(buf) 393 } 394 395 func TestConfigDir(t *testing.T) { 396 tmpHome, err := ioutil.TempDir("", "config-test") 397 if err != nil { 398 t.Fatal(err) 399 } 400 defer os.RemoveAll(tmpHome) 401 402 if ConfigDir() == tmpHome { 403 t.Fatalf("Expected ConfigDir to be different than %s by default, but was the same", tmpHome) 404 } 405 406 // Update configDir 407 SetConfigDir(tmpHome) 408 409 if ConfigDir() != tmpHome { 410 t.Fatalf("Expected ConfigDir to %s, but was %s", tmpHome, ConfigDir()) 411 } 412 } 413 414 func TestConfigFile(t *testing.T) { 415 configFilename := "configFilename" 416 configFile := NewConfigFile(configFilename) 417 418 if configFile.Filename != configFilename { 419 t.Fatalf("Expected %s, got %s", configFilename, configFile.Filename) 420 } 421 } 422 423 func TestJsonReaderNoFile(t *testing.T) { 424 js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } } }` 425 426 config, err := LoadFromReader(strings.NewReader(js)) 427 if err != nil { 428 t.Fatalf("Failed loading on empty json file: %q", err) 429 } 430 431 ac := config.AuthConfigs["https://index.docker.io/v1/"] 432 if ac.Username != "joejoe" || ac.Password != "hello" { 433 t.Fatalf("Missing data from parsing:\n%q", config) 434 } 435 436 } 437 438 func TestOldJsonReaderNoFile(t *testing.T) { 439 js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}` 440 441 config, err := LegacyLoadFromReader(strings.NewReader(js)) 442 if err != nil { 443 t.Fatalf("Failed loading on empty json file: %q", err) 444 } 445 446 ac := config.AuthConfigs["https://index.docker.io/v1/"] 447 if ac.Username != "joejoe" || ac.Password != "hello" { 448 t.Fatalf("Missing data from parsing:\n%q", config) 449 } 450 } 451 452 func TestJsonWithPsFormatNoFile(t *testing.T) { 453 js := `{ 454 "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } }, 455 "psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}" 456 }` 457 config, err := LoadFromReader(strings.NewReader(js)) 458 if err != nil { 459 t.Fatalf("Failed loading on empty json file: %q", err) 460 } 461 462 if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` { 463 t.Fatalf("Unknown ps format: %s\n", config.PsFormat) 464 } 465 466 } 467 468 func TestJsonSaveWithNoFile(t *testing.T) { 469 js := `{ 470 "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } }, 471 "psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}" 472 }` 473 config, err := LoadFromReader(strings.NewReader(js)) 474 err = config.Save() 475 if err == nil { 476 t.Fatalf("Expected error. File should not have been able to save with no file name.") 477 } 478 479 tmpHome, err := ioutil.TempDir("", "config-test") 480 if err != nil { 481 t.Fatalf("Failed to create a temp dir: %q", err) 482 } 483 defer os.RemoveAll(tmpHome) 484 485 fn := filepath.Join(tmpHome, ConfigFileName) 486 f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 487 err = config.SaveToWriter(f) 488 if err != nil { 489 t.Fatalf("Failed saving to file: %q", err) 490 } 491 buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName)) 492 if err != nil { 493 t.Fatal(err) 494 } 495 expConfStr := `{ 496 "auths": { 497 "https://index.docker.io/v1/": { 498 "auth": "am9lam9lOmhlbGxv" 499 } 500 }, 501 "psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}" 502 }` 503 if string(buf) != expConfStr { 504 t.Fatalf("Should have save in new form: \n%s\nnot \n%s", string(buf), expConfStr) 505 } 506 } 507 508 func TestLegacyJsonSaveWithNoFile(t *testing.T) { 509 510 js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}` 511 config, err := LegacyLoadFromReader(strings.NewReader(js)) 512 err = config.Save() 513 if err == nil { 514 t.Fatalf("Expected error. File should not have been able to save with no file name.") 515 } 516 517 tmpHome, err := ioutil.TempDir("", "config-test") 518 if err != nil { 519 t.Fatalf("Failed to create a temp dir: %q", err) 520 } 521 defer os.RemoveAll(tmpHome) 522 523 fn := filepath.Join(tmpHome, ConfigFileName) 524 f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 525 if err = config.SaveToWriter(f); err != nil { 526 t.Fatalf("Failed saving to file: %q", err) 527 } 528 buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName)) 529 if err != nil { 530 t.Fatal(err) 531 } 532 533 expConfStr := `{ 534 "auths": { 535 "https://index.docker.io/v1/": { 536 "auth": "am9lam9lOmhlbGxv", 537 "email": "user@example.com" 538 } 539 } 540 }` 541 542 if string(buf) != expConfStr { 543 t.Fatalf("Should have save in new form: \n%s\n not \n%s", string(buf), expConfStr) 544 } 545 }