mirror of https://github.com/ethereum/go-ethereum
cmd/swarm: add config file (#15548)
This commit adds a TOML configuration option to swarm. It reuses the TOML configuration structure used in geth with swarm customized items. The commit: * Adds a "dumpconfig" command to the swarm executable which allows printing the (default) configuration to stdout, which then can be redirected to a file in order to customize it. * Adds a "--config <file>" option to the swarm executable which will allow to load a configuration file in TOML format from the specified location in order to initialize the Swarm node The override priorities are like follows: environment variables override command line arguments override config file override default config.pull/15659/head
parent
1a32bdf92c
commit
32516c768e
@ -0,0 +1,321 @@ |
||||
// Copyright 2017 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"io" |
||||
"os" |
||||
"reflect" |
||||
"strconv" |
||||
"unicode" |
||||
|
||||
cli "gopkg.in/urfave/cli.v1" |
||||
|
||||
"github.com/ethereum/go-ethereum/cmd/utils" |
||||
"github.com/ethereum/go-ethereum/common" |
||||
"github.com/ethereum/go-ethereum/log" |
||||
"github.com/ethereum/go-ethereum/node" |
||||
"github.com/naoina/toml" |
||||
|
||||
bzzapi "github.com/ethereum/go-ethereum/swarm/api" |
||||
) |
||||
|
||||
var ( |
||||
//flag definition for the dumpconfig command
|
||||
DumpConfigCommand = cli.Command{ |
||||
Action: utils.MigrateFlags(dumpConfig), |
||||
Name: "dumpconfig", |
||||
Usage: "Show configuration values", |
||||
ArgsUsage: "", |
||||
Flags: app.Flags, |
||||
Category: "MISCELLANEOUS COMMANDS", |
||||
Description: `The dumpconfig command shows configuration values.`, |
||||
} |
||||
|
||||
//flag definition for the config file command
|
||||
SwarmTomlConfigPathFlag = cli.StringFlag{ |
||||
Name: "config", |
||||
Usage: "TOML configuration file", |
||||
} |
||||
) |
||||
|
||||
//constants for environment variables
|
||||
const ( |
||||
SWARM_ENV_CHEQUEBOOK_ADDR = "SWARM_CHEQUEBOOK_ADDR" |
||||
SWARM_ENV_ACCOUNT = "SWARM_ACCOUNT" |
||||
SWARM_ENV_LISTEN_ADDR = "SWARM_LISTEN_ADDR" |
||||
SWARM_ENV_PORT = "SWARM_PORT" |
||||
SWARM_ENV_NETWORK_ID = "SWARM_NETWORK_ID" |
||||
SWARM_ENV_SWAP_ENABLE = "SWARM_SWAP_ENABLE" |
||||
SWARM_ENV_SWAP_API = "SWARM_SWAP_API" |
||||
SWARM_ENV_SYNC_ENABLE = "SWARM_SYNC_ENABLE" |
||||
SWARM_ENV_ENS_API = "SWARM_ENS_API" |
||||
SWARM_ENV_ENS_ADDR = "SWARM_ENS_ADDR" |
||||
SWARM_ENV_CORS = "SWARM_CORS" |
||||
SWARM_ENV_BOOTNODES = "SWARM_BOOTNODES" |
||||
GETH_ENV_DATADIR = "GETH_DATADIR" |
||||
) |
||||
|
||||
// These settings ensure that TOML keys use the same names as Go struct fields.
|
||||
var tomlSettings = toml.Config{ |
||||
NormFieldName: func(rt reflect.Type, key string) string { |
||||
return key |
||||
}, |
||||
FieldToKey: func(rt reflect.Type, field string) string { |
||||
return field |
||||
}, |
||||
MissingField: func(rt reflect.Type, field string) error { |
||||
link := "" |
||||
if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" { |
||||
link = fmt.Sprintf(", check github.com/ethereum/go-ethereum/swarm/api/config.go for available fields") |
||||
} |
||||
return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link) |
||||
}, |
||||
} |
||||
|
||||
//before booting the swarm node, build the configuration
|
||||
func buildConfig(ctx *cli.Context) (config *bzzapi.Config, err error) { |
||||
//check for deprecated flags
|
||||
checkDeprecated(ctx) |
||||
//start by creating a default config
|
||||
config = bzzapi.NewDefaultConfig() |
||||
//first load settings from config file (if provided)
|
||||
config, err = configFileOverride(config, ctx) |
||||
//override settings provided by environment variables
|
||||
config = envVarsOverride(config) |
||||
//override settings provided by command line
|
||||
config = cmdLineOverride(config, ctx) |
||||
|
||||
return |
||||
} |
||||
|
||||
//finally, after the configuration build phase is finished, initialize
|
||||
func initSwarmNode(config *bzzapi.Config, stack *node.Node, ctx *cli.Context) { |
||||
//at this point, all vars should be set in the Config
|
||||
//get the account for the provided swarm account
|
||||
prvkey := getAccount(config.BzzAccount, ctx, stack) |
||||
//set the resolved config path (geth --datadir)
|
||||
config.Path = stack.InstanceDir() |
||||
//finally, initialize the configuration
|
||||
config.Init(prvkey) |
||||
//configuration phase completed here
|
||||
log.Debug("Starting Swarm with the following parameters:") |
||||
//after having created the config, print it to screen
|
||||
log.Debug(printConfig(config)) |
||||
} |
||||
|
||||
//override the current config with whatever is in the config file, if a config file has been provided
|
||||
func configFileOverride(config *bzzapi.Config, ctx *cli.Context) (*bzzapi.Config, error) { |
||||
var err error |
||||
|
||||
//only do something if the -config flag has been set
|
||||
if ctx.GlobalIsSet(SwarmTomlConfigPathFlag.Name) { |
||||
var filepath string |
||||
if filepath = ctx.GlobalString(SwarmTomlConfigPathFlag.Name); filepath == "" { |
||||
utils.Fatalf("Config file flag provided with invalid file path") |
||||
} |
||||
f, err := os.Open(filepath) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
defer f.Close() |
||||
|
||||
//decode the TOML file into a Config struct
|
||||
//note that we are decoding into the existing defaultConfig;
|
||||
//if an entry is not present in the file, the default entry is kept
|
||||
err = tomlSettings.NewDecoder(f).Decode(&config) |
||||
// Add file name to errors that have a line number.
|
||||
if _, ok := err.(*toml.LineError); ok { |
||||
err = errors.New(filepath + ", " + err.Error()) |
||||
} |
||||
} |
||||
return config, err |
||||
} |
||||
|
||||
//override the current config with whatever is provided through the command line
|
||||
//most values are not allowed a zero value (empty string), if not otherwise noted
|
||||
func cmdLineOverride(currentConfig *bzzapi.Config, ctx *cli.Context) *bzzapi.Config { |
||||
|
||||
if keyid := ctx.GlobalString(SwarmAccountFlag.Name); keyid != "" { |
||||
currentConfig.BzzAccount = keyid |
||||
} |
||||
|
||||
if chbookaddr := ctx.GlobalString(ChequebookAddrFlag.Name); chbookaddr != "" { |
||||
currentConfig.Contract = common.HexToAddress(chbookaddr) |
||||
} |
||||
|
||||
if networkid := ctx.GlobalString(SwarmNetworkIdFlag.Name); networkid != "" { |
||||
if id, _ := strconv.Atoi(networkid); id != 0 { |
||||
currentConfig.NetworkId = uint64(id) |
||||
} |
||||
} |
||||
|
||||
if ctx.GlobalIsSet(utils.DataDirFlag.Name) { |
||||
if datadir := ctx.GlobalString(utils.DataDirFlag.Name); datadir != "" { |
||||
currentConfig.Path = datadir |
||||
} |
||||
} |
||||
|
||||
bzzport := ctx.GlobalString(SwarmPortFlag.Name) |
||||
if len(bzzport) > 0 { |
||||
currentConfig.Port = bzzport |
||||
} |
||||
|
||||
if bzzaddr := ctx.GlobalString(SwarmListenAddrFlag.Name); bzzaddr != "" { |
||||
currentConfig.ListenAddr = bzzaddr |
||||
} |
||||
|
||||
if ctx.GlobalIsSet(SwarmSwapEnabledFlag.Name) { |
||||
currentConfig.SwapEnabled = true |
||||
} |
||||
|
||||
if ctx.GlobalIsSet(SwarmSyncEnabledFlag.Name) { |
||||
currentConfig.SyncEnabled = true |
||||
} |
||||
|
||||
currentConfig.SwapApi = ctx.GlobalString(SwarmSwapAPIFlag.Name) |
||||
if currentConfig.SwapEnabled && currentConfig.SwapApi == "" { |
||||
utils.Fatalf(SWARM_ERR_SWAP_SET_NO_API) |
||||
} |
||||
|
||||
//EnsApi can be set to "", so can't check for empty string, as it is allowed!
|
||||
if ctx.GlobalIsSet(EnsAPIFlag.Name) { |
||||
currentConfig.EnsApi = ctx.GlobalString(EnsAPIFlag.Name) |
||||
} |
||||
|
||||
if ensaddr := ctx.GlobalString(EnsAddrFlag.Name); ensaddr != "" { |
||||
currentConfig.EnsRoot = common.HexToAddress(ensaddr) |
||||
} |
||||
|
||||
if cors := ctx.GlobalString(CorsStringFlag.Name); cors != "" { |
||||
currentConfig.Cors = cors |
||||
} |
||||
|
||||
if ctx.GlobalIsSet(utils.BootnodesFlag.Name) { |
||||
currentConfig.BootNodes = ctx.GlobalString(utils.BootnodesFlag.Name) |
||||
} |
||||
|
||||
return currentConfig |
||||
|
||||
} |
||||
|
||||
//override the current config with whatver is provided in environment variables
|
||||
//most values are not allowed a zero value (empty string), if not otherwise noted
|
||||
func envVarsOverride(currentConfig *bzzapi.Config) (config *bzzapi.Config) { |
||||
|
||||
if keyid := os.Getenv(SWARM_ENV_ACCOUNT); keyid != "" { |
||||
currentConfig.BzzAccount = keyid |
||||
} |
||||
|
||||
if chbookaddr := os.Getenv(SWARM_ENV_CHEQUEBOOK_ADDR); chbookaddr != "" { |
||||
currentConfig.Contract = common.HexToAddress(chbookaddr) |
||||
} |
||||
|
||||
if networkid := os.Getenv(SWARM_ENV_NETWORK_ID); networkid != "" { |
||||
if id, _ := strconv.Atoi(networkid); id != 0 { |
||||
currentConfig.NetworkId = uint64(id) |
||||
} |
||||
} |
||||
|
||||
if datadir := os.Getenv(GETH_ENV_DATADIR); datadir != "" { |
||||
currentConfig.Path = datadir |
||||
} |
||||
|
||||
bzzport := os.Getenv(SWARM_ENV_PORT) |
||||
if len(bzzport) > 0 { |
||||
currentConfig.Port = bzzport |
||||
} |
||||
|
||||
if bzzaddr := os.Getenv(SWARM_ENV_LISTEN_ADDR); bzzaddr != "" { |
||||
currentConfig.ListenAddr = bzzaddr |
||||
} |
||||
|
||||
if swapenable := os.Getenv(SWARM_ENV_SWAP_ENABLE); swapenable != "" { |
||||
if swap, err := strconv.ParseBool(swapenable); err != nil { |
||||
currentConfig.SwapEnabled = swap |
||||
} |
||||
} |
||||
|
||||
if syncenable := os.Getenv(SWARM_ENV_SYNC_ENABLE); syncenable != "" { |
||||
if sync, err := strconv.ParseBool(syncenable); err != nil { |
||||
currentConfig.SyncEnabled = sync |
||||
} |
||||
} |
||||
|
||||
if swapapi := os.Getenv(SWARM_ENV_SWAP_API); swapapi != "" { |
||||
currentConfig.SwapApi = swapapi |
||||
} |
||||
|
||||
if currentConfig.SwapEnabled && currentConfig.SwapApi == "" { |
||||
utils.Fatalf(SWARM_ERR_SWAP_SET_NO_API) |
||||
} |
||||
|
||||
//EnsApi can be set to "", so can't check for empty string, as it is allowed
|
||||
if ensapi, exists := os.LookupEnv(SWARM_ENV_ENS_API); exists == true { |
||||
currentConfig.EnsApi = ensapi |
||||
} |
||||
|
||||
if ensaddr := os.Getenv(SWARM_ENV_ENS_ADDR); ensaddr != "" { |
||||
currentConfig.EnsRoot = common.HexToAddress(ensaddr) |
||||
} |
||||
|
||||
if cors := os.Getenv(SWARM_ENV_CORS); cors != "" { |
||||
currentConfig.Cors = cors |
||||
} |
||||
|
||||
if bootnodes := os.Getenv(SWARM_ENV_BOOTNODES); bootnodes != "" { |
||||
currentConfig.BootNodes = bootnodes |
||||
} |
||||
|
||||
return currentConfig |
||||
} |
||||
|
||||
// dumpConfig is the dumpconfig command.
|
||||
// writes a default config to STDOUT
|
||||
func dumpConfig(ctx *cli.Context) error { |
||||
cfg, err := buildConfig(ctx) |
||||
if err != nil { |
||||
utils.Fatalf(fmt.Sprintf("Uh oh - dumpconfig triggered an error %v", err)) |
||||
} |
||||
comment := "" |
||||
out, err := tomlSettings.Marshal(&cfg) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
io.WriteString(os.Stdout, comment) |
||||
os.Stdout.Write(out) |
||||
return nil |
||||
} |
||||
|
||||
//deprecated flags checked here
|
||||
func checkDeprecated(ctx *cli.Context) { |
||||
// exit if the deprecated --ethapi flag is set
|
||||
if ctx.GlobalString(DeprecatedEthAPIFlag.Name) != "" { |
||||
utils.Fatalf("--ethapi is no longer a valid command line flag, please use --ens-api and/or --swap-api.") |
||||
} |
||||
} |
||||
|
||||
//print a Config as string
|
||||
func printConfig(config *bzzapi.Config) string { |
||||
out, err := tomlSettings.Marshal(&config) |
||||
if err != nil { |
||||
return (fmt.Sprintf("Something is not right with the configuration: %v", err)) |
||||
} |
||||
return string(out) |
||||
} |
@ -0,0 +1,459 @@ |
||||
// Copyright 2017 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"io" |
||||
"io/ioutil" |
||||
"os" |
||||
"os/exec" |
||||
"testing" |
||||
"time" |
||||
|
||||
"github.com/ethereum/go-ethereum/rpc" |
||||
"github.com/ethereum/go-ethereum/swarm" |
||||
"github.com/ethereum/go-ethereum/swarm/api" |
||||
|
||||
"github.com/docker/docker/pkg/reexec" |
||||
) |
||||
|
||||
func TestDumpConfig(t *testing.T) { |
||||
swarm := runSwarm(t, "dumpconfig") |
||||
defaultConf := api.NewDefaultConfig() |
||||
out, err := tomlSettings.Marshal(&defaultConf) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
swarm.Expect(string(out)) |
||||
swarm.ExpectExit() |
||||
} |
||||
|
||||
func TestFailsSwapEnabledNoSwapApi(t *testing.T) { |
||||
flags := []string{ |
||||
fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42", |
||||
fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545", |
||||
fmt.Sprintf("--%s", SwarmSwapEnabledFlag.Name), |
||||
} |
||||
|
||||
swarm := runSwarm(t, flags...) |
||||
swarm.Expect("Fatal: " + SWARM_ERR_SWAP_SET_NO_API + "\n") |
||||
swarm.ExpectExit() |
||||
} |
||||
|
||||
func TestFailsNoBzzAccount(t *testing.T) { |
||||
flags := []string{ |
||||
fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42", |
||||
fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545", |
||||
} |
||||
|
||||
swarm := runSwarm(t, flags...) |
||||
swarm.Expect("Fatal: " + SWARM_ERR_NO_BZZACCOUNT + "\n") |
||||
swarm.ExpectExit() |
||||
} |
||||
|
||||
func TestCmdLineOverrides(t *testing.T) { |
||||
dir, err := ioutil.TempDir("", "bzztest") |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
defer os.RemoveAll(dir) |
||||
|
||||
conf, account := getTestAccount(t, dir) |
||||
node := &testNode{Dir: dir} |
||||
|
||||
// assign ports
|
||||
httpPort, err := assignTCPPort() |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
flags := []string{ |
||||
fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42", |
||||
fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort, |
||||
fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name), |
||||
fmt.Sprintf("--%s", CorsStringFlag.Name), "*", |
||||
fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(), |
||||
fmt.Sprintf("--%s", EnsAPIFlag.Name), "", |
||||
"--datadir", dir, |
||||
"--ipcpath", conf.IPCPath, |
||||
} |
||||
node.Cmd = runSwarm(t, flags...) |
||||
node.Cmd.InputLine(testPassphrase) |
||||
defer func() { |
||||
if t.Failed() { |
||||
node.Shutdown() |
||||
} |
||||
}() |
||||
// wait for the node to start
|
||||
for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) { |
||||
node.Client, err = rpc.Dial(conf.IPCEndpoint()) |
||||
if err == nil { |
||||
break |
||||
} |
||||
} |
||||
if node.Client == nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
// load info
|
||||
var info swarm.Info |
||||
if err := node.Client.Call(&info, "bzz_info"); err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
if info.Port != httpPort { |
||||
t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port) |
||||
} |
||||
|
||||
if info.NetworkId != 42 { |
||||
t.Fatalf("Expected network ID to be %d, got %d", 42, info.NetworkId) |
||||
} |
||||
|
||||
if info.SyncEnabled != true { |
||||
t.Fatal("Expected Sync to be enabled, but is false") |
||||
} |
||||
|
||||
if info.Cors != "*" { |
||||
t.Fatalf("Expected Cors flag to be set to %s, got %s", "*", info.Cors) |
||||
} |
||||
|
||||
node.Shutdown() |
||||
} |
||||
|
||||
func TestFileOverrides(t *testing.T) { |
||||
|
||||
// assign ports
|
||||
httpPort, err := assignTCPPort() |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
//create a config file
|
||||
//first, create a default conf
|
||||
defaultConf := api.NewDefaultConfig() |
||||
//change some values in order to test if they have been loaded
|
||||
defaultConf.SyncEnabled = true |
||||
defaultConf.NetworkId = 54 |
||||
defaultConf.Port = httpPort |
||||
defaultConf.StoreParams.DbCapacity = 9000000 |
||||
defaultConf.ChunkerParams.Branches = 64 |
||||
defaultConf.HiveParams.CallInterval = 6000000000 |
||||
defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second |
||||
defaultConf.SyncParams.KeyBufferSize = 512 |
||||
//create a TOML string
|
||||
out, err := tomlSettings.Marshal(&defaultConf) |
||||
if err != nil { |
||||
t.Fatalf("Error creating TOML file in TestFileOverride: %v", err) |
||||
} |
||||
//create file
|
||||
f, err := ioutil.TempFile("", "testconfig.toml") |
||||
if err != nil { |
||||
t.Fatalf("Error writing TOML file in TestFileOverride: %v", err) |
||||
} |
||||
//write file
|
||||
_, err = f.WriteString(string(out)) |
||||
if err != nil { |
||||
t.Fatalf("Error writing TOML file in TestFileOverride: %v", err) |
||||
} |
||||
f.Sync() |
||||
|
||||
dir, err := ioutil.TempDir("", "bzztest") |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
defer os.RemoveAll(dir) |
||||
conf, account := getTestAccount(t, dir) |
||||
node := &testNode{Dir: dir} |
||||
|
||||
flags := []string{ |
||||
fmt.Sprintf("--%s", SwarmTomlConfigPathFlag.Name), f.Name(), |
||||
fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(), |
||||
"--ens-api", "", |
||||
"--ipcpath", conf.IPCPath, |
||||
"--datadir", dir, |
||||
} |
||||
node.Cmd = runSwarm(t, flags...) |
||||
node.Cmd.InputLine(testPassphrase) |
||||
defer func() { |
||||
if t.Failed() { |
||||
node.Shutdown() |
||||
} |
||||
}() |
||||
// wait for the node to start
|
||||
for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) { |
||||
node.Client, err = rpc.Dial(conf.IPCEndpoint()) |
||||
if err == nil { |
||||
break |
||||
} |
||||
} |
||||
if node.Client == nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
// load info
|
||||
var info swarm.Info |
||||
if err := node.Client.Call(&info, "bzz_info"); err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
if info.Port != httpPort { |
||||
t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port) |
||||
} |
||||
|
||||
if info.NetworkId != 54 { |
||||
t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId) |
||||
} |
||||
|
||||
if info.SyncEnabled != true { |
||||
t.Fatal("Expected Sync to be enabled, but is false") |
||||
} |
||||
|
||||
if info.StoreParams.DbCapacity != 9000000 { |
||||
t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId) |
||||
} |
||||
|
||||
if info.ChunkerParams.Branches != 64 { |
||||
t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches) |
||||
} |
||||
|
||||
if info.HiveParams.CallInterval != 6000000000 { |
||||
t.Fatalf("Expected HiveParams CallInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.CallInterval)) |
||||
} |
||||
|
||||
if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second { |
||||
t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval) |
||||
} |
||||
|
||||
if info.SyncParams.KeyBufferSize != 512 { |
||||
t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize) |
||||
} |
||||
|
||||
node.Shutdown() |
||||
} |
||||
|
||||
func TestEnvVars(t *testing.T) { |
||||
// assign ports
|
||||
httpPort, err := assignTCPPort() |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
envVars := os.Environ() |
||||
envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmPortFlag.EnvVar, httpPort)) |
||||
envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmNetworkIdFlag.EnvVar, "999")) |
||||
envVars = append(envVars, fmt.Sprintf("%s=%s", CorsStringFlag.EnvVar, "*")) |
||||
envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmSyncEnabledFlag.EnvVar, "true")) |
||||
|
||||
dir, err := ioutil.TempDir("", "bzztest") |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
defer os.RemoveAll(dir) |
||||
conf, account := getTestAccount(t, dir) |
||||
node := &testNode{Dir: dir} |
||||
flags := []string{ |
||||
fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(), |
||||
"--ens-api", "", |
||||
"--datadir", dir, |
||||
"--ipcpath", conf.IPCPath, |
||||
} |
||||
|
||||
//node.Cmd = runSwarm(t,flags...)
|
||||
//node.Cmd.cmd.Env = envVars
|
||||
//the above assignment does not work, so we need a custom Cmd here in order to pass envVars:
|
||||
cmd := &exec.Cmd{ |
||||
Path: reexec.Self(), |
||||
Args: append([]string{"swarm-test"}, flags...), |
||||
Stderr: os.Stderr, |
||||
Stdout: os.Stdout, |
||||
} |
||||
cmd.Env = envVars |
||||
//stdout, err := cmd.StdoutPipe()
|
||||
//if err != nil {
|
||||
// t.Fatal(err)
|
||||
//}
|
||||
//stdout = bufio.NewReader(stdout)
|
||||
var stdin io.WriteCloser |
||||
if stdin, err = cmd.StdinPipe(); err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
if err := cmd.Start(); err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
//cmd.InputLine(testPassphrase)
|
||||
io.WriteString(stdin, testPassphrase+"\n") |
||||
defer func() { |
||||
if t.Failed() { |
||||
node.Shutdown() |
||||
cmd.Process.Kill() |
||||
} |
||||
}() |
||||
// wait for the node to start
|
||||
for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) { |
||||
node.Client, err = rpc.Dial(conf.IPCEndpoint()) |
||||
if err == nil { |
||||
break |
||||
} |
||||
} |
||||
|
||||
if node.Client == nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
// load info
|
||||
var info swarm.Info |
||||
if err := node.Client.Call(&info, "bzz_info"); err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
if info.Port != httpPort { |
||||
t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port) |
||||
} |
||||
|
||||
if info.NetworkId != 999 { |
||||
t.Fatalf("Expected network ID to be %d, got %d", 999, info.NetworkId) |
||||
} |
||||
|
||||
if info.Cors != "*" { |
||||
t.Fatalf("Expected Cors flag to be set to %s, got %s", "*", info.Cors) |
||||
} |
||||
|
||||
if info.SyncEnabled != true { |
||||
t.Fatal("Expected Sync to be enabled, but is false") |
||||
} |
||||
|
||||
node.Shutdown() |
||||
cmd.Process.Kill() |
||||
} |
||||
|
||||
func TestCmdLineOverridesFile(t *testing.T) { |
||||
|
||||
// assign ports
|
||||
httpPort, err := assignTCPPort() |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
//create a config file
|
||||
//first, create a default conf
|
||||
defaultConf := api.NewDefaultConfig() |
||||
//change some values in order to test if they have been loaded
|
||||
defaultConf.SyncEnabled = false |
||||
defaultConf.NetworkId = 54 |
||||
defaultConf.Port = "8588" |
||||
defaultConf.StoreParams.DbCapacity = 9000000 |
||||
defaultConf.ChunkerParams.Branches = 64 |
||||
defaultConf.HiveParams.CallInterval = 6000000000 |
||||
defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second |
||||
defaultConf.SyncParams.KeyBufferSize = 512 |
||||
//create a TOML file
|
||||
out, err := tomlSettings.Marshal(&defaultConf) |
||||
if err != nil { |
||||
t.Fatalf("Error creating TOML file in TestFileOverride: %v", err) |
||||
} |
||||
//write file
|
||||
f, err := ioutil.TempFile("", "testconfig.toml") |
||||
if err != nil { |
||||
t.Fatalf("Error writing TOML file in TestFileOverride: %v", err) |
||||
} |
||||
//write file
|
||||
_, err = f.WriteString(string(out)) |
||||
if err != nil { |
||||
t.Fatalf("Error writing TOML file in TestFileOverride: %v", err) |
||||
} |
||||
f.Sync() |
||||
|
||||
dir, err := ioutil.TempDir("", "bzztest") |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
defer os.RemoveAll(dir) |
||||
conf, account := getTestAccount(t, dir) |
||||
node := &testNode{Dir: dir} |
||||
|
||||
expectNetworkId := uint64(77) |
||||
|
||||
flags := []string{ |
||||
fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "77", |
||||
fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort, |
||||
fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name), |
||||
fmt.Sprintf("--%s", SwarmTomlConfigPathFlag.Name), f.Name(), |
||||
fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(), |
||||
"--ens-api", "", |
||||
"--datadir", dir, |
||||
"--ipcpath", conf.IPCPath, |
||||
} |
||||
node.Cmd = runSwarm(t, flags...) |
||||
node.Cmd.InputLine(testPassphrase) |
||||
defer func() { |
||||
if t.Failed() { |
||||
node.Shutdown() |
||||
} |
||||
}() |
||||
// wait for the node to start
|
||||
for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) { |
||||
node.Client, err = rpc.Dial(conf.IPCEndpoint()) |
||||
if err == nil { |
||||
break |
||||
} |
||||
} |
||||
if node.Client == nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
// load info
|
||||
var info swarm.Info |
||||
if err := node.Client.Call(&info, "bzz_info"); err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
|
||||
if info.Port != httpPort { |
||||
t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port) |
||||
} |
||||
|
||||
if info.NetworkId != expectNetworkId { |
||||
t.Fatalf("Expected network ID to be %d, got %d", expectNetworkId, info.NetworkId) |
||||
} |
||||
|
||||
if info.SyncEnabled != true { |
||||
t.Fatal("Expected Sync to be enabled, but is false") |
||||
} |
||||
|
||||
if info.StoreParams.DbCapacity != 9000000 { |
||||
t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId) |
||||
} |
||||
|
||||
if info.ChunkerParams.Branches != 64 { |
||||
t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches) |
||||
} |
||||
|
||||
if info.HiveParams.CallInterval != 6000000000 { |
||||
t.Fatalf("Expected HiveParams CallInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.CallInterval)) |
||||
} |
||||
|
||||
if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second { |
||||
t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval) |
||||
} |
||||
|
||||
if info.SyncParams.KeyBufferSize != 512 { |
||||
t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize) |
||||
} |
||||
|
||||
node.Shutdown() |
||||
} |
Loading…
Reference in new issue