github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/stream/snapshot_retrieval_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 package stream 25 26 import ( 27 "context" 28 "fmt" 29 "os" 30 "sync" 31 "testing" 32 "time" 33 34 "github.com/ethereum/go-ethereum/node" 35 "github.com/ethereum/go-ethereum/p2p/discover" 36 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 37 "github.com/ethereum/go-ethereum/swarm/log" 38 "github.com/ethereum/go-ethereum/swarm/network" 39 "github.com/ethereum/go-ethereum/swarm/network/simulation" 40 "github.com/ethereum/go-ethereum/swarm/state" 41 "github.com/ethereum/go-ethereum/swarm/storage" 42 ) 43 44 // 45 const ( 46 minFileSize = 2 47 maxFileSize = 40 48 ) 49 50 // 51 // 52 // 53 // 54 // 55 func TestFileRetrieval(t *testing.T) { 56 if *nodes != 0 { 57 err := runFileRetrievalTest(*nodes) 58 if err != nil { 59 t.Fatal(err) 60 } 61 } else { 62 nodeCnt := []int{16} 63 // 64 // 65 if *longrunning { 66 nodeCnt = append(nodeCnt, 32, 64, 128) 67 } 68 for _, n := range nodeCnt { 69 err := runFileRetrievalTest(n) 70 if err != nil { 71 t.Fatal(err) 72 } 73 } 74 } 75 } 76 77 // 78 // 79 // 80 // 81 // 82 // 83 func TestRetrieval(t *testing.T) { 84 // 85 // 86 if *nodes != 0 && *chunks != 0 { 87 err := runRetrievalTest(*chunks, *nodes) 88 if err != nil { 89 t.Fatal(err) 90 } 91 } else { 92 var nodeCnt []int 93 var chnkCnt []int 94 // 95 // 96 if *longrunning { 97 nodeCnt = []int{16, 32, 128} 98 chnkCnt = []int{4, 32, 256} 99 } else { 100 // 101 nodeCnt = []int{16} 102 chnkCnt = []int{32} 103 } 104 for _, n := range nodeCnt { 105 for _, c := range chnkCnt { 106 err := runRetrievalTest(c, n) 107 if err != nil { 108 t.Fatal(err) 109 } 110 } 111 } 112 } 113 } 114 115 /* 116 117 118 119 120 121 122 123 */ 124 125 func runFileRetrievalTest(nodeCount int) error { 126 sim := simulation.New(map[string]simulation.ServiceFunc{ 127 "streamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { 128 129 id := ctx.Config.ID 130 addr := network.NewAddrFromNodeID(id) 131 store, datadir, err := createTestLocalStorageForID(id, addr) 132 if err != nil { 133 return nil, nil, err 134 } 135 bucket.Store(bucketKeyStore, store) 136 cleanup = func() { 137 os.RemoveAll(datadir) 138 store.Close() 139 } 140 localStore := store.(*storage.LocalStore) 141 db := storage.NewDBAPI(localStore) 142 kad := network.NewKademlia(addr.Over(), network.NewKadParams()) 143 delivery := NewDelivery(kad, db) 144 145 r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), &RegistryOptions{ 146 DoSync: true, 147 SyncUpdateDelay: 3 * time.Second, 148 }) 149 150 fileStore := storage.NewFileStore(storage.NewNetStore(localStore, nil), storage.NewFileStoreParams()) 151 bucket.Store(bucketKeyFileStore, fileStore) 152 153 return r, cleanup, nil 154 155 }, 156 }) 157 defer sim.Close() 158 159 log.Info("Initializing test config") 160 161 conf := &synctestConfig{} 162 // 163 conf.idToChunksMap = make(map[discover.NodeID][]int) 164 // 165 conf.addrToIDMap = make(map[string]discover.NodeID) 166 // 167 conf.hashes = make([]storage.Address, 0) 168 169 err := sim.UploadSnapshot(fmt.Sprintf("testing/snapshot_%d.json", nodeCount)) 170 if err != nil { 171 return err 172 } 173 174 ctx, cancelSimRun := context.WithTimeout(context.Background(), 1*time.Minute) 175 defer cancelSimRun() 176 177 result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { 178 nodeIDs := sim.UpNodeIDs() 179 for _, n := range nodeIDs { 180 // 181 a := network.ToOverlayAddr(n.Bytes()) 182 // 183 conf.addrs = append(conf.addrs, a) 184 // 185 // 186 // 187 conf.addrToIDMap[string(a)] = n 188 } 189 190 // 191 var randomFiles []string 192 // 193 // 194 // 195 196 conf.hashes, randomFiles, err = uploadFilesToNodes(sim) 197 if err != nil { 198 return err 199 } 200 if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { 201 return err 202 } 203 204 // 205 // 206 allSuccess := false 207 for !allSuccess { 208 for _, id := range nodeIDs { 209 // 210 localChunks := conf.idToChunksMap[id] 211 localSuccess := true 212 for _, ch := range localChunks { 213 // 214 chunk := conf.hashes[ch] 215 log.Trace(fmt.Sprintf("node has chunk: %s:", chunk)) 216 // 217 var err error 218 // 219 item, ok := sim.NodeItem(id, bucketKeyFileStore) 220 if !ok { 221 return fmt.Errorf("No registry") 222 } 223 fileStore := item.(*storage.FileStore) 224 // 225 for i, hash := range conf.hashes { 226 reader, _ := fileStore.Retrieve(context.TODO(), hash) 227 // 228 if s, err := reader.Size(ctx, nil); err != nil || s != int64(len(randomFiles[i])) { 229 allSuccess = false 230 log.Warn("Retrieve error", "err", err, "hash", hash, "nodeId", id) 231 } else { 232 log.Debug(fmt.Sprintf("File with root hash %x successfully retrieved", hash)) 233 } 234 } 235 if err != nil { 236 log.Warn(fmt.Sprintf("Chunk %s NOT found for id %s", chunk, id)) 237 localSuccess = false 238 } else { 239 log.Debug(fmt.Sprintf("Chunk %s IS FOUND for id %s", chunk, id)) 240 } 241 } 242 allSuccess = localSuccess 243 } 244 } 245 if !allSuccess { 246 return fmt.Errorf("Not all chunks succeeded!") 247 } 248 return nil 249 }) 250 251 if result.Error != nil { 252 return result.Error 253 } 254 255 return nil 256 } 257 258 /* 259 260 261 262 263 264 265 266 267 */ 268 269 func runRetrievalTest(chunkCount int, nodeCount int) error { 270 sim := simulation.New(map[string]simulation.ServiceFunc{ 271 "streamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { 272 273 id := ctx.Config.ID 274 addr := network.NewAddrFromNodeID(id) 275 store, datadir, err := createTestLocalStorageForID(id, addr) 276 if err != nil { 277 return nil, nil, err 278 } 279 bucket.Store(bucketKeyStore, store) 280 cleanup = func() { 281 os.RemoveAll(datadir) 282 store.Close() 283 } 284 localStore := store.(*storage.LocalStore) 285 db := storage.NewDBAPI(localStore) 286 kad := network.NewKademlia(addr.Over(), network.NewKadParams()) 287 delivery := NewDelivery(kad, db) 288 289 r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), &RegistryOptions{ 290 DoSync: true, 291 SyncUpdateDelay: 0, 292 }) 293 294 fileStore := storage.NewFileStore(storage.NewNetStore(localStore, nil), storage.NewFileStoreParams()) 295 bucketKeyFileStore = simulation.BucketKey("filestore") 296 bucket.Store(bucketKeyFileStore, fileStore) 297 298 return r, cleanup, nil 299 300 }, 301 }) 302 defer sim.Close() 303 304 conf := &synctestConfig{} 305 // 306 conf.idToChunksMap = make(map[discover.NodeID][]int) 307 // 308 conf.addrToIDMap = make(map[string]discover.NodeID) 309 // 310 conf.hashes = make([]storage.Address, 0) 311 312 err := sim.UploadSnapshot(fmt.Sprintf("testing/snapshot_%d.json", nodeCount)) 313 if err != nil { 314 return err 315 } 316 317 ctx := context.Background() 318 result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { 319 nodeIDs := sim.UpNodeIDs() 320 for _, n := range nodeIDs { 321 // 322 a := network.ToOverlayAddr(n.Bytes()) 323 // 324 conf.addrs = append(conf.addrs, a) 325 // 326 // 327 // 328 conf.addrToIDMap[string(a)] = n 329 } 330 331 // 332 var randomFiles []string 333 // 334 node := sim.RandomUpNode() 335 item, ok := sim.NodeItem(node.ID, bucketKeyStore) 336 if !ok { 337 return fmt.Errorf("No localstore") 338 } 339 lstore := item.(*storage.LocalStore) 340 conf.hashes, err = uploadFileToSingleNodeStore(node.ID, chunkCount, lstore) 341 if err != nil { 342 return err 343 } 344 if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { 345 return err 346 } 347 348 // 349 // 350 allSuccess := false 351 for !allSuccess { 352 for _, id := range nodeIDs { 353 // 354 localChunks := conf.idToChunksMap[id] 355 localSuccess := true 356 for _, ch := range localChunks { 357 // 358 chunk := conf.hashes[ch] 359 log.Trace(fmt.Sprintf("node has chunk: %s:", chunk)) 360 // 361 var err error 362 // 363 item, ok := sim.NodeItem(id, bucketKeyFileStore) 364 if !ok { 365 return fmt.Errorf("No registry") 366 } 367 fileStore := item.(*storage.FileStore) 368 // 369 for i, hash := range conf.hashes { 370 reader, _ := fileStore.Retrieve(context.TODO(), hash) 371 // 372 if s, err := reader.Size(ctx, nil); err != nil || s != int64(len(randomFiles[i])) { 373 allSuccess = false 374 log.Warn("Retrieve error", "err", err, "hash", hash, "nodeId", id) 375 } else { 376 log.Debug(fmt.Sprintf("File with root hash %x successfully retrieved", hash)) 377 } 378 } 379 if err != nil { 380 log.Warn(fmt.Sprintf("Chunk %s NOT found for id %s", chunk, id)) 381 localSuccess = false 382 } else { 383 log.Debug(fmt.Sprintf("Chunk %s IS FOUND for id %s", chunk, id)) 384 } 385 } 386 allSuccess = localSuccess 387 } 388 } 389 if !allSuccess { 390 return fmt.Errorf("Not all chunks succeeded!") 391 } 392 return nil 393 }) 394 395 if result.Error != nil { 396 return result.Error 397 } 398 399 return nil 400 }