github.com/gobitfly/go-ethereum@v1.8.12/swarm/storage/netstore_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 storage 18 19 import ( 20 "encoding/hex" 21 "errors" 22 "io/ioutil" 23 "testing" 24 "time" 25 26 "github.com/ethereum/go-ethereum/swarm/network" 27 ) 28 29 var ( 30 errUnknown = errors.New("unknown error") 31 ) 32 33 type mockRetrieve struct { 34 requests map[string]int 35 } 36 37 func NewMockRetrieve() *mockRetrieve { 38 return &mockRetrieve{requests: make(map[string]int)} 39 } 40 41 func newDummyChunk(addr Address) *Chunk { 42 chunk := NewChunk(addr, make(chan bool)) 43 chunk.SData = []byte{3, 4, 5} 44 chunk.Size = 3 45 46 return chunk 47 } 48 49 func (m *mockRetrieve) retrieve(chunk *Chunk) error { 50 hkey := hex.EncodeToString(chunk.Addr) 51 m.requests[hkey] += 1 52 53 // on second call return error 54 if m.requests[hkey] == 2 { 55 return errUnknown 56 } 57 58 // on third call return data 59 if m.requests[hkey] == 3 { 60 *chunk = *newDummyChunk(chunk.Addr) 61 go func() { 62 time.Sleep(100 * time.Millisecond) 63 close(chunk.ReqC) 64 }() 65 66 return nil 67 } 68 69 return nil 70 } 71 72 func TestNetstoreFailedRequest(t *testing.T) { 73 searchTimeout = 300 * time.Millisecond 74 75 // setup 76 addr := network.RandomAddr() // tested peers peer address 77 78 // temp datadir 79 datadir, err := ioutil.TempDir("", "netstore") 80 if err != nil { 81 t.Fatal(err) 82 } 83 params := NewDefaultLocalStoreParams() 84 params.Init(datadir) 85 params.BaseKey = addr.Over() 86 localStore, err := NewTestLocalStoreForAddr(params) 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 r := NewMockRetrieve() 92 netStore := NewNetStore(localStore, r.retrieve) 93 94 key := Address{} 95 96 // first call is done by the retry on ErrChunkNotFound, no need to do it here 97 // _, err = netStore.Get(key) 98 // if err == nil || err != ErrChunkNotFound { 99 // t.Fatalf("expected to get ErrChunkNotFound, but got: %s", err) 100 // } 101 102 // second call 103 _, err = netStore.Get(key) 104 if got := r.requests[hex.EncodeToString(key)]; got != 2 { 105 t.Fatalf("expected to have called retrieve two times, but got: %v", got) 106 } 107 if err != errUnknown { 108 t.Fatalf("expected to get an unknown error, but got: %s", err) 109 } 110 111 // third call 112 chunk, err := netStore.Get(key) 113 if got := r.requests[hex.EncodeToString(key)]; got != 3 { 114 t.Fatalf("expected to have called retrieve three times, but got: %v", got) 115 } 116 if err != nil || chunk == nil { 117 t.Fatalf("expected to get a chunk but got: %v, %s", chunk, err) 118 } 119 if len(chunk.SData) != 3 { 120 t.Fatalf("expected to get a chunk with size 3, but got: %v", chunk.SData) 121 } 122 }