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