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