github.com/clem109/go-ethereum@v1.8.3-0.20180316121352-fe6cf00f480a/cmd/swarm/config_test.go (about)

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