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