github.com/oskarth/go-ethereum@v1.6.8-0.20191013093314-dac24a9d3494/swarm/storage/mock/test/test.go (about)

     1  // Copyright 2018 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 test provides functions that are used for testing
    18  // GlobalStorer implementations.
    19  package test
    20  
    21  import (
    22  	"bytes"
    23  	"fmt"
    24  	"io"
    25  	"strconv"
    26  	"testing"
    27  
    28  	"github.com/ethereum/go-ethereum/common"
    29  	"github.com/ethereum/go-ethereum/swarm/storage"
    30  	"github.com/ethereum/go-ethereum/swarm/storage/mock"
    31  )
    32  
    33  // MockStore creates NodeStore instances from provided GlobalStorer,
    34  // each one with a unique address, stores different chunks on them
    35  // and checks if they are retrievable or not on all nodes.
    36  // Attribute n defines the number of NodeStores that will be created.
    37  func MockStore(t *testing.T, globalStore mock.GlobalStorer, n int) {
    38  	t.Run("GlobalStore", func(t *testing.T) {
    39  		addrs := make([]common.Address, n)
    40  		for i := 0; i < n; i++ {
    41  			addrs[i] = common.HexToAddress(strconv.FormatInt(int64(i)+1, 16))
    42  		}
    43  
    44  		for i, addr := range addrs {
    45  			chunkAddr := storage.Address(append(addr[:], []byte(strconv.FormatInt(int64(i)+1, 16))...))
    46  			data := []byte(strconv.FormatInt(int64(i)+1, 16))
    47  			data = append(data, make([]byte, 4096-len(data))...)
    48  			globalStore.Put(addr, chunkAddr, data)
    49  
    50  			for _, cAddr := range addrs {
    51  				cData, err := globalStore.Get(cAddr, chunkAddr)
    52  				if cAddr == addr {
    53  					if err != nil {
    54  						t.Fatalf("get data from store %s key %s: %v", cAddr.Hex(), chunkAddr.Hex(), err)
    55  					}
    56  					if !bytes.Equal(data, cData) {
    57  						t.Fatalf("data on store %s: expected %x, got %x", cAddr.Hex(), data, cData)
    58  					}
    59  					if !globalStore.HasKey(cAddr, chunkAddr) {
    60  						t.Fatalf("expected key %s on global store for node %s, but it was not found", chunkAddr.Hex(), cAddr.Hex())
    61  					}
    62  				} else {
    63  					if err != mock.ErrNotFound {
    64  						t.Fatalf("expected error from store %s: %v, got %v", cAddr.Hex(), mock.ErrNotFound, err)
    65  					}
    66  					if len(cData) > 0 {
    67  						t.Fatalf("data on store %s: expected nil, got %x", cAddr.Hex(), cData)
    68  					}
    69  					if globalStore.HasKey(cAddr, chunkAddr) {
    70  						t.Fatalf("not expected key %s on global store for node %s, but it was found", chunkAddr.Hex(), cAddr.Hex())
    71  					}
    72  				}
    73  			}
    74  		}
    75  	})
    76  
    77  	t.Run("NodeStore", func(t *testing.T) {
    78  		nodes := make(map[common.Address]*mock.NodeStore)
    79  		for i := 0; i < n; i++ {
    80  			addr := common.HexToAddress(strconv.FormatInt(int64(i)+1, 16))
    81  			nodes[addr] = globalStore.NewNodeStore(addr)
    82  		}
    83  
    84  		i := 0
    85  		for addr, store := range nodes {
    86  			i++
    87  			chunkAddr := storage.Address(append(addr[:], []byte(fmt.Sprintf("%x", i))...))
    88  			data := []byte(strconv.FormatInt(int64(i)+1, 16))
    89  			data = append(data, make([]byte, 4096-len(data))...)
    90  			store.Put(chunkAddr, data)
    91  
    92  			for cAddr, cStore := range nodes {
    93  				cData, err := cStore.Get(chunkAddr)
    94  				if cAddr == addr {
    95  					if err != nil {
    96  						t.Fatalf("get data from store %s key %s: %v", cAddr.Hex(), chunkAddr.Hex(), err)
    97  					}
    98  					if !bytes.Equal(data, cData) {
    99  						t.Fatalf("data on store %s: expected %x, got %x", cAddr.Hex(), data, cData)
   100  					}
   101  					if !globalStore.HasKey(cAddr, chunkAddr) {
   102  						t.Fatalf("expected key %s on global store for node %s, but it was not found", chunkAddr.Hex(), cAddr.Hex())
   103  					}
   104  				} else {
   105  					if err != mock.ErrNotFound {
   106  						t.Fatalf("expected error from store %s: %v, got %v", cAddr.Hex(), mock.ErrNotFound, err)
   107  					}
   108  					if len(cData) > 0 {
   109  						t.Fatalf("data on store %s: expected nil, got %x", cAddr.Hex(), cData)
   110  					}
   111  					if globalStore.HasKey(cAddr, chunkAddr) {
   112  						t.Fatalf("not expected key %s on global store for node %s, but it was found", chunkAddr.Hex(), cAddr.Hex())
   113  					}
   114  				}
   115  			}
   116  		}
   117  	})
   118  }
   119  
   120  // ImportExport saves chunks to the outStore, exports them to the tar archive,
   121  // imports tar archive to the inStore and checks if all chunks are imported correctly.
   122  func ImportExport(t *testing.T, outStore, inStore mock.GlobalStorer, n int) {
   123  	exporter, ok := outStore.(mock.Exporter)
   124  	if !ok {
   125  		t.Fatal("outStore does not implement mock.Exporter")
   126  	}
   127  	importer, ok := inStore.(mock.Importer)
   128  	if !ok {
   129  		t.Fatal("inStore does not implement mock.Importer")
   130  	}
   131  	addrs := make([]common.Address, n)
   132  	for i := 0; i < n; i++ {
   133  		addrs[i] = common.HexToAddress(strconv.FormatInt(int64(i)+1, 16))
   134  	}
   135  
   136  	for i, addr := range addrs {
   137  		chunkAddr := storage.Address(append(addr[:], []byte(strconv.FormatInt(int64(i)+1, 16))...))
   138  		data := []byte(strconv.FormatInt(int64(i)+1, 16))
   139  		data = append(data, make([]byte, 4096-len(data))...)
   140  		outStore.Put(addr, chunkAddr, data)
   141  	}
   142  
   143  	r, w := io.Pipe()
   144  	defer r.Close()
   145  
   146  	go func() {
   147  		defer w.Close()
   148  		if _, err := exporter.Export(w); err != nil {
   149  			t.Fatalf("export: %v", err)
   150  		}
   151  	}()
   152  
   153  	if _, err := importer.Import(r); err != nil {
   154  		t.Fatalf("import: %v", err)
   155  	}
   156  
   157  	for i, addr := range addrs {
   158  		chunkAddr := storage.Address(append(addr[:], []byte(strconv.FormatInt(int64(i)+1, 16))...))
   159  		data := []byte(strconv.FormatInt(int64(i)+1, 16))
   160  		data = append(data, make([]byte, 4096-len(data))...)
   161  		for _, cAddr := range addrs {
   162  			cData, err := inStore.Get(cAddr, chunkAddr)
   163  			if cAddr == addr {
   164  				if err != nil {
   165  					t.Fatalf("get data from store %s key %s: %v", cAddr.Hex(), chunkAddr.Hex(), err)
   166  				}
   167  				if !bytes.Equal(data, cData) {
   168  					t.Fatalf("data on store %s: expected %x, got %x", cAddr.Hex(), data, cData)
   169  				}
   170  				if !inStore.HasKey(cAddr, chunkAddr) {
   171  					t.Fatalf("expected key %s on global store for node %s, but it was not found", chunkAddr.Hex(), cAddr.Hex())
   172  				}
   173  			} else {
   174  				if err != mock.ErrNotFound {
   175  					t.Fatalf("expected error from store %s: %v, got %v", cAddr.Hex(), mock.ErrNotFound, err)
   176  				}
   177  				if len(cData) > 0 {
   178  					t.Fatalf("data on store %s: expected nil, got %x", cAddr.Hex(), cData)
   179  				}
   180  				if inStore.HasKey(cAddr, chunkAddr) {
   181  					t.Fatalf("not expected key %s on global store for node %s, but it was found", chunkAddr.Hex(), cAddr.Hex())
   182  				}
   183  			}
   184  		}
   185  	}
   186  }