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  }