github.com/ghodss/etcd@v0.3.1-0.20140417172404-cc329bfa55cb/config/config_test.go (about)

     1  package config
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/coreos/etcd/third_party/github.com/BurntSushi/toml"
     9  	"github.com/coreos/etcd/third_party/github.com/stretchr/testify/assert"
    10  )
    11  
    12  // Ensures that a configuration can be deserialized from TOML.
    13  func TestConfigTOML(t *testing.T) {
    14  	content := `
    15  		addr = "127.0.0.1:4002"
    16  		ca_file = "/tmp/file.ca"
    17  		cert_file = "/tmp/file.cert"
    18  		cors = ["*"]
    19  		cpu_profile_file = "XXX"
    20  		data_dir = "/tmp/data"
    21  		discovery = "http://example.com/foobar"
    22  		key_file = "/tmp/file.key"
    23  		bind_addr = "127.0.0.1:4003"
    24  		peers = ["coreos.com:4001", "coreos.com:4002"]
    25  		peers_file = "/tmp/peers"
    26  		max_cluster_size = 10
    27  		max_result_buffer = 512
    28  		max_retry_attempts = 5
    29  		name = "test-name"
    30  		snapshot = true
    31  		verbose = true
    32  		very_verbose = true
    33  
    34  		[peer]
    35  		addr = "127.0.0.1:7002"
    36  		ca_file = "/tmp/peer/file.ca"
    37  		cert_file = "/tmp/peer/file.cert"
    38  		key_file = "/tmp/peer/file.key"
    39  		bind_addr = "127.0.0.1:7003"
    40  	`
    41  	c := New()
    42  	_, err := toml.Decode(content, &c)
    43  	assert.Nil(t, err, "")
    44  	assert.Equal(t, c.Addr, "127.0.0.1:4002", "")
    45  	assert.Equal(t, c.CAFile, "/tmp/file.ca", "")
    46  	assert.Equal(t, c.CertFile, "/tmp/file.cert", "")
    47  	assert.Equal(t, c.CorsOrigins, []string{"*"}, "")
    48  	assert.Equal(t, c.DataDir, "/tmp/data", "")
    49  	assert.Equal(t, c.Discovery, "http://example.com/foobar", "")
    50  	assert.Equal(t, c.KeyFile, "/tmp/file.key", "")
    51  	assert.Equal(t, c.BindAddr, "127.0.0.1:4003", "")
    52  	assert.Equal(t, c.Peers, []string{"coreos.com:4001", "coreos.com:4002"}, "")
    53  	assert.Equal(t, c.PeersFile, "/tmp/peers", "")
    54  	assert.Equal(t, c.MaxResultBuffer, 512, "")
    55  	assert.Equal(t, c.MaxRetryAttempts, 5, "")
    56  	assert.Equal(t, c.Name, "test-name", "")
    57  	assert.Equal(t, c.Snapshot, true, "")
    58  	assert.Equal(t, c.Verbose, true, "")
    59  	assert.Equal(t, c.VeryVerbose, true, "")
    60  	assert.Equal(t, c.Peer.Addr, "127.0.0.1:7002", "")
    61  	assert.Equal(t, c.Peer.CAFile, "/tmp/peer/file.ca", "")
    62  	assert.Equal(t, c.Peer.CertFile, "/tmp/peer/file.cert", "")
    63  	assert.Equal(t, c.Peer.KeyFile, "/tmp/peer/file.key", "")
    64  	assert.Equal(t, c.Peer.BindAddr, "127.0.0.1:7003", "")
    65  }
    66  
    67  // Ensures that a configuration can be retrieved from environment variables.
    68  func TestConfigEnv(t *testing.T) {
    69  	os.Setenv("ETCD_CA_FILE", "/tmp/file.ca")
    70  	os.Setenv("ETCD_CERT_FILE", "/tmp/file.cert")
    71  	os.Setenv("ETCD_CPU_PROFILE_FILE", "XXX")
    72  	os.Setenv("ETCD_CORS", "localhost:4001,localhost:4002")
    73  	os.Setenv("ETCD_DATA_DIR", "/tmp/data")
    74  	os.Setenv("ETCD_DISCOVERY", "http://example.com/foobar")
    75  	os.Setenv("ETCD_KEY_FILE", "/tmp/file.key")
    76  	os.Setenv("ETCD_BIND_ADDR", "127.0.0.1:4003")
    77  	os.Setenv("ETCD_PEERS", "coreos.com:4001,coreos.com:4002")
    78  	os.Setenv("ETCD_PEERS_FILE", "/tmp/peers")
    79  	os.Setenv("ETCD_MAX_CLUSTER_SIZE", "10")
    80  	os.Setenv("ETCD_MAX_RESULT_BUFFER", "512")
    81  	os.Setenv("ETCD_MAX_RETRY_ATTEMPTS", "5")
    82  	os.Setenv("ETCD_NAME", "test-name")
    83  	os.Setenv("ETCD_SNAPSHOT", "true")
    84  	os.Setenv("ETCD_VERBOSE", "1")
    85  	os.Setenv("ETCD_VERY_VERBOSE", "yes")
    86  	os.Setenv("ETCD_PEER_ADDR", "127.0.0.1:7002")
    87  	os.Setenv("ETCD_PEER_CA_FILE", "/tmp/peer/file.ca")
    88  	os.Setenv("ETCD_PEER_CERT_FILE", "/tmp/peer/file.cert")
    89  	os.Setenv("ETCD_PEER_KEY_FILE", "/tmp/peer/file.key")
    90  	os.Setenv("ETCD_PEER_BIND_ADDR", "127.0.0.1:7003")
    91  
    92  	c := New()
    93  	c.LoadEnv()
    94  	assert.Equal(t, c.CAFile, "/tmp/file.ca", "")
    95  	assert.Equal(t, c.CertFile, "/tmp/file.cert", "")
    96  	assert.Equal(t, c.CorsOrigins, []string{"localhost:4001", "localhost:4002"}, "")
    97  	assert.Equal(t, c.DataDir, "/tmp/data", "")
    98  	assert.Equal(t, c.Discovery, "http://example.com/foobar", "")
    99  	assert.Equal(t, c.KeyFile, "/tmp/file.key", "")
   100  	assert.Equal(t, c.BindAddr, "127.0.0.1:4003", "")
   101  	assert.Equal(t, c.Peers, []string{"coreos.com:4001", "coreos.com:4002"}, "")
   102  	assert.Equal(t, c.PeersFile, "/tmp/peers", "")
   103  	assert.Equal(t, c.MaxResultBuffer, 512, "")
   104  	assert.Equal(t, c.MaxRetryAttempts, 5, "")
   105  	assert.Equal(t, c.Name, "test-name", "")
   106  	assert.Equal(t, c.Snapshot, true, "")
   107  	assert.Equal(t, c.Verbose, true, "")
   108  	assert.Equal(t, c.VeryVerbose, true, "")
   109  	assert.Equal(t, c.Peer.Addr, "127.0.0.1:7002", "")
   110  	assert.Equal(t, c.Peer.CAFile, "/tmp/peer/file.ca", "")
   111  	assert.Equal(t, c.Peer.CertFile, "/tmp/peer/file.cert", "")
   112  	assert.Equal(t, c.Peer.KeyFile, "/tmp/peer/file.key", "")
   113  	assert.Equal(t, c.Peer.BindAddr, "127.0.0.1:7003", "")
   114  
   115  	// Clear this as it will mess up other tests
   116  	os.Setenv("ETCD_DISCOVERY", "")
   117  }
   118  
   119  // Ensures that the "help" flag can be parsed.
   120  func TestConfigHelpFlag(t *testing.T) {
   121  	c := New()
   122  	assert.Nil(t, c.LoadFlags([]string{"-help"}), "")
   123  	assert.True(t, c.ShowHelp)
   124  }
   125  
   126  // Ensures that the abbreviated "help" flag can be parsed.
   127  func TestConfigAbbreviatedHelpFlag(t *testing.T) {
   128  	c := New()
   129  	assert.Nil(t, c.LoadFlags([]string{"-h"}), "")
   130  	assert.True(t, c.ShowHelp)
   131  }
   132  
   133  // Ensures that the "version" flag can be parsed.
   134  func TestConfigVersionFlag(t *testing.T) {
   135  	c := New()
   136  	assert.Nil(t, c.LoadFlags([]string{"-version"}), "")
   137  	assert.True(t, c.ShowVersion)
   138  }
   139  
   140  // Ensures that the "force config" flag can be parsed.
   141  func TestConfigForceFlag(t *testing.T) {
   142  	c := New()
   143  	assert.Nil(t, c.LoadFlags([]string{"-force"}), "")
   144  	assert.True(t, c.Force)
   145  }
   146  
   147  // Ensures that the abbreviated "force config" flag can be parsed.
   148  func TestConfigAbbreviatedForceFlag(t *testing.T) {
   149  	c := New()
   150  	assert.Nil(t, c.LoadFlags([]string{"-f"}), "")
   151  	assert.True(t, c.Force)
   152  }
   153  
   154  // Ensures that a the advertised url can be parsed from the environment.
   155  func TestConfigAddrEnv(t *testing.T) {
   156  	withEnv("ETCD_ADDR", "127.0.0.1:4002", func(c *Config) {
   157  		assert.Nil(t, c.LoadEnv(), "")
   158  		assert.Equal(t, c.Addr, "127.0.0.1:4002", "")
   159  	})
   160  }
   161  
   162  // Ensures that a the advertised flag can be parsed.
   163  func TestConfigAddrFlag(t *testing.T) {
   164  	c := New()
   165  	assert.Nil(t, c.LoadFlags([]string{"-addr", "127.0.0.1:4002"}), "")
   166  	assert.Equal(t, c.Addr, "127.0.0.1:4002", "")
   167  }
   168  
   169  // Ensures that a the CA file can be parsed from the environment.
   170  func TestConfigCAFileEnv(t *testing.T) {
   171  	withEnv("ETCD_CA_FILE", "/tmp/file.ca", func(c *Config) {
   172  		assert.Nil(t, c.LoadEnv(), "")
   173  		assert.Equal(t, c.CAFile, "/tmp/file.ca", "")
   174  	})
   175  }
   176  
   177  // Ensures that a the CA file flag can be parsed.
   178  func TestConfigCAFileFlag(t *testing.T) {
   179  	c := New()
   180  	assert.Nil(t, c.LoadFlags([]string{"-ca-file", "/tmp/file.ca"}), "")
   181  	assert.Equal(t, c.CAFile, "/tmp/file.ca", "")
   182  }
   183  
   184  // Ensures that a the CA file can be parsed from the environment.
   185  func TestConfigCertFileEnv(t *testing.T) {
   186  	withEnv("ETCD_CERT_FILE", "/tmp/file.cert", func(c *Config) {
   187  		assert.Nil(t, c.LoadEnv(), "")
   188  		assert.Equal(t, c.CertFile, "/tmp/file.cert", "")
   189  	})
   190  }
   191  
   192  // Ensures that a the Cert file flag can be parsed.
   193  func TestConfigCertFileFlag(t *testing.T) {
   194  	c := New()
   195  	assert.Nil(t, c.LoadFlags([]string{"-cert-file", "/tmp/file.cert"}), "")
   196  	assert.Equal(t, c.CertFile, "/tmp/file.cert", "")
   197  }
   198  
   199  // Ensures that a the Key file can be parsed from the environment.
   200  func TestConfigKeyFileEnv(t *testing.T) {
   201  	withEnv("ETCD_KEY_FILE", "/tmp/file.key", func(c *Config) {
   202  		assert.Nil(t, c.LoadEnv(), "")
   203  		assert.Equal(t, c.KeyFile, "/tmp/file.key", "")
   204  	})
   205  }
   206  
   207  // Ensures that a the Key file flag can be parsed.
   208  func TestConfigKeyFileFlag(t *testing.T) {
   209  	c := New()
   210  	assert.Nil(t, c.LoadFlags([]string{"-key-file", "/tmp/file.key"}), "")
   211  	assert.Equal(t, c.KeyFile, "/tmp/file.key", "")
   212  }
   213  
   214  // Ensures that a the Listen Host can be parsed from the environment.
   215  func TestConfigBindAddrEnv(t *testing.T) {
   216  	withEnv("ETCD_BIND_ADDR", "127.0.0.1:4003", func(c *Config) {
   217  		assert.Nil(t, c.LoadEnv(), "")
   218  		assert.Equal(t, c.BindAddr, "127.0.0.1:4003", "")
   219  	})
   220  }
   221  
   222  // Ensures that a the Listen Host file flag can be parsed.
   223  func TestConfigBindAddrFlag(t *testing.T) {
   224  	c := New()
   225  	assert.Nil(t, c.LoadFlags([]string{"-bind-addr", "127.0.0.1:4003"}), "")
   226  	assert.Equal(t, c.BindAddr, "127.0.0.1:4003", "")
   227  }
   228  
   229  // Ensures that a the Listen Host port overrides the advertised port
   230  func TestConfigBindAddrOverride(t *testing.T) {
   231  	c := New()
   232  	assert.Nil(t, c.LoadFlags([]string{"-addr", "127.0.0.1:4009", "-bind-addr", "127.0.0.1:4010"}), "")
   233  	assert.Nil(t, c.Sanitize())
   234  	assert.Equal(t, c.BindAddr, "127.0.0.1:4010", "")
   235  }
   236  
   237  // Ensures that a the Listen Host inherits its port from the advertised addr
   238  func TestConfigBindAddrInheritPort(t *testing.T) {
   239  	c := New()
   240  	assert.Nil(t, c.LoadFlags([]string{"-addr", "127.0.0.1:4009", "-bind-addr", "127.0.0.1"}), "")
   241  	assert.Nil(t, c.Sanitize())
   242  	assert.Equal(t, c.BindAddr, "127.0.0.1:4009", "")
   243  }
   244  
   245  // Ensures that a port only argument errors out
   246  func TestConfigBindAddrErrorOnNoHost(t *testing.T) {
   247  	c := New()
   248  	assert.Nil(t, c.LoadFlags([]string{"-addr", "127.0.0.1:4009", "-bind-addr", ":4010"}), "")
   249  	assert.Error(t, c.Sanitize())
   250  }
   251  
   252  // Ensures that the peers can be parsed from the environment.
   253  func TestConfigPeersEnv(t *testing.T) {
   254  	withEnv("ETCD_PEERS", "coreos.com:4001,coreos.com:4002", func(c *Config) {
   255  		assert.Nil(t, c.LoadEnv(), "")
   256  		assert.Equal(t, c.Peers, []string{"coreos.com:4001", "coreos.com:4002"}, "")
   257  	})
   258  }
   259  
   260  // Ensures that a the Peers flag can be parsed.
   261  func TestConfigPeersFlag(t *testing.T) {
   262  	c := New()
   263  	assert.Nil(t, c.LoadFlags([]string{"-peers", "coreos.com:4001,coreos.com:4002"}), "")
   264  	assert.Equal(t, c.Peers, []string{"coreos.com:4001", "coreos.com:4002"}, "")
   265  }
   266  
   267  // Ensures that the Peers File can be parsed from the environment.
   268  func TestConfigPeersFileEnv(t *testing.T) {
   269  	withEnv("ETCD_PEERS_FILE", "/tmp/peers", func(c *Config) {
   270  		assert.Nil(t, c.LoadEnv(), "")
   271  		assert.Equal(t, c.PeersFile, "/tmp/peers", "")
   272  	})
   273  }
   274  
   275  // Ensures that a the Peers File flag can be parsed.
   276  func TestConfigPeersFileFlag(t *testing.T) {
   277  	c := New()
   278  	assert.Nil(t, c.LoadFlags([]string{"-peers-file", "/tmp/peers"}), "")
   279  	assert.Equal(t, c.PeersFile, "/tmp/peers", "")
   280  }
   281  
   282  // Ensures that the Max Result Buffer can be parsed from the environment.
   283  func TestConfigMaxResultBufferEnv(t *testing.T) {
   284  	withEnv("ETCD_MAX_RESULT_BUFFER", "512", func(c *Config) {
   285  		assert.Nil(t, c.LoadEnv(), "")
   286  		assert.Equal(t, c.MaxResultBuffer, 512, "")
   287  	})
   288  }
   289  
   290  // Ensures that a the Max Result Buffer flag can be parsed.
   291  func TestConfigMaxResultBufferFlag(t *testing.T) {
   292  	c := New()
   293  	assert.Nil(t, c.LoadFlags([]string{"-max-result-buffer", "512"}), "")
   294  	assert.Equal(t, c.MaxResultBuffer, 512, "")
   295  }
   296  
   297  // Ensures that the Max Retry Attempts can be parsed from the environment.
   298  func TestConfigMaxRetryAttemptsEnv(t *testing.T) {
   299  	withEnv("ETCD_MAX_RETRY_ATTEMPTS", "10", func(c *Config) {
   300  		assert.Nil(t, c.LoadEnv(), "")
   301  		assert.Equal(t, c.MaxRetryAttempts, 10, "")
   302  	})
   303  }
   304  
   305  // Ensures that a the Max Retry Attempts flag can be parsed.
   306  func TestConfigMaxRetryAttemptsFlag(t *testing.T) {
   307  	c := New()
   308  	assert.Nil(t, c.LoadFlags([]string{"-max-retry-attempts", "10"}), "")
   309  	assert.Equal(t, c.MaxRetryAttempts, 10, "")
   310  }
   311  
   312  // Ensures that the Name can be parsed from the environment.
   313  func TestConfigNameEnv(t *testing.T) {
   314  	withEnv("ETCD_NAME", "test-name", func(c *Config) {
   315  		assert.Nil(t, c.LoadEnv(), "")
   316  		assert.Equal(t, c.Name, "test-name", "")
   317  	})
   318  }
   319  
   320  // Ensures that a the Name flag can be parsed.
   321  func TestConfigNameFlag(t *testing.T) {
   322  	c := New()
   323  	assert.Nil(t, c.LoadFlags([]string{"-name", "test-name"}), "")
   324  	assert.Equal(t, c.Name, "test-name", "")
   325  }
   326  
   327  // Ensures that a Name gets guessed if not specified
   328  func TestConfigNameGuess(t *testing.T) {
   329  	c := New()
   330  	assert.Nil(t, c.LoadFlags([]string{}), "")
   331  	assert.Nil(t, c.Sanitize())
   332  	name, _ := os.Hostname()
   333  	assert.Equal(t, c.Name, name, "")
   334  }
   335  
   336  // Ensures that a DataDir gets guessed if not specified
   337  func TestConfigDataDirGuess(t *testing.T) {
   338  	c := New()
   339  	assert.Nil(t, c.LoadFlags([]string{}), "")
   340  	assert.Nil(t, c.Sanitize())
   341  	name, _ := os.Hostname()
   342  	assert.Equal(t, c.DataDir, name+".etcd", "")
   343  }
   344  
   345  // Ensures that Snapshot can be parsed from the environment.
   346  func TestConfigSnapshotEnv(t *testing.T) {
   347  	withEnv("ETCD_SNAPSHOT", "1", func(c *Config) {
   348  		assert.Nil(t, c.LoadEnv(), "")
   349  		assert.Equal(t, c.Snapshot, true, "")
   350  	})
   351  }
   352  
   353  // Ensures that a the Snapshot flag can be parsed.
   354  func TestConfigSnapshotFlag(t *testing.T) {
   355  	c := New()
   356  	assert.Nil(t, c.LoadFlags([]string{"-snapshot"}), "")
   357  	assert.Equal(t, c.Snapshot, true, "")
   358  }
   359  
   360  // Ensures that Verbose can be parsed from the environment.
   361  func TestConfigVerboseEnv(t *testing.T) {
   362  	withEnv("ETCD_VERBOSE", "true", func(c *Config) {
   363  		assert.Nil(t, c.LoadEnv(), "")
   364  		assert.Equal(t, c.Verbose, true, "")
   365  	})
   366  }
   367  
   368  // Ensures that a the Verbose flag can be parsed.
   369  func TestConfigVerboseFlag(t *testing.T) {
   370  	c := New()
   371  	assert.Nil(t, c.LoadFlags([]string{"-v"}), "")
   372  	assert.Equal(t, c.Verbose, true, "")
   373  }
   374  
   375  // Ensures that Very Verbose can be parsed from the environment.
   376  func TestConfigVeryVerboseEnv(t *testing.T) {
   377  	withEnv("ETCD_VERY_VERBOSE", "true", func(c *Config) {
   378  		assert.Nil(t, c.LoadEnv(), "")
   379  		assert.Equal(t, c.VeryVerbose, true, "")
   380  	})
   381  }
   382  
   383  // Ensures that a the Very Verbose flag can be parsed.
   384  func TestConfigVeryVerboseFlag(t *testing.T) {
   385  	c := New()
   386  	assert.Nil(t, c.LoadFlags([]string{"-vv"}), "")
   387  	assert.Equal(t, c.VeryVerbose, true, "")
   388  }
   389  
   390  // Ensures that the Peer Advertised URL can be parsed from the environment.
   391  func TestConfigPeerAddrEnv(t *testing.T) {
   392  	withEnv("ETCD_PEER_ADDR", "localhost:7002", func(c *Config) {
   393  		assert.Nil(t, c.LoadEnv(), "")
   394  		assert.Equal(t, c.Peer.Addr, "localhost:7002", "")
   395  	})
   396  }
   397  
   398  // Ensures that a the Peer Advertised URL flag can be parsed.
   399  func TestConfigPeerAddrFlag(t *testing.T) {
   400  	c := New()
   401  	assert.Nil(t, c.LoadFlags([]string{"-peer-addr", "localhost:7002"}), "")
   402  	assert.Equal(t, c.Peer.Addr, "localhost:7002", "")
   403  }
   404  
   405  // Ensures that the Peer CA File can be parsed from the environment.
   406  func TestConfigPeerCAFileEnv(t *testing.T) {
   407  	withEnv("ETCD_PEER_CA_FILE", "/tmp/peer/file.ca", func(c *Config) {
   408  		assert.Nil(t, c.LoadEnv(), "")
   409  		assert.Equal(t, c.Peer.CAFile, "/tmp/peer/file.ca", "")
   410  	})
   411  }
   412  
   413  // Ensures that a the Peer CA file flag can be parsed.
   414  func TestConfigPeerCAFileFlag(t *testing.T) {
   415  	c := New()
   416  	assert.Nil(t, c.LoadFlags([]string{"-peer-ca-file", "/tmp/peer/file.ca"}), "")
   417  	assert.Equal(t, c.Peer.CAFile, "/tmp/peer/file.ca", "")
   418  }
   419  
   420  // Ensures that the Peer Cert File can be parsed from the environment.
   421  func TestConfigPeerCertFileEnv(t *testing.T) {
   422  	withEnv("ETCD_PEER_CERT_FILE", "/tmp/peer/file.cert", func(c *Config) {
   423  		assert.Nil(t, c.LoadEnv(), "")
   424  		assert.Equal(t, c.Peer.CertFile, "/tmp/peer/file.cert", "")
   425  	})
   426  }
   427  
   428  // Ensures that a the Cert file flag can be parsed.
   429  func TestConfigPeerCertFileFlag(t *testing.T) {
   430  	c := New()
   431  	assert.Nil(t, c.LoadFlags([]string{"-peer-cert-file", "/tmp/peer/file.cert"}), "")
   432  	assert.Equal(t, c.Peer.CertFile, "/tmp/peer/file.cert", "")
   433  }
   434  
   435  // Ensures that the Peer Key File can be parsed from the environment.
   436  func TestConfigPeerKeyFileEnv(t *testing.T) {
   437  	withEnv("ETCD_PEER_KEY_FILE", "/tmp/peer/file.key", func(c *Config) {
   438  		assert.Nil(t, c.LoadEnv(), "")
   439  		assert.Equal(t, c.Peer.KeyFile, "/tmp/peer/file.key", "")
   440  	})
   441  }
   442  
   443  // Ensures that a the Peer Key file flag can be parsed.
   444  func TestConfigPeerKeyFileFlag(t *testing.T) {
   445  	c := New()
   446  	assert.Nil(t, c.LoadFlags([]string{"-peer-key-file", "/tmp/peer/file.key"}), "")
   447  	assert.Equal(t, c.Peer.KeyFile, "/tmp/peer/file.key", "")
   448  }
   449  
   450  // Ensures that the Peer Listen Host can be parsed from the environment.
   451  func TestConfigPeerBindAddrEnv(t *testing.T) {
   452  	withEnv("ETCD_PEER_BIND_ADDR", "localhost:7004", func(c *Config) {
   453  		assert.Nil(t, c.LoadEnv(), "")
   454  		assert.Equal(t, c.Peer.BindAddr, "localhost:7004", "")
   455  	})
   456  }
   457  
   458  // Ensures that a bad flag returns an error.
   459  func TestConfigBadFlag(t *testing.T) {
   460  	c := New()
   461  	err := c.LoadFlags([]string{"-no-such-flag"})
   462  	assert.Error(t, err)
   463  	assert.Equal(t, err.Error(), `flag provided but not defined: -no-such-flag`)
   464  }
   465  
   466  // Ensures that a the Peer Listen Host file flag can be parsed.
   467  func TestConfigPeerBindAddrFlag(t *testing.T) {
   468  	c := New()
   469  	assert.Nil(t, c.LoadFlags([]string{"-peer-bind-addr", "127.0.0.1:4003"}), "")
   470  	assert.Equal(t, c.Peer.BindAddr, "127.0.0.1:4003", "")
   471  }
   472  
   473  // Ensures that a system config field is overridden by a custom config field.
   474  func TestConfigCustomConfigOverrideSystemConfig(t *testing.T) {
   475  	system := `addr = "127.0.0.1:5000"`
   476  	custom := `addr = "127.0.0.1:6000"`
   477  	withTempFile(system, func(p1 string) {
   478  		withTempFile(custom, func(p2 string) {
   479  			c := New()
   480  			c.SystemPath = p1
   481  			assert.Nil(t, c.Load([]string{"-config", p2}), "")
   482  			assert.Equal(t, c.Addr, "http://127.0.0.1:6000", "")
   483  		})
   484  	})
   485  }
   486  
   487  // Ensures that a custom config field is overridden by an environment variable.
   488  func TestConfigEnvVarOverrideCustomConfig(t *testing.T) {
   489  	os.Setenv("ETCD_PEER_ADDR", "127.0.0.1:8000")
   490  	defer os.Setenv("ETCD_PEER_ADDR", "")
   491  
   492  	custom := `[peer]` + "\n" + `advertised_url = "127.0.0.1:9000"`
   493  	withTempFile(custom, func(path string) {
   494  		c := New()
   495  		c.SystemPath = ""
   496  		assert.Nil(t, c.Load([]string{"-config", path}), "")
   497  		assert.Equal(t, c.Peer.Addr, "http://127.0.0.1:8000", "")
   498  	})
   499  }
   500  
   501  // Ensures that an environment variable field is overridden by a command line argument.
   502  func TestConfigCLIArgsOverrideEnvVar(t *testing.T) {
   503  	os.Setenv("ETCD_ADDR", "127.0.0.1:1000")
   504  	defer os.Setenv("ETCD_ADDR", "")
   505  
   506  	c := New()
   507  	c.SystemPath = ""
   508  	assert.Nil(t, c.Load([]string{"-addr", "127.0.0.1:2000"}), "")
   509  	assert.Equal(t, c.Addr, "http://127.0.0.1:2000", "")
   510  }
   511  
   512  //--------------------------------------
   513  // DEPRECATED (v1)
   514  //--------------------------------------
   515  
   516  func TestConfigDeprecatedAddrFlag(t *testing.T) {
   517  	_, stderr := capture(func() {
   518  		c := New()
   519  		err := c.LoadFlags([]string{"-c", "127.0.0.1:4002"})
   520  		assert.NoError(t, err)
   521  		assert.Equal(t, c.Addr, "127.0.0.1:4002")
   522  	})
   523  	assert.Equal(t, stderr, "[deprecated] use -addr, not -c\n")
   524  }
   525  
   526  func TestConfigDeprecatedBindAddrFlag(t *testing.T) {
   527  	_, stderr := capture(func() {
   528  		c := New()
   529  		err := c.LoadFlags([]string{"-cl", "127.0.0.1:4003"})
   530  		assert.NoError(t, err)
   531  		assert.Equal(t, c.BindAddr, "127.0.0.1:4003", "")
   532  	})
   533  	assert.Equal(t, stderr, "[deprecated] use -bind-addr, not -cl\n", "")
   534  }
   535  
   536  func TestConfigDeprecatedCAFileFlag(t *testing.T) {
   537  	_, stderr := capture(func() {
   538  		c := New()
   539  		err := c.LoadFlags([]string{"-clientCAFile", "/tmp/file.ca"})
   540  		assert.NoError(t, err)
   541  		assert.Equal(t, c.CAFile, "/tmp/file.ca", "")
   542  	})
   543  	assert.Equal(t, stderr, "[deprecated] use -ca-file, not -clientCAFile\n", "")
   544  }
   545  
   546  func TestConfigDeprecatedCertFileFlag(t *testing.T) {
   547  	_, stderr := capture(func() {
   548  		c := New()
   549  		err := c.LoadFlags([]string{"-clientCert", "/tmp/file.cert"})
   550  		assert.NoError(t, err)
   551  		assert.Equal(t, c.CertFile, "/tmp/file.cert", "")
   552  	})
   553  	assert.Equal(t, stderr, "[deprecated] use -cert-file, not -clientCert\n", "")
   554  }
   555  
   556  func TestConfigDeprecatedKeyFileFlag(t *testing.T) {
   557  	_, stderr := capture(func() {
   558  		c := New()
   559  		err := c.LoadFlags([]string{"-clientKey", "/tmp/file.key"})
   560  		assert.NoError(t, err)
   561  		assert.Equal(t, c.KeyFile, "/tmp/file.key", "")
   562  	})
   563  	assert.Equal(t, stderr, "[deprecated] use -key-file, not -clientKey\n", "")
   564  }
   565  
   566  func TestConfigDeprecatedPeersFlag(t *testing.T) {
   567  	_, stderr := capture(func() {
   568  		c := New()
   569  		err := c.LoadFlags([]string{"-C", "coreos.com:4001,coreos.com:4002"})
   570  		assert.NoError(t, err)
   571  		assert.Equal(t, c.Peers, []string{"coreos.com:4001", "coreos.com:4002"}, "")
   572  	})
   573  	assert.Equal(t, stderr, "[deprecated] use -peers, not -C\n", "")
   574  }
   575  
   576  func TestConfigDeprecatedPeersFileFlag(t *testing.T) {
   577  	_, stderr := capture(func() {
   578  		c := New()
   579  		err := c.LoadFlags([]string{"-CF", "/tmp/machines"})
   580  		assert.NoError(t, err)
   581  		assert.Equal(t, c.PeersFile, "/tmp/machines", "")
   582  	})
   583  	assert.Equal(t, stderr, "[deprecated] use -peers-file, not -CF\n", "")
   584  }
   585  
   586  func TestConfigDeprecatedMaxRetryAttemptsFlag(t *testing.T) {
   587  	_, stderr := capture(func() {
   588  		c := New()
   589  		err := c.LoadFlags([]string{"-r", "10"})
   590  		assert.NoError(t, err)
   591  		assert.Equal(t, c.MaxRetryAttempts, 10, "")
   592  	})
   593  	assert.Equal(t, stderr, "[deprecated] use -max-retry-attempts, not -r\n", "")
   594  }
   595  
   596  func TestConfigDeprecatedNameFlag(t *testing.T) {
   597  	_, stderr := capture(func() {
   598  		c := New()
   599  		err := c.LoadFlags([]string{"-n", "test-name"})
   600  		assert.NoError(t, err)
   601  		assert.Equal(t, c.Name, "test-name", "")
   602  	})
   603  	assert.Equal(t, stderr, "[deprecated] use -name, not -n\n", "")
   604  }
   605  
   606  func TestConfigDeprecatedPeerAddrFlag(t *testing.T) {
   607  	_, stderr := capture(func() {
   608  		c := New()
   609  		err := c.LoadFlags([]string{"-s", "localhost:7002"})
   610  		assert.NoError(t, err)
   611  		assert.Equal(t, c.Peer.Addr, "localhost:7002", "")
   612  	})
   613  	assert.Equal(t, stderr, "[deprecated] use -peer-addr, not -s\n", "")
   614  }
   615  
   616  func TestConfigDeprecatedPeerBindAddrFlag(t *testing.T) {
   617  	_, stderr := capture(func() {
   618  		c := New()
   619  		err := c.LoadFlags([]string{"-sl", "127.0.0.1:4003"})
   620  		assert.NoError(t, err)
   621  		assert.Equal(t, c.Peer.BindAddr, "127.0.0.1:4003", "")
   622  	})
   623  	assert.Equal(t, stderr, "[deprecated] use -peer-bind-addr, not -sl\n", "")
   624  }
   625  
   626  func TestConfigDeprecatedPeerCAFileFlag(t *testing.T) {
   627  	_, stderr := capture(func() {
   628  		c := New()
   629  		err := c.LoadFlags([]string{"-serverCAFile", "/tmp/peer/file.ca"})
   630  		assert.NoError(t, err)
   631  		assert.Equal(t, c.Peer.CAFile, "/tmp/peer/file.ca", "")
   632  	})
   633  	assert.Equal(t, stderr, "[deprecated] use -peer-ca-file, not -serverCAFile\n", "")
   634  }
   635  
   636  func TestConfigDeprecatedPeerCertFileFlag(t *testing.T) {
   637  	_, stderr := capture(func() {
   638  		c := New()
   639  		err := c.LoadFlags([]string{"-serverCert", "/tmp/peer/file.cert"})
   640  		assert.NoError(t, err)
   641  		assert.Equal(t, c.Peer.CertFile, "/tmp/peer/file.cert", "")
   642  	})
   643  	assert.Equal(t, stderr, "[deprecated] use -peer-cert-file, not -serverCert\n", "")
   644  }
   645  
   646  func TestConfigDeprecatedPeerKeyFileFlag(t *testing.T) {
   647  	_, stderr := capture(func() {
   648  		c := New()
   649  		err := c.LoadFlags([]string{"-serverKey", "/tmp/peer/file.key"})
   650  		assert.NoError(t, err)
   651  		assert.Equal(t, c.Peer.KeyFile, "/tmp/peer/file.key", "")
   652  	})
   653  	assert.Equal(t, stderr, "[deprecated] use -peer-key-file, not -serverKey\n", "")
   654  }
   655  
   656  //--------------------------------------
   657  // Helpers
   658  //--------------------------------------
   659  
   660  // Sets up the environment with a given environment variable set.
   661  func withEnv(key, value string, f func(c *Config)) {
   662  	os.Setenv(key, value)
   663  	defer os.Setenv(key, "")
   664  	c := New()
   665  	f(c)
   666  }
   667  
   668  // Creates a temp file and calls a function with the context.
   669  func withTempFile(content string, fn func(string)) {
   670  	f, _ := ioutil.TempFile("", "")
   671  	f.WriteString(content)
   672  	f.Close()
   673  	defer os.Remove(f.Name())
   674  	fn(f.Name())
   675  }
   676  
   677  // Captures STDOUT & STDERR and returns the output as strings.
   678  func capture(fn func()) (string, string) {
   679  	// Create temp files.
   680  	tmpout, _ := ioutil.TempFile("", "")
   681  	defer os.Remove(tmpout.Name())
   682  	tmperr, _ := ioutil.TempFile("", "")
   683  	defer os.Remove(tmperr.Name())
   684  
   685  	stdout, stderr := os.Stdout, os.Stderr
   686  	os.Stdout, os.Stderr = tmpout, tmperr
   687  
   688  	// Execute function argument and then reassign stdout/stderr.
   689  	fn()
   690  	os.Stdout, os.Stderr = stdout, stderr
   691  
   692  	// Close temp files and read them.
   693  	tmpout.Close()
   694  	bout, _ := ioutil.ReadFile(tmpout.Name())
   695  	tmperr.Close()
   696  	berr, _ := ioutil.ReadFile(tmperr.Name())
   697  
   698  	return string(bout), string(berr)
   699  }