github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/go-ethereum-master/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  	"fmt"
    23  	"io"
    24  	"io/ioutil"
    25  	"math/big"
    26  	"os"
    27  	"testing"
    28  
    29  	"github.com/ethereum/go-ethereum/common"
    30  	"github.com/ethereum/go-ethereum/core/types"
    31  	"github.com/ethereum/go-ethereum/swarm/log"
    32  	"github.com/ethereum/go-ethereum/swarm/storage"
    33  )
    34  
    35  func testAPI(t *testing.T, f func(*API, bool)) {
    36  	datadir, err := ioutil.TempDir("", "bzz-test")
    37  	if err != nil {
    38  		t.Fatalf("unable to create temp dir: %v", err)
    39  	}
    40  	defer os.RemoveAll(datadir)
    41  	fileStore, err := storage.NewLocalFileStore(datadir, make([]byte, 32))
    42  	if err != nil {
    43  		return
    44  	}
    45  	api := NewAPI(fileStore, nil, nil)
    46  	f(api, false)
    47  	f(api, true)
    48  }
    49  
    50  type testResponse struct {
    51  	reader storage.LazySectionReader
    52  	*Response
    53  }
    54  
    55  func checkResponse(t *testing.T, resp *testResponse, exp *Response) {
    56  
    57  	if resp.MimeType != exp.MimeType {
    58  		t.Errorf("incorrect mimeType. expected '%s', got '%s'", exp.MimeType, resp.MimeType)
    59  	}
    60  	if resp.Status != exp.Status {
    61  		t.Errorf("incorrect status. expected '%d', got '%d'", exp.Status, resp.Status)
    62  	}
    63  	if resp.Size != exp.Size {
    64  		t.Errorf("incorrect size. expected '%d', got '%d'", exp.Size, resp.Size)
    65  	}
    66  	if resp.reader != nil {
    67  		content := make([]byte, resp.Size)
    68  		read, _ := resp.reader.Read(content)
    69  		if int64(read) != exp.Size {
    70  			t.Errorf("incorrect content length. expected '%d...', got '%d...'", read, exp.Size)
    71  		}
    72  		resp.Content = string(content)
    73  	}
    74  	if resp.Content != exp.Content {
    75  		// if !bytes.Equal(resp.Content, exp.Content)
    76  		t.Errorf("incorrect content. expected '%s...', got '%s...'", string(exp.Content), string(resp.Content))
    77  	}
    78  }
    79  
    80  // func expResponse(content []byte, mimeType string, status int) *Response {
    81  func expResponse(content string, mimeType string, status int) *Response {
    82  	log.Trace(fmt.Sprintf("expected content (%v): %v ", len(content), content))
    83  	return &Response{mimeType, status, int64(len(content)), content}
    84  }
    85  
    86  func testGet(t *testing.T, api *API, bzzhash, path string) *testResponse {
    87  	addr := storage.Address(common.Hex2Bytes(bzzhash))
    88  	reader, mimeType, status, _, err := api.Get(context.TODO(), addr, path)
    89  	if err != nil {
    90  		t.Fatalf("unexpected error: %v", err)
    91  	}
    92  	quitC := make(chan bool)
    93  	size, err := reader.Size(quitC)
    94  	if err != nil {
    95  		t.Fatalf("unexpected error: %v", err)
    96  	}
    97  	log.Trace(fmt.Sprintf("reader size: %v ", size))
    98  	s := make([]byte, size)
    99  	_, err = reader.Read(s)
   100  	if err != io.EOF {
   101  		t.Fatalf("unexpected error: %v", err)
   102  	}
   103  	reader.Seek(0, 0)
   104  	return &testResponse{reader, &Response{mimeType, status, size, string(s)}}
   105  	// return &testResponse{reader, &Response{mimeType, status, reader.Size(), nil}}
   106  }
   107  
   108  func TestApiPut(t *testing.T) {
   109  	testAPI(t, func(api *API, toEncrypt bool) {
   110  		content := "hello"
   111  		exp := expResponse(content, "text/plain", 0)
   112  		ctx := context.TODO()
   113  		addr, wait, err := api.Put(ctx, content, exp.MimeType, toEncrypt)
   114  		if err != nil {
   115  			t.Fatalf("unexpected error: %v", err)
   116  		}
   117  		err = wait(ctx)
   118  		if err != nil {
   119  			t.Fatalf("unexpected error: %v", err)
   120  		}
   121  		resp := testGet(t, api, addr.Hex(), "")
   122  		checkResponse(t, resp, exp)
   123  	})
   124  }
   125  
   126  // testResolver implements the Resolver interface and either returns the given
   127  // hash if it is set, or returns a "name not found" error
   128  type testResolveValidator struct {
   129  	hash *common.Hash
   130  }
   131  
   132  func newTestResolveValidator(addr string) *testResolveValidator {
   133  	r := &testResolveValidator{}
   134  	if addr != "" {
   135  		hash := common.HexToHash(addr)
   136  		r.hash = &hash
   137  	}
   138  	return r
   139  }
   140  
   141  func (t *testResolveValidator) Resolve(addr string) (common.Hash, error) {
   142  	if t.hash == nil {
   143  		return common.Hash{}, fmt.Errorf("DNS name not found: %q", addr)
   144  	}
   145  	return *t.hash, nil
   146  }
   147  
   148  func (t *testResolveValidator) Owner(node [32]byte) (addr common.Address, err error) {
   149  	return
   150  }
   151  func (t *testResolveValidator) HeaderByNumber(context.Context, *big.Int) (header *types.Header, err error) {
   152  	return
   153  }
   154  
   155  // TestAPIResolve tests resolving URIs which can either contain content hashes
   156  // or ENS names
   157  func TestAPIResolve(t *testing.T) {
   158  	ensAddr := "swarm.eth"
   159  	hashAddr := "1111111111111111111111111111111111111111111111111111111111111111"
   160  	resolvedAddr := "2222222222222222222222222222222222222222222222222222222222222222"
   161  	doesResolve := newTestResolveValidator(resolvedAddr)
   162  	doesntResolve := newTestResolveValidator("")
   163  
   164  	type test struct {
   165  		desc      string
   166  		dns       Resolver
   167  		addr      string
   168  		immutable bool
   169  		result    string
   170  		expectErr error
   171  	}
   172  
   173  	tests := []*test{
   174  		{
   175  			desc:   "DNS not configured, hash address, returns hash address",
   176  			dns:    nil,
   177  			addr:   hashAddr,
   178  			result: hashAddr,
   179  		},
   180  		{
   181  			desc:      "DNS not configured, ENS address, returns error",
   182  			dns:       nil,
   183  			addr:      ensAddr,
   184  			expectErr: errors.New(`no DNS to resolve name: "swarm.eth"`),
   185  		},
   186  		{
   187  			desc:   "DNS configured, hash address, hash resolves, returns resolved address",
   188  			dns:    doesResolve,
   189  			addr:   hashAddr,
   190  			result: resolvedAddr,
   191  		},
   192  		{
   193  			desc:      "DNS configured, immutable hash address, hash resolves, returns hash address",
   194  			dns:       doesResolve,
   195  			addr:      hashAddr,
   196  			immutable: true,
   197  			result:    hashAddr,
   198  		},
   199  		{
   200  			desc:   "DNS configured, hash address, hash doesn't resolve, returns hash address",
   201  			dns:    doesntResolve,
   202  			addr:   hashAddr,
   203  			result: hashAddr,
   204  		},
   205  		{
   206  			desc:   "DNS configured, ENS address, name resolves, returns resolved address",
   207  			dns:    doesResolve,
   208  			addr:   ensAddr,
   209  			result: resolvedAddr,
   210  		},
   211  		{
   212  			desc:      "DNS configured, immutable ENS address, name resolves, returns error",
   213  			dns:       doesResolve,
   214  			addr:      ensAddr,
   215  			immutable: true,
   216  			expectErr: errors.New(`immutable address not a content hash: "swarm.eth"`),
   217  		},
   218  		{
   219  			desc:      "DNS configured, ENS address, name doesn't resolve, returns error",
   220  			dns:       doesntResolve,
   221  			addr:      ensAddr,
   222  			expectErr: errors.New(`DNS name not found: "swarm.eth"`),
   223  		},
   224  	}
   225  	for _, x := range tests {
   226  		t.Run(x.desc, func(t *testing.T) {
   227  			api := &API{dns: x.dns}
   228  			uri := &URI{Addr: x.addr, Scheme: "bzz"}
   229  			if x.immutable {
   230  				uri.Scheme = "bzz-immutable"
   231  			}
   232  			res, err := api.Resolve(context.TODO(), uri)
   233  			if err == nil {
   234  				if x.expectErr != nil {
   235  					t.Fatalf("expected error %q, got result %q", x.expectErr, res)
   236  				}
   237  				if res.String() != x.result {
   238  					t.Fatalf("expected result %q, got %q", x.result, res)
   239  				}
   240  			} else {
   241  				if x.expectErr == nil {
   242  					t.Fatalf("expected no error, got %q", err)
   243  				}
   244  				if err.Error() != x.expectErr.Error() {
   245  					t.Fatalf("expected error %q, got %q", x.expectErr, err)
   246  				}
   247  			}
   248  		})
   249  	}
   250  }
   251  
   252  func TestMultiResolver(t *testing.T) {
   253  	doesntResolve := newTestResolveValidator("")
   254  
   255  	ethAddr := "swarm.eth"
   256  	ethHash := "0x2222222222222222222222222222222222222222222222222222222222222222"
   257  	ethResolve := newTestResolveValidator(ethHash)
   258  
   259  	testAddr := "swarm.test"
   260  	testHash := "0x1111111111111111111111111111111111111111111111111111111111111111"
   261  	testResolve := newTestResolveValidator(testHash)
   262  
   263  	tests := []struct {
   264  		desc   string
   265  		r      Resolver
   266  		addr   string
   267  		result string
   268  		err    error
   269  	}{
   270  		{
   271  			desc: "No resolvers, returns error",
   272  			r:    NewMultiResolver(),
   273  			err:  NewNoResolverError(""),
   274  		},
   275  		{
   276  			desc:   "One default resolver, returns resolved address",
   277  			r:      NewMultiResolver(MultiResolverOptionWithResolver(ethResolve, "")),
   278  			addr:   ethAddr,
   279  			result: ethHash,
   280  		},
   281  		{
   282  			desc: "Two default resolvers, returns resolved address",
   283  			r: NewMultiResolver(
   284  				MultiResolverOptionWithResolver(ethResolve, ""),
   285  				MultiResolverOptionWithResolver(ethResolve, ""),
   286  			),
   287  			addr:   ethAddr,
   288  			result: ethHash,
   289  		},
   290  		{
   291  			desc: "Two default resolvers, first doesn't resolve, returns resolved address",
   292  			r: NewMultiResolver(
   293  				MultiResolverOptionWithResolver(doesntResolve, ""),
   294  				MultiResolverOptionWithResolver(ethResolve, ""),
   295  			),
   296  			addr:   ethAddr,
   297  			result: ethHash,
   298  		},
   299  		{
   300  			desc: "Default resolver doesn't resolve, tld resolver resolve, returns resolved address",
   301  			r: NewMultiResolver(
   302  				MultiResolverOptionWithResolver(doesntResolve, ""),
   303  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   304  			),
   305  			addr:   ethAddr,
   306  			result: ethHash,
   307  		},
   308  		{
   309  			desc: "Three TLD resolvers, third resolves, returns resolved address",
   310  			r: NewMultiResolver(
   311  				MultiResolverOptionWithResolver(doesntResolve, "eth"),
   312  				MultiResolverOptionWithResolver(doesntResolve, "eth"),
   313  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   314  			),
   315  			addr:   ethAddr,
   316  			result: ethHash,
   317  		},
   318  		{
   319  			desc: "One TLD resolver doesn't resolve, returns error",
   320  			r: NewMultiResolver(
   321  				MultiResolverOptionWithResolver(doesntResolve, ""),
   322  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   323  			),
   324  			addr:   ethAddr,
   325  			result: ethHash,
   326  		},
   327  		{
   328  			desc: "One defautl and one TLD resolver, all doesn't resolve, returns error",
   329  			r: NewMultiResolver(
   330  				MultiResolverOptionWithResolver(doesntResolve, ""),
   331  				MultiResolverOptionWithResolver(doesntResolve, "eth"),
   332  			),
   333  			addr:   ethAddr,
   334  			result: ethHash,
   335  			err:    errors.New(`DNS name not found: "swarm.eth"`),
   336  		},
   337  		{
   338  			desc: "Two TLD resolvers, both resolve, returns resolved address",
   339  			r: NewMultiResolver(
   340  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   341  				MultiResolverOptionWithResolver(testResolve, "test"),
   342  			),
   343  			addr:   testAddr,
   344  			result: testHash,
   345  		},
   346  		{
   347  			desc: "One TLD resolver, no default resolver, returns error for different TLD",
   348  			r: NewMultiResolver(
   349  				MultiResolverOptionWithResolver(ethResolve, "eth"),
   350  			),
   351  			addr: testAddr,
   352  			err:  NewNoResolverError("test"),
   353  		},
   354  	}
   355  	for _, x := range tests {
   356  		t.Run(x.desc, func(t *testing.T) {
   357  			res, err := x.r.Resolve(x.addr)
   358  			if err == nil {
   359  				if x.err != nil {
   360  					t.Fatalf("expected error %q, got result %q", x.err, res.Hex())
   361  				}
   362  				if res.Hex() != x.result {
   363  					t.Fatalf("expected result %q, got %q", x.result, res.Hex())
   364  				}
   365  			} else {
   366  				if x.err == nil {
   367  					t.Fatalf("expected no error, got %q", err)
   368  				}
   369  				if err.Error() != x.err.Error() {
   370  					t.Fatalf("expected error %q, got %q", x.err, err)
   371  				}
   372  			}
   373  		})
   374  	}
   375  }