github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/storage/memstore_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:49</date> 10 //</624342681815879680> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 28 package storage 29 30 import ( 31 "context" 32 "crypto/rand" 33 "encoding/binary" 34 "io/ioutil" 35 "os" 36 "sync" 37 "testing" 38 39 "github.com/ethereum/go-ethereum/swarm/log" 40 ) 41 42 func newTestMemStore() *MemStore { 43 storeparams := NewDefaultStoreParams() 44 return NewMemStore(storeparams, nil) 45 } 46 47 func testMemStoreRandom(n int, processors int, chunksize int64, t *testing.T) { 48 m := newTestMemStore() 49 defer m.Close() 50 testStoreRandom(m, processors, n, chunksize, t) 51 } 52 53 func testMemStoreCorrect(n int, processors int, chunksize int64, t *testing.T) { 54 m := newTestMemStore() 55 defer m.Close() 56 testStoreCorrect(m, processors, n, chunksize, t) 57 } 58 59 func TestMemStoreRandom_1(t *testing.T) { 60 testMemStoreRandom(1, 1, 0, t) 61 } 62 63 func TestMemStoreCorrect_1(t *testing.T) { 64 testMemStoreCorrect(1, 1, 4104, t) 65 } 66 67 func TestMemStoreRandom_1_1k(t *testing.T) { 68 testMemStoreRandom(1, 1000, 0, t) 69 } 70 71 func TestMemStoreCorrect_1_1k(t *testing.T) { 72 testMemStoreCorrect(1, 100, 4096, t) 73 } 74 75 func TestMemStoreRandom_8_1k(t *testing.T) { 76 testMemStoreRandom(8, 1000, 0, t) 77 } 78 79 func TestMemStoreCorrect_8_1k(t *testing.T) { 80 testMemStoreCorrect(8, 1000, 4096, t) 81 } 82 83 func TestMemStoreNotFound(t *testing.T) { 84 m := newTestMemStore() 85 defer m.Close() 86 87 _, err := m.Get(context.TODO(), ZeroAddr) 88 if err != ErrChunkNotFound { 89 t.Errorf("Expected ErrChunkNotFound, got %v", err) 90 } 91 } 92 93 func benchmarkMemStorePut(n int, processors int, chunksize int64, b *testing.B) { 94 m := newTestMemStore() 95 defer m.Close() 96 benchmarkStorePut(m, processors, n, chunksize, b) 97 } 98 99 func benchmarkMemStoreGet(n int, processors int, chunksize int64, b *testing.B) { 100 m := newTestMemStore() 101 defer m.Close() 102 benchmarkStoreGet(m, processors, n, chunksize, b) 103 } 104 105 func BenchmarkMemStorePut_1_500(b *testing.B) { 106 benchmarkMemStorePut(500, 1, 4096, b) 107 } 108 109 func BenchmarkMemStorePut_8_500(b *testing.B) { 110 benchmarkMemStorePut(500, 8, 4096, b) 111 } 112 113 func BenchmarkMemStoreGet_1_500(b *testing.B) { 114 benchmarkMemStoreGet(500, 1, 4096, b) 115 } 116 117 func BenchmarkMemStoreGet_8_500(b *testing.B) { 118 benchmarkMemStoreGet(500, 8, 4096, b) 119 } 120 121 func newLDBStore(t *testing.T) (*LDBStore, func()) { 122 dir, err := ioutil.TempDir("", "bzz-storage-test") 123 if err != nil { 124 t.Fatal(err) 125 } 126 log.Trace("memstore.tempdir", "dir", dir) 127 128 ldbparams := NewLDBStoreParams(NewDefaultStoreParams(), dir) 129 db, err := NewLDBStore(ldbparams) 130 if err != nil { 131 t.Fatal(err) 132 } 133 134 cleanup := func() { 135 db.Close() 136 err := os.RemoveAll(dir) 137 if err != nil { 138 t.Fatal(err) 139 } 140 } 141 142 return db, cleanup 143 } 144 145 func TestMemStoreAndLDBStore(t *testing.T) { 146 ldb, cleanup := newLDBStore(t) 147 ldb.setCapacity(4000) 148 defer cleanup() 149 150 cacheCap := 200 151 requestsCap := 200 152 memStore := NewMemStore(NewStoreParams(4000, 200, 200, nil, nil), nil) 153 154 tests := []struct { 155 n int // 156 chunkSize uint64 // 157 request bool // 158 }{ 159 { 160 n: 1, 161 chunkSize: 4096, 162 request: false, 163 }, 164 { 165 n: 201, 166 chunkSize: 4096, 167 request: false, 168 }, 169 { 170 n: 501, 171 chunkSize: 4096, 172 request: false, 173 }, 174 { 175 n: 3100, 176 chunkSize: 4096, 177 request: false, 178 }, 179 { 180 n: 100, 181 chunkSize: 4096, 182 request: true, 183 }, 184 } 185 186 for i, tt := range tests { 187 log.Info("running test", "idx", i, "tt", tt) 188 var chunks []*Chunk 189 190 for i := 0; i < tt.n; i++ { 191 var c *Chunk 192 if tt.request { 193 c = NewRandomRequestChunk(tt.chunkSize) 194 } else { 195 c = NewRandomChunk(tt.chunkSize) 196 } 197 198 chunks = append(chunks, c) 199 } 200 201 for i := 0; i < tt.n; i++ { 202 go ldb.Put(context.TODO(), chunks[i]) 203 memStore.Put(context.TODO(), chunks[i]) 204 205 if got := memStore.cache.Len(); got > cacheCap { 206 t.Fatalf("expected to get cache capacity less than %v, but got %v", cacheCap, got) 207 } 208 209 if got := memStore.requests.Len(); got > requestsCap { 210 t.Fatalf("expected to get requests capacity less than %v, but got %v", requestsCap, got) 211 } 212 } 213 214 for i := 0; i < tt.n; i++ { 215 _, err := memStore.Get(context.TODO(), chunks[i].Addr) 216 if err != nil { 217 if err == ErrChunkNotFound { 218 _, err := ldb.Get(context.TODO(), chunks[i].Addr) 219 if err != nil { 220 t.Fatalf("couldn't get chunk %v from ldb, got error: %v", i, err) 221 } 222 } else { 223 t.Fatalf("got error from memstore: %v", err) 224 } 225 } 226 } 227 228 // 229 for i := 0; i < tt.n; i++ { 230 <-chunks[i].dbStoredC 231 } 232 } 233 } 234 235 func NewRandomChunk(chunkSize uint64) *Chunk { 236 c := &Chunk{ 237 Addr: make([]byte, 32), 238 ReqC: nil, 239 SData: make([]byte, chunkSize+8), // 240 dbStoredC: make(chan bool), 241 dbStoredMu: &sync.Mutex{}, 242 } 243 244 rand.Read(c.SData) 245 246 binary.LittleEndian.PutUint64(c.SData[:8], chunkSize) 247 248 hasher := MakeHashFunc(SHA3Hash)() 249 hasher.Write(c.SData) 250 copy(c.Addr, hasher.Sum(nil)) 251 252 return c 253 } 254 255 func NewRandomRequestChunk(chunkSize uint64) *Chunk { 256 c := NewRandomChunk(chunkSize) 257 c.ReqC = make(chan bool) 258 259 return c 260 } 261