github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/storage/localstore_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 19:16:45</date> 10 //</624450120234045440> 11 12 13 package storage 14 15 import ( 16 "context" 17 "io/ioutil" 18 "os" 19 "testing" 20 "time" 21 22 ch "github.com/ethereum/go-ethereum/swarm/chunk" 23 ) 24 25 var ( 26 hashfunc = MakeHashFunc(DefaultHash) 27 ) 28 29 //测试内容地址验证器是否正确检查数据 30 //通过内容地址验证器传递源更新块的测试 31 //检查资源更新验证器内部正确性的测试在storage/feeds/handler_test.go中找到。 32 func TestValidator(t *testing.T) { 33 //设置本地存储 34 datadir, err := ioutil.TempDir("", "storage-testvalidator") 35 if err != nil { 36 t.Fatal(err) 37 } 38 defer os.RemoveAll(datadir) 39 40 params := NewDefaultLocalStoreParams() 41 params.Init(datadir) 42 store, err := NewLocalStore(params, nil) 43 if err != nil { 44 t.Fatal(err) 45 } 46 47 //不带验证器的检验结果,均成功 48 chunks := GenerateRandomChunks(259, 2) 49 goodChunk := chunks[0] 50 badChunk := chunks[1] 51 copy(badChunk.Data(), goodChunk.Data()) 52 53 errs := putChunks(store, goodChunk, badChunk) 54 if errs[0] != nil { 55 t.Fatalf("expected no error on good content address chunk in spite of no validation, but got: %s", err) 56 } 57 if errs[1] != nil { 58 t.Fatalf("expected no error on bad content address chunk in spite of no validation, but got: %s", err) 59 } 60 61 //添加内容地址验证程序并检查Puts 62 //坏的应该失败,好的应该通过。 63 store.Validators = append(store.Validators, NewContentAddressValidator(hashfunc)) 64 chunks = GenerateRandomChunks(ch.DefaultSize, 2) 65 goodChunk = chunks[0] 66 badChunk = chunks[1] 67 copy(badChunk.Data(), goodChunk.Data()) 68 69 errs = putChunks(store, goodChunk, badChunk) 70 if errs[0] != nil { 71 t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err) 72 } 73 if errs[1] == nil { 74 t.Fatal("expected error on bad content address chunk with content address validator only, but got nil") 75 } 76 77 //附加一个始终拒绝的验证器 78 //坏的应该失败,好的应该通过, 79 var negV boolTestValidator 80 store.Validators = append(store.Validators, negV) 81 82 chunks = GenerateRandomChunks(ch.DefaultSize, 2) 83 goodChunk = chunks[0] 84 badChunk = chunks[1] 85 copy(badChunk.Data(), goodChunk.Data()) 86 87 errs = putChunks(store, goodChunk, badChunk) 88 if errs[0] != nil { 89 t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err) 90 } 91 if errs[1] == nil { 92 t.Fatal("expected error on bad content address chunk with content address validator only, but got nil") 93 } 94 95 //附加一个始终批准的验证器 96 //一切都将通过 97 var posV boolTestValidator = true 98 store.Validators = append(store.Validators, posV) 99 100 chunks = GenerateRandomChunks(ch.DefaultSize, 2) 101 goodChunk = chunks[0] 102 badChunk = chunks[1] 103 copy(badChunk.Data(), goodChunk.Data()) 104 105 errs = putChunks(store, goodChunk, badChunk) 106 if errs[0] != nil { 107 t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err) 108 } 109 if errs[1] != nil { 110 t.Fatalf("expected no error on bad content address chunk in spite of no validation, but got: %s", err) 111 } 112 113 } 114 115 type boolTestValidator bool 116 117 func (self boolTestValidator) Validate(chunk Chunk) bool { 118 return bool(self) 119 } 120 121 //PutChunks将块添加到LocalStore 122 //它等待存储通道上的接收 123 //它记录但在传递错误时不会失败 124 func putChunks(store *LocalStore, chunks ...Chunk) []error { 125 i := 0 126 f := func(n int64) Chunk { 127 chunk := chunks[i] 128 i++ 129 return chunk 130 } 131 _, errs := put(store, len(chunks), f) 132 return errs 133 } 134 135 func put(store *LocalStore, n int, f func(i int64) Chunk) (hs []Address, errs []error) { 136 for i := int64(0); i < int64(n); i++ { 137 chunk := f(ch.DefaultSize) 138 err := store.Put(context.TODO(), chunk) 139 errs = append(errs, err) 140 hs = append(hs, chunk.Address()) 141 } 142 return hs, errs 143 } 144 145 //testgetfrequentlyaccessedchunkwontgetgarbag收集的测试 146 //频繁访问的块不是从ldbstore收集的垃圾,即, 147 //当我们达到容量并且垃圾收集器运行时,从磁盘开始。为此 148 //我们开始将随机块放入数据库,同时不断地访问 149 //我们关心的块,然后检查我们是否仍然可以从磁盘中检索到它。 150 func TestGetFrequentlyAccessedChunkWontGetGarbageCollected(t *testing.T) { 151 ldbCap := defaultGCRatio 152 store, cleanup := setupLocalStore(t, ldbCap) 153 defer cleanup() 154 155 var chunks []Chunk 156 for i := 0; i < ldbCap; i++ { 157 chunks = append(chunks, GenerateRandomChunk(ch.DefaultSize)) 158 } 159 160 mostAccessed := chunks[0].Address() 161 for _, chunk := range chunks { 162 if err := store.Put(context.Background(), chunk); err != nil { 163 t.Fatal(err) 164 } 165 166 if _, err := store.Get(context.Background(), mostAccessed); err != nil { 167 t.Fatal(err) 168 } 169 //添加markaccessed()在单独的goroutine中完成的时间 170 time.Sleep(1 * time.Millisecond) 171 } 172 173 store.DbStore.collectGarbage() 174 if _, err := store.DbStore.Get(context.Background(), mostAccessed); err != nil { 175 t.Logf("most frequntly accessed chunk not found on disk (key: %v)", mostAccessed) 176 t.Fatal(err) 177 } 178 179 } 180 181 func setupLocalStore(t *testing.T, ldbCap int) (ls *LocalStore, cleanup func()) { 182 t.Helper() 183 184 var err error 185 datadir, err := ioutil.TempDir("", "storage") 186 if err != nil { 187 t.Fatal(err) 188 } 189 190 params := &LocalStoreParams{ 191 StoreParams: NewStoreParams(uint64(ldbCap), uint(ldbCap), nil, nil), 192 } 193 params.Init(datadir) 194 195 store, err := NewLocalStore(params, nil) 196 if err != nil { 197 _ = os.RemoveAll(datadir) 198 t.Fatal(err) 199 } 200 201 cleanup = func() { 202 store.Close() 203 _ = os.RemoveAll(datadir) 204 } 205 206 return store, cleanup 207 } 208