github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/swarm/api/api_test.go (about)

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