config_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of go-ethereum.
  3. //
  4. // go-ethereum is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // go-ethereum is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  16. package main
  17. import (
  18. "fmt"
  19. "io"
  20. "io/ioutil"
  21. "os"
  22. "os/exec"
  23. "testing"
  24. "time"
  25. "github.com/ethereum/go-ethereum/rpc"
  26. "github.com/ethereum/go-ethereum/swarm"
  27. "github.com/ethereum/go-ethereum/swarm/api"
  28. "github.com/docker/docker/pkg/reexec"
  29. )
  30. func TestDumpConfig(t *testing.T) {
  31. swarm := runSwarm(t, "dumpconfig")
  32. defaultConf := api.NewDefaultConfig()
  33. out, err := tomlSettings.Marshal(&defaultConf)
  34. if err != nil {
  35. t.Fatal(err)
  36. }
  37. swarm.Expect(string(out))
  38. swarm.ExpectExit()
  39. }
  40. func TestFailsSwapEnabledNoSwapApi(t *testing.T) {
  41. flags := []string{
  42. fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42",
  43. fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545",
  44. fmt.Sprintf("--%s", SwarmSwapEnabledFlag.Name),
  45. }
  46. swarm := runSwarm(t, flags...)
  47. swarm.Expect("Fatal: " + SWARM_ERR_SWAP_SET_NO_API + "\n")
  48. swarm.ExpectExit()
  49. }
  50. func TestFailsNoBzzAccount(t *testing.T) {
  51. flags := []string{
  52. fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42",
  53. fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545",
  54. }
  55. swarm := runSwarm(t, flags...)
  56. swarm.Expect("Fatal: " + SWARM_ERR_NO_BZZACCOUNT + "\n")
  57. swarm.ExpectExit()
  58. }
  59. func TestCmdLineOverrides(t *testing.T) {
  60. dir, err := ioutil.TempDir("", "bzztest")
  61. if err != nil {
  62. t.Fatal(err)
  63. }
  64. defer os.RemoveAll(dir)
  65. conf, account := getTestAccount(t, dir)
  66. node := &testNode{Dir: dir}
  67. // assign ports
  68. httpPort, err := assignTCPPort()
  69. if err != nil {
  70. t.Fatal(err)
  71. }
  72. flags := []string{
  73. fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42",
  74. fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort,
  75. fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name),
  76. fmt.Sprintf("--%s", CorsStringFlag.Name), "*",
  77. fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(),
  78. fmt.Sprintf("--%s", EnsAPIFlag.Name), "",
  79. "--datadir", dir,
  80. "--ipcpath", conf.IPCPath,
  81. }
  82. node.Cmd = runSwarm(t, flags...)
  83. node.Cmd.InputLine(testPassphrase)
  84. defer func() {
  85. if t.Failed() {
  86. node.Shutdown()
  87. }
  88. }()
  89. // wait for the node to start
  90. for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) {
  91. node.Client, err = rpc.Dial(conf.IPCEndpoint())
  92. if err == nil {
  93. break
  94. }
  95. }
  96. if node.Client == nil {
  97. t.Fatal(err)
  98. }
  99. // load info
  100. var info swarm.Info
  101. if err := node.Client.Call(&info, "bzz_info"); err != nil {
  102. t.Fatal(err)
  103. }
  104. if info.Port != httpPort {
  105. t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port)
  106. }
  107. if info.NetworkId != 42 {
  108. t.Fatalf("Expected network ID to be %d, got %d", 42, info.NetworkId)
  109. }
  110. if !info.SyncEnabled {
  111. t.Fatal("Expected Sync to be enabled, but is false")
  112. }
  113. if info.Cors != "*" {
  114. t.Fatalf("Expected Cors flag to be set to %s, got %s", "*", info.Cors)
  115. }
  116. node.Shutdown()
  117. }
  118. func TestFileOverrides(t *testing.T) {
  119. // assign ports
  120. httpPort, err := assignTCPPort()
  121. if err != nil {
  122. t.Fatal(err)
  123. }
  124. //create a config file
  125. //first, create a default conf
  126. defaultConf := api.NewDefaultConfig()
  127. //change some values in order to test if they have been loaded
  128. defaultConf.SyncEnabled = true
  129. defaultConf.NetworkId = 54
  130. defaultConf.Port = httpPort
  131. defaultConf.StoreParams.DbCapacity = 9000000
  132. defaultConf.ChunkerParams.Branches = 64
  133. defaultConf.HiveParams.CallInterval = 6000000000
  134. defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second
  135. defaultConf.SyncParams.KeyBufferSize = 512
  136. //create a TOML string
  137. out, err := tomlSettings.Marshal(&defaultConf)
  138. if err != nil {
  139. t.Fatalf("Error creating TOML file in TestFileOverride: %v", err)
  140. }
  141. //create file
  142. f, err := ioutil.TempFile("", "testconfig.toml")
  143. if err != nil {
  144. t.Fatalf("Error writing TOML file in TestFileOverride: %v", err)
  145. }
  146. //write file
  147. _, err = f.WriteString(string(out))
  148. if err != nil {
  149. t.Fatalf("Error writing TOML file in TestFileOverride: %v", err)
  150. }
  151. f.Sync()
  152. dir, err := ioutil.TempDir("", "bzztest")
  153. if err != nil {
  154. t.Fatal(err)
  155. }
  156. defer os.RemoveAll(dir)
  157. conf, account := getTestAccount(t, dir)
  158. node := &testNode{Dir: dir}
  159. flags := []string{
  160. fmt.Sprintf("--%s", SwarmTomlConfigPathFlag.Name), f.Name(),
  161. fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(),
  162. "--ens-api", "",
  163. "--ipcpath", conf.IPCPath,
  164. "--datadir", dir,
  165. }
  166. node.Cmd = runSwarm(t, flags...)
  167. node.Cmd.InputLine(testPassphrase)
  168. defer func() {
  169. if t.Failed() {
  170. node.Shutdown()
  171. }
  172. }()
  173. // wait for the node to start
  174. for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) {
  175. node.Client, err = rpc.Dial(conf.IPCEndpoint())
  176. if err == nil {
  177. break
  178. }
  179. }
  180. if node.Client == nil {
  181. t.Fatal(err)
  182. }
  183. // load info
  184. var info swarm.Info
  185. if err := node.Client.Call(&info, "bzz_info"); err != nil {
  186. t.Fatal(err)
  187. }
  188. if info.Port != httpPort {
  189. t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port)
  190. }
  191. if info.NetworkId != 54 {
  192. t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId)
  193. }
  194. if !info.SyncEnabled {
  195. t.Fatal("Expected Sync to be enabled, but is false")
  196. }
  197. if info.StoreParams.DbCapacity != 9000000 {
  198. t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId)
  199. }
  200. if info.ChunkerParams.Branches != 64 {
  201. t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches)
  202. }
  203. if info.HiveParams.CallInterval != 6000000000 {
  204. t.Fatalf("Expected HiveParams CallInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.CallInterval))
  205. }
  206. if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second {
  207. t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval)
  208. }
  209. if info.SyncParams.KeyBufferSize != 512 {
  210. t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize)
  211. }
  212. node.Shutdown()
  213. }
  214. func TestEnvVars(t *testing.T) {
  215. // assign ports
  216. httpPort, err := assignTCPPort()
  217. if err != nil {
  218. t.Fatal(err)
  219. }
  220. envVars := os.Environ()
  221. envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmPortFlag.EnvVar, httpPort))
  222. envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmNetworkIdFlag.EnvVar, "999"))
  223. envVars = append(envVars, fmt.Sprintf("%s=%s", CorsStringFlag.EnvVar, "*"))
  224. envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmSyncEnabledFlag.EnvVar, "true"))
  225. dir, err := ioutil.TempDir("", "bzztest")
  226. if err != nil {
  227. t.Fatal(err)
  228. }
  229. defer os.RemoveAll(dir)
  230. conf, account := getTestAccount(t, dir)
  231. node := &testNode{Dir: dir}
  232. flags := []string{
  233. fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(),
  234. "--ens-api", "",
  235. "--datadir", dir,
  236. "--ipcpath", conf.IPCPath,
  237. }
  238. //node.Cmd = runSwarm(t,flags...)
  239. //node.Cmd.cmd.Env = envVars
  240. //the above assignment does not work, so we need a custom Cmd here in order to pass envVars:
  241. cmd := &exec.Cmd{
  242. Path: reexec.Self(),
  243. Args: append([]string{"swarm-test"}, flags...),
  244. Stderr: os.Stderr,
  245. Stdout: os.Stdout,
  246. }
  247. cmd.Env = envVars
  248. //stdout, err := cmd.StdoutPipe()
  249. //if err != nil {
  250. // t.Fatal(err)
  251. //}
  252. //stdout = bufio.NewReader(stdout)
  253. var stdin io.WriteCloser
  254. if stdin, err = cmd.StdinPipe(); err != nil {
  255. t.Fatal(err)
  256. }
  257. if err := cmd.Start(); err != nil {
  258. t.Fatal(err)
  259. }
  260. //cmd.InputLine(testPassphrase)
  261. io.WriteString(stdin, testPassphrase+"\n")
  262. defer func() {
  263. if t.Failed() {
  264. node.Shutdown()
  265. cmd.Process.Kill()
  266. }
  267. }()
  268. // wait for the node to start
  269. for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) {
  270. node.Client, err = rpc.Dial(conf.IPCEndpoint())
  271. if err == nil {
  272. break
  273. }
  274. }
  275. if node.Client == nil {
  276. t.Fatal(err)
  277. }
  278. // load info
  279. var info swarm.Info
  280. if err := node.Client.Call(&info, "bzz_info"); err != nil {
  281. t.Fatal(err)
  282. }
  283. if info.Port != httpPort {
  284. t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port)
  285. }
  286. if info.NetworkId != 999 {
  287. t.Fatalf("Expected network ID to be %d, got %d", 999, info.NetworkId)
  288. }
  289. if info.Cors != "*" {
  290. t.Fatalf("Expected Cors flag to be set to %s, got %s", "*", info.Cors)
  291. }
  292. if !info.SyncEnabled {
  293. t.Fatal("Expected Sync to be enabled, but is false")
  294. }
  295. node.Shutdown()
  296. cmd.Process.Kill()
  297. }
  298. func TestCmdLineOverridesFile(t *testing.T) {
  299. // assign ports
  300. httpPort, err := assignTCPPort()
  301. if err != nil {
  302. t.Fatal(err)
  303. }
  304. //create a config file
  305. //first, create a default conf
  306. defaultConf := api.NewDefaultConfig()
  307. //change some values in order to test if they have been loaded
  308. defaultConf.SyncEnabled = false
  309. defaultConf.NetworkId = 54
  310. defaultConf.Port = "8588"
  311. defaultConf.StoreParams.DbCapacity = 9000000
  312. defaultConf.ChunkerParams.Branches = 64
  313. defaultConf.HiveParams.CallInterval = 6000000000
  314. defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second
  315. defaultConf.SyncParams.KeyBufferSize = 512
  316. //create a TOML file
  317. out, err := tomlSettings.Marshal(&defaultConf)
  318. if err != nil {
  319. t.Fatalf("Error creating TOML file in TestFileOverride: %v", err)
  320. }
  321. //write file
  322. f, err := ioutil.TempFile("", "testconfig.toml")
  323. if err != nil {
  324. t.Fatalf("Error writing TOML file in TestFileOverride: %v", err)
  325. }
  326. //write file
  327. _, err = f.WriteString(string(out))
  328. if err != nil {
  329. t.Fatalf("Error writing TOML file in TestFileOverride: %v", err)
  330. }
  331. f.Sync()
  332. dir, err := ioutil.TempDir("", "bzztest")
  333. if err != nil {
  334. t.Fatal(err)
  335. }
  336. defer os.RemoveAll(dir)
  337. conf, account := getTestAccount(t, dir)
  338. node := &testNode{Dir: dir}
  339. expectNetworkId := uint64(77)
  340. flags := []string{
  341. fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "77",
  342. fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort,
  343. fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name),
  344. fmt.Sprintf("--%s", SwarmTomlConfigPathFlag.Name), f.Name(),
  345. fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(),
  346. "--ens-api", "",
  347. "--datadir", dir,
  348. "--ipcpath", conf.IPCPath,
  349. }
  350. node.Cmd = runSwarm(t, flags...)
  351. node.Cmd.InputLine(testPassphrase)
  352. defer func() {
  353. if t.Failed() {
  354. node.Shutdown()
  355. }
  356. }()
  357. // wait for the node to start
  358. for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) {
  359. node.Client, err = rpc.Dial(conf.IPCEndpoint())
  360. if err == nil {
  361. break
  362. }
  363. }
  364. if node.Client == nil {
  365. t.Fatal(err)
  366. }
  367. // load info
  368. var info swarm.Info
  369. if err := node.Client.Call(&info, "bzz_info"); err != nil {
  370. t.Fatal(err)
  371. }
  372. if info.Port != httpPort {
  373. t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port)
  374. }
  375. if info.NetworkId != expectNetworkId {
  376. t.Fatalf("Expected network ID to be %d, got %d", expectNetworkId, info.NetworkId)
  377. }
  378. if !info.SyncEnabled {
  379. t.Fatal("Expected Sync to be enabled, but is false")
  380. }
  381. if info.StoreParams.DbCapacity != 9000000 {
  382. t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId)
  383. }
  384. if info.ChunkerParams.Branches != 64 {
  385. t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches)
  386. }
  387. if info.HiveParams.CallInterval != 6000000000 {
  388. t.Fatalf("Expected HiveParams CallInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.CallInterval))
  389. }
  390. if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second {
  391. t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval)
  392. }
  393. if info.SyncParams.KeyBufferSize != 512 {
  394. t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize)
  395. }
  396. node.Shutdown()
  397. }
  398. func TestValidateConfig(t *testing.T) {
  399. for _, c := range []struct {
  400. cfg *api.Config
  401. err string
  402. }{
  403. {
  404. cfg: &api.Config{EnsAPIs: []string{
  405. "/data/testnet/geth.ipc",
  406. }},
  407. },
  408. {
  409. cfg: &api.Config{EnsAPIs: []string{
  410. "http://127.0.0.1:1234",
  411. }},
  412. },
  413. {
  414. cfg: &api.Config{EnsAPIs: []string{
  415. "ws://127.0.0.1:1234",
  416. }},
  417. },
  418. {
  419. cfg: &api.Config{EnsAPIs: []string{
  420. "test:/data/testnet/geth.ipc",
  421. }},
  422. },
  423. {
  424. cfg: &api.Config{EnsAPIs: []string{
  425. "test:ws://127.0.0.1:1234",
  426. }},
  427. },
  428. {
  429. cfg: &api.Config{EnsAPIs: []string{
  430. "314159265dD8dbb310642f98f50C066173C1259b@/data/testnet/geth.ipc",
  431. }},
  432. },
  433. {
  434. cfg: &api.Config{EnsAPIs: []string{
  435. "314159265dD8dbb310642f98f50C066173C1259b@http://127.0.0.1:1234",
  436. }},
  437. },
  438. {
  439. cfg: &api.Config{EnsAPIs: []string{
  440. "314159265dD8dbb310642f98f50C066173C1259b@ws://127.0.0.1:1234",
  441. }},
  442. },
  443. {
  444. cfg: &api.Config{EnsAPIs: []string{
  445. "test:314159265dD8dbb310642f98f50C066173C1259b@/data/testnet/geth.ipc",
  446. }},
  447. },
  448. {
  449. cfg: &api.Config{EnsAPIs: []string{
  450. "eth:314159265dD8dbb310642f98f50C066173C1259b@http://127.0.0.1:1234",
  451. }},
  452. },
  453. {
  454. cfg: &api.Config{EnsAPIs: []string{
  455. "eth:314159265dD8dbb310642f98f50C066173C1259b@ws://127.0.0.1:12344",
  456. }},
  457. },
  458. {
  459. cfg: &api.Config{EnsAPIs: []string{
  460. "eth:",
  461. }},
  462. err: "invalid format [tld:][contract-addr@]url for ENS API endpoint configuration \"eth:\": missing url",
  463. },
  464. {
  465. cfg: &api.Config{EnsAPIs: []string{
  466. "314159265dD8dbb310642f98f50C066173C1259b@",
  467. }},
  468. err: "invalid format [tld:][contract-addr@]url for ENS API endpoint configuration \"314159265dD8dbb310642f98f50C066173C1259b@\": missing url",
  469. },
  470. {
  471. cfg: &api.Config{EnsAPIs: []string{
  472. ":314159265dD8dbb310642f98f50C066173C1259",
  473. }},
  474. err: "invalid format [tld:][contract-addr@]url for ENS API endpoint configuration \":314159265dD8dbb310642f98f50C066173C1259\": missing tld",
  475. },
  476. {
  477. cfg: &api.Config{EnsAPIs: []string{
  478. "@/data/testnet/geth.ipc",
  479. }},
  480. err: "invalid format [tld:][contract-addr@]url for ENS API endpoint configuration \"@/data/testnet/geth.ipc\": missing contract address",
  481. },
  482. } {
  483. err := validateConfig(c.cfg)
  484. if c.err != "" && err.Error() != c.err {
  485. t.Errorf("expected error %q, got %q", c.err, err)
  486. }
  487. if c.err == "" && err != nil {
  488. t.Errorf("unexpected error %q", err)
  489. }
  490. }
  491. }