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