github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/swarm_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:45</date>
    10  //</624450121693663232>
    11  
    12  
    13  package swarm
    14  
    15  import (
    16  	"context"
    17  	"encoding/hex"
    18  	"io/ioutil"
    19  	"math/rand"
    20  	"os"
    21  	"path"
    22  	"runtime"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/ethereum/go-ethereum/common"
    28  	"github.com/ethereum/go-ethereum/crypto"
    29  	"github.com/ethereum/go-ethereum/rpc"
    30  	"github.com/ethereum/go-ethereum/swarm/api"
    31  )
    32  
    33  //TestNewsWarm验证repsect中的Swarm字段是否符合所提供的配置。
    34  func TestNewSwarm(t *testing.T) {
    35  	dir, err := ioutil.TempDir("", "swarm")
    36  	if err != nil {
    37  		t.Fatal(err)
    38  	}
    39  	defer os.RemoveAll(dir)
    40  
    41  //用于测试拨号的简单RPC终结点
    42  	ipcEndpoint := path.Join(dir, "TestSwarm.ipc")
    43  
    44  //Windows名称管道不在文件系统上,而是在NPF上
    45  	if runtime.GOOS == "windows" {
    46  		b := make([]byte, 8)
    47  		rand.Read(b)
    48  		ipcEndpoint = `\\.\pipe\TestSwarm-` + hex.EncodeToString(b)
    49  	}
    50  
    51  	_, server, err := rpc.StartIPCEndpoint(ipcEndpoint, nil)
    52  	if err != nil {
    53  		t.Error(err)
    54  	}
    55  	defer server.Stop()
    56  
    57  	for _, tc := range []struct {
    58  		name      string
    59  		configure func(*api.Config)
    60  		check     func(*testing.T, *Swarm, *api.Config)
    61  	}{
    62  		{
    63  			name:      "defaults",
    64  			configure: nil,
    65  			check: func(t *testing.T, s *Swarm, config *api.Config) {
    66  				if s.config != config {
    67  					t.Error("config is not the same object")
    68  				}
    69  				if s.backend != nil {
    70  					t.Error("backend is not nil")
    71  				}
    72  				if s.privateKey == nil {
    73  					t.Error("private key is not set")
    74  				}
    75  				if !s.config.HiveParams.Discovery {
    76  					t.Error("config.HiveParams.Discovery is false, must be true regardless the configuration")
    77  				}
    78  				if s.dns != nil {
    79  					t.Error("dns initialized, but it should not be")
    80  				}
    81  				if s.netStore == nil {
    82  					t.Error("netStore not initialized")
    83  				}
    84  				if s.streamer == nil {
    85  					t.Error("streamer not initialized")
    86  				}
    87  				if s.fileStore == nil {
    88  					t.Error("fileStore not initialized")
    89  				}
    90  				if s.bzz == nil {
    91  					t.Error("bzz not initialized")
    92  				}
    93  				if s.ps == nil {
    94  					t.Error("pss not initialized")
    95  				}
    96  				if s.api == nil {
    97  					t.Error("api not initialized")
    98  				}
    99  				if s.sfs == nil {
   100  					t.Error("swarm filesystem not initialized")
   101  				}
   102  			},
   103  		},
   104  		{
   105  			name: "with swap",
   106  			configure: func(config *api.Config) {
   107  				config.SwapAPI = ipcEndpoint
   108  				config.SwapEnabled = true
   109  			},
   110  			check: func(t *testing.T, s *Swarm, _ *api.Config) {
   111  				if s.backend == nil {
   112  					t.Error("backend is nil")
   113  				}
   114  			},
   115  		},
   116  		{
   117  			name: "with swap disabled",
   118  			configure: func(config *api.Config) {
   119  				config.SwapAPI = ipcEndpoint
   120  				config.SwapEnabled = false
   121  			},
   122  			check: func(t *testing.T, s *Swarm, _ *api.Config) {
   123  				if s.backend != nil {
   124  					t.Error("backend is not nil")
   125  				}
   126  			},
   127  		},
   128  		{
   129  			name: "with swap enabled and api endpoint blank",
   130  			configure: func(config *api.Config) {
   131  				config.SwapAPI = ""
   132  				config.SwapEnabled = true
   133  			},
   134  			check: func(t *testing.T, s *Swarm, _ *api.Config) {
   135  				if s.backend != nil {
   136  					t.Error("backend is not nil")
   137  				}
   138  			},
   139  		},
   140  		{
   141  			name: "ens",
   142  			configure: func(config *api.Config) {
   143  				config.EnsAPIs = []string{
   144  "http://127.0.0.1:8888“,
   145  				}
   146  			},
   147  			check: func(t *testing.T, s *Swarm, _ *api.Config) {
   148  				if s.dns == nil {
   149  					t.Error("dns is not initialized")
   150  				}
   151  			},
   152  		},
   153  	} {
   154  		t.Run(tc.name, func(t *testing.T) {
   155  			config := api.NewConfig()
   156  
   157  			dir, err := ioutil.TempDir("", "swarm")
   158  			if err != nil {
   159  				t.Fatal(err)
   160  			}
   161  			defer os.RemoveAll(dir)
   162  
   163  			config.Path = dir
   164  
   165  			privkey, err := crypto.GenerateKey()
   166  			if err != nil {
   167  				t.Fatal(err)
   168  			}
   169  
   170  			config.Init(privkey)
   171  
   172  			if tc.configure != nil {
   173  				tc.configure(config)
   174  			}
   175  
   176  			s, err := NewSwarm(config, nil)
   177  			if err != nil {
   178  				t.Fatal(err)
   179  			}
   180  
   181  			if tc.check != nil {
   182  				tc.check(t, s, config)
   183  			}
   184  		})
   185  	}
   186  }
   187  
   188  func TestParseEnsAPIAddress(t *testing.T) {
   189  	for _, x := range []struct {
   190  		description string
   191  		value       string
   192  		tld         string
   193  		endpoint    string
   194  		addr        common.Address
   195  	}{
   196  		{
   197  			description: "IPC endpoint",
   198  			value:       "/data/testnet/geth.ipc",
   199  			endpoint:    "/data/testnet/geth.ipc",
   200  		},
   201  		{
   202  			description: "HTTP endpoint",
   203  value:       "http://127.0.0.1:1234“,
   204  endpoint:    "http://127.0.0.1:1234“,
   205  		},
   206  		{
   207  			description: "WS endpoint",
   208  value:       "ws://127.0.0.1:1234“,
   209  endpoint:    "ws://127.0.0.1:1234“,
   210  		},
   211  		{
   212  			description: "IPC Endpoint and TLD",
   213  			value:       "test:/data/testnet/geth.ipc",
   214  			endpoint:    "/data/testnet/geth.ipc",
   215  			tld:         "test",
   216  		},
   217  		{
   218  			description: "HTTP endpoint and TLD",
   219  value:       "test:http://127.0.0.1:1234“,
   220  endpoint:    "http://127.0.0.1:1234“,
   221  			tld:         "test",
   222  		},
   223  		{
   224  			description: "WS endpoint and TLD",
   225  value:       "test:ws://127.0.0.1:1234“,
   226  endpoint:    "ws://127.0.0.1:1234“,
   227  			tld:         "test",
   228  		},
   229  		{
   230  			description: "IPC Endpoint and contract address",
   231  			value:       "314159265dD8dbb310642f98f50C066173C1259b@/data/testnet/geth.ipc",
   232  			endpoint:    "/data/testnet/geth.ipc",
   233  			addr:        common.HexToAddress("314159265dD8dbb310642f98f50C066173C1259b"),
   234  		},
   235  		{
   236  			description: "HTTP endpoint and contract address",
   237  value:       "314159265dD8dbb310642f98f50C066173C1259b@http://127.0.0.1:1234“,
   238  endpoint:    "http://127.0.0.1:1234“,
   239  			addr:        common.HexToAddress("314159265dD8dbb310642f98f50C066173C1259b"),
   240  		},
   241  		{
   242  			description: "WS endpoint and contract address",
   243  value:       "314159265dD8dbb310642f98f50C066173C1259b@ws://127.0.0.1:1234“,
   244  endpoint:    "ws://127.0.0.1:1234“,
   245  			addr:        common.HexToAddress("314159265dD8dbb310642f98f50C066173C1259b"),
   246  		},
   247  		{
   248  			description: "IPC Endpoint, TLD and contract address",
   249  			value:       "test:314159265dD8dbb310642f98f50C066173C1259b@/data/testnet/geth.ipc",
   250  			endpoint:    "/data/testnet/geth.ipc",
   251  			addr:        common.HexToAddress("314159265dD8dbb310642f98f50C066173C1259b"),
   252  			tld:         "test",
   253  		},
   254  		{
   255  			description: "HTTP endpoint, TLD and contract address",
   256  value:       "eth:314159265dD8dbb310642f98f50C066173C1259b@http://127.0.0.1:1234“,
   257  endpoint:    "http://127.0.0.1:1234“,
   258  			addr:        common.HexToAddress("314159265dD8dbb310642f98f50C066173C1259b"),
   259  			tld:         "eth",
   260  		},
   261  		{
   262  			description: "WS endpoint, TLD and contract address",
   263  value:       "eth:314159265dD8dbb310642f98f50C066173C1259b@ws://127.0.0.1:1234“,
   264  endpoint:    "ws://127.0.0.1:1234“,
   265  			addr:        common.HexToAddress("314159265dD8dbb310642f98f50C066173C1259b"),
   266  			tld:         "eth",
   267  		},
   268  	} {
   269  		t.Run(x.description, func(t *testing.T) {
   270  			tld, endpoint, addr := parseEnsAPIAddress(x.value)
   271  			if endpoint != x.endpoint {
   272  				t.Errorf("expected Endpoint %q, got %q", x.endpoint, endpoint)
   273  			}
   274  			if addr != x.addr {
   275  				t.Errorf("expected ContractAddress %q, got %q", x.addr.String(), addr.String())
   276  			}
   277  			if tld != x.tld {
   278  				t.Errorf("expected TLD %q, got %q", x.tld, tld)
   279  			}
   280  		})
   281  	}
   282  }
   283  
   284  //testlocalstoreandretrieve在上载不同大小文件的情况下运行多个测试
   285  //使用api存储到单个swarm实例,并根据返回的内容进行检查
   286  //通过API检索函数。
   287  //
   288  //此测试旨在验证chunker store和join函数的功能。
   289  //以及它们在群中的相互作用,而不将结果与
   290  //另一个chunker实现,在swarm/storage测试中完成。
   291  func TestLocalStoreAndRetrieve(t *testing.T) {
   292  	config := api.NewConfig()
   293  
   294  	dir, err := ioutil.TempDir("", "node")
   295  	if err != nil {
   296  		t.Fatal(err)
   297  	}
   298  	defer os.RemoveAll(dir)
   299  
   300  	config.Path = dir
   301  
   302  	privkey, err := crypto.GenerateKey()
   303  	if err != nil {
   304  		t.Fatal(err)
   305  	}
   306  
   307  	config.Init(privkey)
   308  
   309  	swarm, err := NewSwarm(config, nil)
   310  	if err != nil {
   311  		t.Fatal(err)
   312  	}
   313  
   314  //默认情况下,只测试单独的块情况
   315  	sizes := []int{1, 60, 4097, 524288 + 1, 7*524288 + 1}
   316  
   317  	if *longrunning {
   318  //如果设置了-longruning标志,则测试更广泛的案例集
   319  		sizes = append(sizes, 83, 179, 253, 1024, 4095, 4096, 8191, 8192, 8193, 12287, 12288, 12289, 123456, 2345678, 67298391, 524288, 524288+4096, 524288+4097, 7*524288, 7*524288+4096, 7*524288+4097, 128*524288+1, 128*524288, 128*524288+4096, 128*524288+4097, 816778334)
   320  	}
   321  	for _, n := range sizes {
   322  		testLocalStoreAndRetrieve(t, swarm, n, true)
   323  		testLocalStoreAndRetrieve(t, swarm, n, false)
   324  	}
   325  }
   326  
   327  //testlocalstoreandretrieve正在使用单个swarm实例上传
   328  //一个长度为n的文件,带有可选的随机数据,使用api存储函数,
   329  //并检查同一实例上API检索函数的输出。
   330  //这是针对问题的回归测试
   331  //网址:https://github.com/ethersphere/go-ethereum/issues/639
   332  //如果金字塔chunker没有正确拆分长度为
   333  //是否存在块和树参数的边缘情况,取决于是否存在
   334  //是一个只有一个数据块的树块以及压缩功能
   335  //改变了树。
   336  func testLocalStoreAndRetrieve(t *testing.T, swarm *Swarm, n int, randomData bool) {
   337  	slice := make([]byte, n)
   338  	if randomData {
   339  		rand.Seed(time.Now().UnixNano())
   340  		rand.Read(slice)
   341  	}
   342  	dataPut := string(slice)
   343  
   344  	ctx := context.TODO()
   345  	k, wait, err := swarm.api.Store(ctx, strings.NewReader(dataPut), int64(len(dataPut)), false)
   346  	if err != nil {
   347  		t.Fatal(err)
   348  	}
   349  	if wait != nil {
   350  		err = wait(ctx)
   351  		if err != nil {
   352  			t.Fatal(err)
   353  		}
   354  	}
   355  
   356  	r, _ := swarm.api.Retrieve(context.TODO(), k)
   357  
   358  	d, err := ioutil.ReadAll(r)
   359  	if err != nil {
   360  		t.Fatal(err)
   361  	}
   362  	dataGet := string(d)
   363  
   364  	if len(dataPut) != len(dataGet) {
   365  		t.Fatalf("data not matched: length expected %v, got %v", len(dataPut), len(dataGet))
   366  	} else {
   367  		if dataPut != dataGet {
   368  			t.Fatal("data not matched")
   369  		}
   370  	}
   371  }
   372