config_test.go 24 KB

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