config_test.go 15 KB

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