github.com/alanchchen/go-ethereum@v1.6.6-0.20170601190819-6171d01b1195/swarm/storage/common_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 storage 18 19 import ( 20 "bytes" 21 "crypto/rand" 22 "fmt" 23 "io" 24 "sync" 25 "testing" 26 27 "github.com/ethereum/go-ethereum/log" 28 ) 29 30 type brokenLimitedReader struct { 31 lr io.Reader 32 errAt int 33 off int 34 size int 35 } 36 37 func brokenLimitReader(data io.Reader, size int, errAt int) *brokenLimitedReader { 38 return &brokenLimitedReader{ 39 lr: data, 40 errAt: errAt, 41 size: size, 42 } 43 } 44 45 func testDataReader(l int) (r io.Reader) { 46 return io.LimitReader(rand.Reader, int64(l)) 47 } 48 49 func (self *brokenLimitedReader) Read(buf []byte) (int, error) { 50 if self.off+len(buf) > self.errAt { 51 return 0, fmt.Errorf("Broken reader") 52 } 53 self.off += len(buf) 54 return self.lr.Read(buf) 55 } 56 57 func testDataReaderAndSlice(l int) (r io.Reader, slice []byte) { 58 slice = make([]byte, l) 59 if _, err := rand.Read(slice); err != nil { 60 panic("rand error") 61 } 62 r = io.LimitReader(bytes.NewReader(slice), int64(l)) 63 return 64 } 65 66 func testStore(m ChunkStore, l int64, branches int64, t *testing.T) { 67 68 chunkC := make(chan *Chunk) 69 go func() { 70 for chunk := range chunkC { 71 m.Put(chunk) 72 if chunk.wg != nil { 73 chunk.wg.Done() 74 } 75 } 76 }() 77 chunker := NewTreeChunker(&ChunkerParams{ 78 Branches: branches, 79 Hash: defaultHash, 80 }) 81 swg := &sync.WaitGroup{} 82 key, _ := chunker.Split(rand.Reader, l, chunkC, swg, nil) 83 swg.Wait() 84 close(chunkC) 85 chunkC = make(chan *Chunk) 86 87 quit := make(chan bool) 88 89 go func() { 90 for ch := range chunkC { 91 go func(chunk *Chunk) { 92 storedChunk, err := m.Get(chunk.Key) 93 if err == notFound { 94 log.Trace(fmt.Sprintf("chunk '%v' not found", chunk.Key.Log())) 95 } else if err != nil { 96 log.Trace(fmt.Sprintf("error retrieving chunk %v: %v", chunk.Key.Log(), err)) 97 } else { 98 chunk.SData = storedChunk.SData 99 chunk.Size = storedChunk.Size 100 } 101 log.Trace(fmt.Sprintf("chunk '%v' not found", chunk.Key.Log())) 102 close(chunk.C) 103 }(ch) 104 } 105 close(quit) 106 }() 107 r := chunker.Join(key, chunkC) 108 109 b := make([]byte, l) 110 n, err := r.ReadAt(b, 0) 111 if err != io.EOF { 112 t.Fatalf("read error (%v/%v) %v", n, l, err) 113 } 114 close(chunkC) 115 <-quit 116 }