github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/api/api_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2016 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package api
    26  
    27  import (
    28  	"context"
    29  	"errors"
    30  	"flag"
    31  	"fmt"
    32  	"io"
    33  	"io/ioutil"
    34  	"math/big"
    35  	"os"
    36  	"testing"
    37  
    38  	"github.com/ethereum/go-ethereum/common"
    39  	"github.com/ethereum/go-ethereum/core/types"
    40  	"github.com/ethereum/go-ethereum/log"
    41  	"github.com/ethereum/go-ethereum/swarm/sctx"
    42  	"github.com/ethereum/go-ethereum/swarm/storage"
    43  )
    44  
    45  func init() {
    46  	loglevel := flag.Int("loglevel", 2, "loglevel")
    47  	flag.Parse()
    48  	log.Root().SetHandler(log.CallerFileHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true)))))
    49  }
    50  
    51  func testAPI(t *testing.T, f func(*API, bool)) {
    52  	datadir, err := ioutil.TempDir("", "bzz-test")
    53  	if err != nil {
    54  		t.Fatalf("unable to create temp dir: %v", err)
    55  	}
    56  	defer os.RemoveAll(datadir)
    57  	fileStore, err := storage.NewLocalFileStore(datadir, make([]byte, 32))
    58  	if err != nil {
    59  		return
    60  	}
    61  	api := NewAPI(fileStore, nil, nil, nil)
    62  	f(api, false)
    63  	f(api, true)
    64  }
    65  
    66  type testResponse struct {
    67  	reader storage.LazySectionReader
    68  	*Response
    69  }
    70  
    71  func checkResponse(t *testing.T, resp *testResponse, exp *Response) {
    72  
    73  	if resp.MimeType != exp.MimeType {
    74  		t.Errorf("incorrect mimeType. expected '%s', got '%s'", exp.MimeType, resp.MimeType)
    75  	}
    76  	if resp.Status != exp.Status {
    77  		t.Errorf("incorrect status. expected '%d', got '%d'", exp.Status, resp.Status)
    78  	}
    79  	if resp.Size != exp.Size {
    80  		t.Errorf("incorrect size. expected '%d', got '%d'", exp.Size, resp.Size)
    81  	}
    82  	if resp.reader != nil {
    83  		content := make([]byte, resp.Size)
    84  		read, _ := resp.reader.Read(content)
    85  		if int64(read) != exp.Size {
    86  			t.Errorf("incorrect content length. expected '%d...', got '%d...'", read, exp.Size)
    87  		}
    88  		resp.Content = string(content)
    89  	}
    90  	if resp.Content != exp.Content {
    91  //如果!bytes.equal(resp.content,exp.content)
    92  		t.Errorf("incorrect content. expected '%s...', got '%s...'", string(exp.Content), string(resp.Content))
    93  	}
    94  }
    95  
    96  //func expresponse(content[]byte,mimetype string,status int)*响应
    97  func expResponse(content string, mimeType string, status int) *Response {
    98  	log.Trace(fmt.Sprintf("expected content (%v): %v ", len(content), content))
    99  	return &Response{mimeType, status, int64(len(content)), content}
   100  }
   101  
   102  func testGet(t *testing.T, api *API, bzzhash, path string) *testResponse {
   103  	addr := storage.Address(common.Hex2Bytes(bzzhash))
   104  	reader, mimeType, status, _, err := api.Get(context.TODO(), NOOPDecrypt, addr, path)
   105  	if err != nil {
   106  		t.Fatalf("unexpected error: %v", err)
   107  	}
   108  	quitC := make(chan bool)
   109  	size, err := reader.Size(context.TODO(), quitC)
   110  	if err != nil {
   111  		t.Fatalf("unexpected error: %v", err)
   112  	}
   113  	log.Trace(fmt.Sprintf("reader size: %v ", size))
   114  	s := make([]byte, size)
   115  	_, err = reader.Read(s)
   116  	if err != io.EOF {
   117  		t.Fatalf("unexpected error: %v", err)
   118  	}
   119  	reader.Seek(0, 0)
   120  	return &testResponse{reader, &Response{mimeType, status, size, string(s)}}
   121  //返回&testreresponse reader,&response mimetype,status,reader.size(),nil
   122  }
   123  
   124  func TestApiPut(t *testing.T) {
   125  	testAPI(t, func(api *API, toEncrypt bool) {
   126  		content := "hello"
   127  		exp := expResponse(content, "text/plain", 0)
   128  		ctx := context.TODO()
   129  		addr, wait, err := api.Put(ctx, content, exp.MimeType, toEncrypt)
   130  		if err != nil {
   131  			t.Fatalf("unexpected error: %v", err)
   132  		}
   133  		err = wait(ctx)
   134  		if err != nil {
   135  			t.Fatalf("unexpected error: %v", err)
   136  		}
   137  		resp := testGet(t, api, addr.Hex(), "")
   138  		checkResponse(t, resp, exp)
   139  	})
   140  }
   141  
   142  //TestResolver实现Resolver接口,并返回给定的
   143  //如果设置了哈希,则返回“找不到名称”错误
   144  type testResolveValidator struct {
   145  	hash *common.Hash
   146  }
   147  
   148  func newTestResolveValidator(addr string) *testResolveValidator {
   149  	r := &testResolveValidator{}
   150  	if addr != "" {
   151  		hash := common.HexToHash(addr)
   152  		r.hash = &hash
   153  	}
   154  	return r
   155  }
   156  
   157  func (t *testResolveValidator) Resolve(addr string) (common.Hash, error) {
   158  	if t.hash == nil {
   159  		return common.Hash{}, fmt.Errorf("DNS name not found: %q", addr)
   160  	}
   161  	return *t.hash, nil
   162  }
   163  
   164  func (t *testResolveValidator) Owner(node [32]byte) (addr common.Address, err error) {
   165  	return
   166  }
   167  func (t *testResolveValidator) HeaderByNumber(context.Context, *big.Int) (header *types.Header, err error) {
   168  	return
   169  }
   170  
   171  //测试优先权测试解析可以包含内容哈希的URI
   172  //或姓
   173  func TestAPIResolve(t *testing.T) {
   174  	ensAddr := "swarm.eth"
   175  	hashAddr := "1111111111111111111111111111111111111111111111111111111111111111"
   176  	resolvedAddr := "2222222222222222222222222222222222222222222222222222222222222222"
   177  	doesResolve := newTestResolveValidator(resolvedAddr)
   178  	doesntResolve := newTestResolveValidator("")
   179  
   180  	type test struct {
   181  		desc      string
   182  		dns       Resolver
   183  		addr      string
   184  		immutable bool
   185  		result    string
   186  		expectErr error
   187  	}
   188  
   189  	tests := []*test{
   190  		{
   191  			desc:   "DNS not configured, hash address, returns hash address",
   192  			dns:    nil,
   193  			addr:   hashAddr,
   194  			result: hashAddr,
   195  		},
   196  		{
   197  			desc:      "DNS not configured, ENS address, returns error",
   198  			dns:       nil,
   199  			addr:      ensAddr,
   200  			expectErr: errors.New(`no DNS to resolve name: "swarm.eth"`),
   201  		},
   202  		{
   203  			desc:   "DNS configured, hash address, hash resolves, returns resolved address",
   204  			dns:    doesResolve,
   205  			addr:   hashAddr,
   206  			result: resolvedAddr,
   207  		},
   208  		{
   209  			desc:      "DNS configured, immutable hash address, hash resolves, returns hash address",
   210  			dns:       doesResolve,
   211  			addr:      hashAddr,
   212  			immutable: true,
   213  			result:    hashAddr,
   214  		},
   215  		{
   216  			desc:   "DNS configured, hash address, hash doesn't resolve, returns hash address",
   217  			dns:    doesntResolve,
   218  			addr:   hashAddr,
   219  			result: hashAddr,
   220  		},
   221  		{
   222  			desc:   "DNS configured, ENS address, name resolves, returns resolved address",
   223  			dns:    doesResolve,
   224  			addr:   ensAddr,
   225  			result: resolvedAddr,
   226  		},
   227  		{
   228  			desc:      "DNS configured, immutable ENS address, name resolves, returns error",
   229  			dns:       doesResolve,
   230  			addr:      ensAddr,
   231  			immutable: true,
   232  			expectErr: errors.New(`immutable address not a content hash: "swarm.eth"`),
   233  		},
   234  		{
   235  			desc:      "DNS configured, ENS address, name doesn't resolve, returns error",
   236  			dns:       doesntResolve,
   237  			addr:      ensAddr,
   238  			expectErr: errors.New(`DNS name not found: "swarm.eth"`),
   239  		},
   240  	}
   241  	for _, x := range tests {
   242  		t.Run(x.desc, func(t *testing.T) {
   243  			api := &API{dns: x.dns}
   244  			uri := &URI{Addr: x.addr, Scheme: "bzz"}
   245  			if x.immutable {
   246  				uri.Scheme = "bzz-immutable"
   247  			}
   248  			res, err := api.ResolveURI(context.TODO(), uri, "")
   249  			if err == nil {
   250  				if x.expectErr != nil {
   251  					t.Fatalf("expected error %q, got result %q", x.expectErr, res)
   252  				}
   253  				if res.String() != x.result {
   254  					t.Fatalf("expected result %q, got %q", x.result, res)
   255  				}
   256  			} else {
   257  				if x.expectErr == nil {
   258  					t.Fatalf("expected no error, got %q", err)
   259  				}
   260  				if err.Error() != x.expectErr.Error() {
   261  					t.Fatalf("expected error %q, got %q", x.expectErr, err)
   262  				}
   263  			}
   264  		})
   265  	}
   266  }
   267  
   268  func TestMultiResolver(t *testing.T) {
   269  	doesntResolve := newTestResolveValidator("")
   270  
   271  	ethAddr := "swarm.eth"
   272  	ethHash := "0x2222222222222222222222222222222222222222222222222222222222222222"
   273  	ethResolve := newTestResolveValidator(ethHash)
   274  
   275  	testAddr := "swarm.test"
   276  	testHash := "0x1111111111111111111111111111111111111111111111111111111111111111"
   277  	testResolve := newTestResolveValidator(testHash)
   278  
   279  	tests := []struct {
   280  		desc   string
   281  		r      Resolver
   282  		addr   string
   283  		result string
   284  		err    error
   285  	}{
   286  		{
   287  			desc: "No resolvers, returns error",
   288  			r:    NewMultiResolver(),
   289  			err:  NewNoResolverError(""),
   290  		},
   291  		{
   292  			desc:   "One default resolver, returns resolved address",
   293  			r:      NewMultiResolver(MultiResolverOptionWithResolver(ethResolve, "")),
   294  			addr:   ethAddr,
   295  			result: ethHash,
   296  		},
   297  		{
   298  			desc: "Two default resolvers, returns resolved address",
   299  			r: NewMultiResolver(
   300  				MultiResolverOptionWithResolver(ethResolve, ""),
   301  				MultiResolverOptionWithResolver(ethResolve, ""),
   302  			),
   303  			addr:   ethAddr,
   304  			result: ethHash,
   305  		},
   306  		{
   307  			desc: "Two default resolvers, first doesn't resolve, returns resolved address",
   308  			r: NewMultiResolver(
   309  				MultiResolverOptionWithResolver(doesntResolve, ""),
   310  				MultiResolverOptionWithResolver(ethResolve, ""),
   311  			),
   312  			addr:   ethAddr,
   313  			result: ethHash,
   314  		},
   315  		{
   316  			desc: "Default resolver doesn't resolve, tld resolver resolve, returns resolved address",
   317  			r: NewMultiResolver(
   318  				MultiResolverOptionWithResolver(doesntResolve, ""),
   319  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   320  			),
   321  			addr:   ethAddr,
   322  			result: ethHash,
   323  		},
   324  		{
   325  			desc: "Three TLD resolvers, third resolves, returns resolved address",
   326  			r: NewMultiResolver(
   327  				MultiResolverOptionWithResolver(doesntResolve, "eth"),
   328  				MultiResolverOptionWithResolver(doesntResolve, "eth"),
   329  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   330  			),
   331  			addr:   ethAddr,
   332  			result: ethHash,
   333  		},
   334  		{
   335  			desc: "One TLD resolver doesn't resolve, returns error",
   336  			r: NewMultiResolver(
   337  				MultiResolverOptionWithResolver(doesntResolve, ""),
   338  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   339  			),
   340  			addr:   ethAddr,
   341  			result: ethHash,
   342  		},
   343  		{
   344  			desc: "One defautl and one TLD resolver, all doesn't resolve, returns error",
   345  			r: NewMultiResolver(
   346  				MultiResolverOptionWithResolver(doesntResolve, ""),
   347  				MultiResolverOptionWithResolver(doesntResolve, "eth"),
   348  			),
   349  			addr:   ethAddr,
   350  			result: ethHash,
   351  			err:    errors.New(`DNS name not found: "swarm.eth"`),
   352  		},
   353  		{
   354  			desc: "Two TLD resolvers, both resolve, returns resolved address",
   355  			r: NewMultiResolver(
   356  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   357  				MultiResolverOptionWithResolver(testResolve, "test"),
   358  			),
   359  			addr:   testAddr,
   360  			result: testHash,
   361  		},
   362  		{
   363  			desc: "One TLD resolver, no default resolver, returns error for different TLD",
   364  			r: NewMultiResolver(
   365  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   366  			),
   367  			addr: testAddr,
   368  			err:  NewNoResolverError("test"),
   369  		},
   370  	}
   371  	for _, x := range tests {
   372  		t.Run(x.desc, func(t *testing.T) {
   373  			res, err := x.r.Resolve(x.addr)
   374  			if err == nil {
   375  				if x.err != nil {
   376  					t.Fatalf("expected error %q, got result %q", x.err, res.Hex())
   377  				}
   378  				if res.Hex() != x.result {
   379  					t.Fatalf("expected result %q, got %q", x.result, res.Hex())
   380  				}
   381  			} else {
   382  				if x.err == nil {
   383  					t.Fatalf("expected no error, got %q", err)
   384  				}
   385  				if err.Error() != x.err.Error() {
   386  					t.Fatalf("expected error %q, got %q", x.err, err)
   387  				}
   388  			}
   389  		})
   390  	}
   391  }
   392  
   393  func TestDecryptOriginForbidden(t *testing.T) {
   394  	ctx := context.TODO()
   395  	ctx = sctx.SetHost(ctx, "swarm-gateways.net")
   396  
   397  	me := &ManifestEntry{
   398  		Access: &AccessEntry{Type: AccessTypePass},
   399  	}
   400  
   401  	api := NewAPI(nil, nil, nil, nil)
   402  
   403  	f := api.Decryptor(ctx, "")
   404  	err := f(me)
   405  	if err != ErrDecryptDomainForbidden {
   406  		t.Fatalf("should fail with ErrDecryptDomainForbidden, got %v", err)
   407  	}
   408  }
   409  
   410  func TestDecryptOrigin(t *testing.T) {
   411  	for _, v := range []struct {
   412  		host        string
   413  		expectError error
   414  	}{
   415  		{
   416  			host:        "localhost",
   417  			expectError: ErrDecrypt,
   418  		},
   419  		{
   420  			host:        "127.0.0.1",
   421  			expectError: ErrDecrypt,
   422  		},
   423  		{
   424  			host:        "swarm-gateways.net",
   425  			expectError: ErrDecryptDomainForbidden,
   426  		},
   427  	} {
   428  		ctx := context.TODO()
   429  		ctx = sctx.SetHost(ctx, v.host)
   430  
   431  		me := &ManifestEntry{
   432  			Access: &AccessEntry{Type: AccessTypePass},
   433  		}
   434  
   435  		api := NewAPI(nil, nil, nil, nil)
   436  
   437  		f := api.Decryptor(ctx, "")
   438  		err := f(me)
   439  		if err != v.expectError {
   440  			t.Fatalf("should fail with %v, got %v", v.expectError, err)
   441  		}
   442  	}
   443  }