config_test.go 24 KB

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