gitee.com/bomy/docker.git@v1.13.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  func TestJSONWithCredentialStore(t *testing.T) {
   380  	tmpHome, err := ioutil.TempDir("", "config-test")
   381  	if err != nil {
   382  		t.Fatal(err)
   383  	}
   384  	defer os.RemoveAll(tmpHome)
   385  
   386  	fn := filepath.Join(tmpHome, ConfigFileName)
   387  	js := `{
   388  		"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } },
   389  		"credsStore": "crazy-secure-storage"
   390  }`
   391  	if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
   392  		t.Fatal(err)
   393  	}
   394  
   395  	config, err := Load(tmpHome)
   396  	if err != nil {
   397  		t.Fatalf("Failed loading on empty json file: %q", err)
   398  	}
   399  
   400  	if config.CredentialsStore != "crazy-secure-storage" {
   401  		t.Fatalf("Unknown credential store: %s\n", config.CredentialsStore)
   402  	}
   403  
   404  	// Now save it and make sure it shows up in new form
   405  	configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
   406  	if !strings.Contains(configStr, `"credsStore":`) ||
   407  		!strings.Contains(configStr, "crazy-secure-storage") {
   408  		t.Fatalf("Should have save in new form: %s", configStr)
   409  	}
   410  }
   411  
   412  func TestJSONWithCredentialHelpers(t *testing.T) {
   413  	tmpHome, err := ioutil.TempDir("", "config-test")
   414  	if err != nil {
   415  		t.Fatal(err)
   416  	}
   417  	defer os.RemoveAll(tmpHome)
   418  
   419  	fn := filepath.Join(tmpHome, ConfigFileName)
   420  	js := `{
   421  		"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } },
   422  		"credHelpers": { "images.io": "images-io", "containers.com": "crazy-secure-storage" }
   423  }`
   424  	if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
   425  		t.Fatal(err)
   426  	}
   427  
   428  	config, err := Load(tmpHome)
   429  	if err != nil {
   430  		t.Fatalf("Failed loading on empty json file: %q", err)
   431  	}
   432  
   433  	if config.CredentialHelpers == nil {
   434  		t.Fatal("config.CredentialHelpers was nil")
   435  	} else if config.CredentialHelpers["images.io"] != "images-io" ||
   436  		config.CredentialHelpers["containers.com"] != "crazy-secure-storage" {
   437  		t.Fatalf("Credential helpers not deserialized properly: %v\n", config.CredentialHelpers)
   438  	}
   439  
   440  	// Now save it and make sure it shows up in new form
   441  	configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
   442  	if !strings.Contains(configStr, `"credHelpers":`) ||
   443  		!strings.Contains(configStr, "images.io") ||
   444  		!strings.Contains(configStr, "images-io") ||
   445  		!strings.Contains(configStr, "containers.com") ||
   446  		!strings.Contains(configStr, "crazy-secure-storage") {
   447  		t.Fatalf("Should have save in new form: %s", configStr)
   448  	}
   449  }
   450  
   451  // Save it and make sure it shows up in new form
   452  func saveConfigAndValidateNewFormat(t *testing.T, config *configfile.ConfigFile, homeFolder string) string {
   453  	if err := config.Save(); err != nil {
   454  		t.Fatalf("Failed to save: %q", err)
   455  	}
   456  
   457  	buf, err := ioutil.ReadFile(filepath.Join(homeFolder, ConfigFileName))
   458  	if err != nil {
   459  		t.Fatal(err)
   460  	}
   461  	if !strings.Contains(string(buf), `"auths":`) {
   462  		t.Fatalf("Should have save in new form: %s", string(buf))
   463  	}
   464  	return string(buf)
   465  }
   466  
   467  func TestConfigDir(t *testing.T) {
   468  	tmpHome, err := ioutil.TempDir("", "config-test")
   469  	if err != nil {
   470  		t.Fatal(err)
   471  	}
   472  	defer os.RemoveAll(tmpHome)
   473  
   474  	if ConfigDir() == tmpHome {
   475  		t.Fatalf("Expected ConfigDir to be different than %s by default, but was the same", tmpHome)
   476  	}
   477  
   478  	// Update configDir
   479  	SetConfigDir(tmpHome)
   480  
   481  	if ConfigDir() != tmpHome {
   482  		t.Fatalf("Expected ConfigDir to %s, but was %s", tmpHome, ConfigDir())
   483  	}
   484  }
   485  
   486  func TestConfigFile(t *testing.T) {
   487  	configFilename := "configFilename"
   488  	configFile := NewConfigFile(configFilename)
   489  
   490  	if configFile.Filename != configFilename {
   491  		t.Fatalf("Expected %s, got %s", configFilename, configFile.Filename)
   492  	}
   493  }
   494  
   495  func TestJSONReaderNoFile(t *testing.T) {
   496  	js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } } }`
   497  
   498  	config, err := LoadFromReader(strings.NewReader(js))
   499  	if err != nil {
   500  		t.Fatalf("Failed loading on empty json file: %q", err)
   501  	}
   502  
   503  	ac := config.AuthConfigs["https://index.docker.io/v1/"]
   504  	if ac.Username != "joejoe" || ac.Password != "hello" {
   505  		t.Fatalf("Missing data from parsing:\n%q", config)
   506  	}
   507  
   508  }
   509  
   510  func TestOldJSONReaderNoFile(t *testing.T) {
   511  	js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
   512  
   513  	config, err := LegacyLoadFromReader(strings.NewReader(js))
   514  	if err != nil {
   515  		t.Fatalf("Failed loading on empty json file: %q", err)
   516  	}
   517  
   518  	ac := config.AuthConfigs["https://index.docker.io/v1/"]
   519  	if ac.Username != "joejoe" || ac.Password != "hello" {
   520  		t.Fatalf("Missing data from parsing:\n%q", config)
   521  	}
   522  }
   523  
   524  func TestJSONWithPsFormatNoFile(t *testing.T) {
   525  	js := `{
   526  		"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } },
   527  		"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
   528  }`
   529  	config, err := LoadFromReader(strings.NewReader(js))
   530  	if err != nil {
   531  		t.Fatalf("Failed loading on empty json file: %q", err)
   532  	}
   533  
   534  	if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` {
   535  		t.Fatalf("Unknown ps format: %s\n", config.PsFormat)
   536  	}
   537  
   538  }
   539  
   540  func TestJSONSaveWithNoFile(t *testing.T) {
   541  	js := `{
   542  		"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } },
   543  		"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
   544  }`
   545  	config, err := LoadFromReader(strings.NewReader(js))
   546  	err = config.Save()
   547  	if err == nil {
   548  		t.Fatalf("Expected error. File should not have been able to save with no file name.")
   549  	}
   550  
   551  	tmpHome, err := ioutil.TempDir("", "config-test")
   552  	if err != nil {
   553  		t.Fatalf("Failed to create a temp dir: %q", err)
   554  	}
   555  	defer os.RemoveAll(tmpHome)
   556  
   557  	fn := filepath.Join(tmpHome, ConfigFileName)
   558  	f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
   559  	defer f.Close()
   560  
   561  	err = config.SaveToWriter(f)
   562  	if err != nil {
   563  		t.Fatalf("Failed saving to file: %q", err)
   564  	}
   565  	buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName))
   566  	if err != nil {
   567  		t.Fatal(err)
   568  	}
   569  	expConfStr := `{
   570  	"auths": {
   571  		"https://index.docker.io/v1/": {
   572  			"auth": "am9lam9lOmhlbGxv"
   573  		}
   574  	},
   575  	"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
   576  }`
   577  	if string(buf) != expConfStr {
   578  		t.Fatalf("Should have save in new form: \n%s\nnot \n%s", string(buf), expConfStr)
   579  	}
   580  }
   581  
   582  func TestLegacyJSONSaveWithNoFile(t *testing.T) {
   583  
   584  	js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
   585  	config, err := LegacyLoadFromReader(strings.NewReader(js))
   586  	err = config.Save()
   587  	if err == nil {
   588  		t.Fatalf("Expected error. File should not have been able to save with no file name.")
   589  	}
   590  
   591  	tmpHome, err := ioutil.TempDir("", "config-test")
   592  	if err != nil {
   593  		t.Fatalf("Failed to create a temp dir: %q", err)
   594  	}
   595  	defer os.RemoveAll(tmpHome)
   596  
   597  	fn := filepath.Join(tmpHome, ConfigFileName)
   598  	f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
   599  	defer f.Close()
   600  
   601  	if err = config.SaveToWriter(f); err != nil {
   602  		t.Fatalf("Failed saving to file: %q", err)
   603  	}
   604  	buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName))
   605  	if err != nil {
   606  		t.Fatal(err)
   607  	}
   608  
   609  	expConfStr := `{
   610  	"auths": {
   611  		"https://index.docker.io/v1/": {
   612  			"auth": "am9lam9lOmhlbGxv",
   613  			"email": "user@example.com"
   614  		}
   615  	}
   616  }`
   617  
   618  	if string(buf) != expConfStr {
   619  		t.Fatalf("Should have save in new form: \n%s\n not \n%s", string(buf), expConfStr)
   620  	}
   621  }