github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/stream/common_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 stream 26 27 import ( 28 "context" 29 crand "crypto/rand" 30 "errors" 31 "flag" 32 "fmt" 33 "io" 34 "io/ioutil" 35 "math/rand" 36 "os" 37 "strings" 38 "sync/atomic" 39 "testing" 40 "time" 41 42 "github.com/ethereum/go-ethereum/log" 43 "github.com/ethereum/go-ethereum/p2p/discover" 44 p2ptest "github.com/ethereum/go-ethereum/p2p/testing" 45 "github.com/ethereum/go-ethereum/swarm/network" 46 "github.com/ethereum/go-ethereum/swarm/network/simulation" 47 "github.com/ethereum/go-ethereum/swarm/pot" 48 "github.com/ethereum/go-ethereum/swarm/state" 49 "github.com/ethereum/go-ethereum/swarm/storage" 50 mockdb "github.com/ethereum/go-ethereum/swarm/storage/mock/db" 51 colorable "github.com/mattn/go-colorable" 52 ) 53 54 var ( 55 loglevel = flag.Int("loglevel", 2, "verbosity of logs") 56 nodes = flag.Int("nodes", 0, "number of nodes") 57 chunks = flag.Int("chunks", 0, "number of chunks") 58 useMockStore = flag.Bool("mockstore", false, "disabled mock store (default: enabled)") 59 longrunning = flag.Bool("longrunning", false, "do run long-running tests") 60 61 bucketKeyDB = simulation.BucketKey("db") 62 bucketKeyStore = simulation.BucketKey("store") 63 bucketKeyFileStore = simulation.BucketKey("filestore") 64 bucketKeyNetStore = simulation.BucketKey("netstore") 65 bucketKeyDelivery = simulation.BucketKey("delivery") 66 bucketKeyRegistry = simulation.BucketKey("registry") 67 68 chunkSize = 4096 69 pof = pot.DefaultPof(256) 70 ) 71 72 func init() { 73 flag.Parse() 74 rand.Seed(time.Now().UnixNano()) 75 76 log.PrintOrigins(true) 77 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) 78 } 79 80 func createGlobalStore() (string, *mockdb.GlobalStore, error) { 81 var globalStore *mockdb.GlobalStore 82 globalStoreDir, err := ioutil.TempDir("", "global.store") 83 if err != nil { 84 log.Error("Error initiating global store temp directory!", "err", err) 85 return "", nil, err 86 } 87 globalStore, err = mockdb.NewGlobalStore(globalStoreDir) 88 if err != nil { 89 log.Error("Error initiating global store!", "err", err) 90 return "", nil, err 91 } 92 return globalStoreDir, globalStore, nil 93 } 94 95 func newStreamerTester(t *testing.T) (*p2ptest.ProtocolTester, *Registry, *storage.LocalStore, func(), error) { 96 // 97 addr := network.RandomAddr() // 98 to := network.NewKademlia(addr.OAddr, network.NewKadParams()) 99 100 // 101 datadir, err := ioutil.TempDir("", "streamer") 102 if err != nil { 103 return nil, nil, nil, func() {}, err 104 } 105 removeDataDir := func() { 106 os.RemoveAll(datadir) 107 } 108 109 params := storage.NewDefaultLocalStoreParams() 110 params.Init(datadir) 111 params.BaseKey = addr.Over() 112 113 localStore, err := storage.NewTestLocalStoreForAddr(params) 114 if err != nil { 115 return nil, nil, nil, removeDataDir, err 116 } 117 118 db := storage.NewDBAPI(localStore) 119 delivery := NewDelivery(to, db) 120 streamer := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), nil) 121 teardown := func() { 122 streamer.Close() 123 removeDataDir() 124 } 125 protocolTester := p2ptest.NewProtocolTester(t, network.NewNodeIDFromAddr(addr), 1, streamer.runProtocol) 126 127 err = waitForPeers(streamer, 1*time.Second, 1) 128 if err != nil { 129 return nil, nil, nil, nil, errors.New("timeout: peer is not created") 130 } 131 132 return protocolTester, streamer, localStore, teardown, nil 133 } 134 135 func waitForPeers(streamer *Registry, timeout time.Duration, expectedPeers int) error { 136 ticker := time.NewTicker(10 * time.Millisecond) 137 timeoutTimer := time.NewTimer(timeout) 138 for { 139 select { 140 case <-ticker.C: 141 if streamer.peersCount() >= expectedPeers { 142 return nil 143 } 144 case <-timeoutTimer.C: 145 return errors.New("timeout") 146 } 147 } 148 } 149 150 type roundRobinStore struct { 151 index uint32 152 stores []storage.ChunkStore 153 } 154 155 func newRoundRobinStore(stores ...storage.ChunkStore) *roundRobinStore { 156 return &roundRobinStore{ 157 stores: stores, 158 } 159 } 160 161 func (rrs *roundRobinStore) Get(ctx context.Context, addr storage.Address) (*storage.Chunk, error) { 162 return nil, errors.New("get not well defined on round robin store") 163 } 164 165 func (rrs *roundRobinStore) Put(ctx context.Context, chunk *storage.Chunk) { 166 i := atomic.AddUint32(&rrs.index, 1) 167 idx := int(i) % len(rrs.stores) 168 rrs.stores[idx].Put(ctx, chunk) 169 } 170 171 func (rrs *roundRobinStore) Close() { 172 for _, store := range rrs.stores { 173 store.Close() 174 } 175 } 176 177 func readAll(fileStore *storage.FileStore, hash []byte) (int64, error) { 178 r, _ := fileStore.Retrieve(context.TODO(), hash) 179 buf := make([]byte, 1024) 180 var n int 181 var total int64 182 var err error 183 for (total == 0 || n > 0) && err == nil { 184 n, err = r.ReadAt(buf, total) 185 total += int64(n) 186 } 187 if err != nil && err != io.EOF { 188 return total, err 189 } 190 return total, nil 191 } 192 193 func uploadFilesToNodes(sim *simulation.Simulation) ([]storage.Address, []string, error) { 194 nodes := sim.UpNodeIDs() 195 nodeCnt := len(nodes) 196 log.Debug(fmt.Sprintf("Uploading %d files to nodes", nodeCnt)) 197 // 198 rfiles := make([]string, nodeCnt) 199 // 200 rootAddrs := make([]storage.Address, nodeCnt) 201 202 var err error 203 // 204 for i, id := range nodes { 205 item, ok := sim.NodeItem(id, bucketKeyFileStore) 206 if !ok { 207 return nil, nil, fmt.Errorf("Error accessing localstore") 208 } 209 fileStore := item.(*storage.FileStore) 210 // 211 rfiles[i], err = generateRandomFile() 212 if err != nil { 213 return nil, nil, err 214 } 215 // 216 ctx := context.TODO() 217 rk, wait, err := fileStore.Store(ctx, strings.NewReader(rfiles[i]), int64(len(rfiles[i])), false) 218 log.Debug("Uploaded random string file to node") 219 if err != nil { 220 return nil, nil, err 221 } 222 err = wait(ctx) 223 if err != nil { 224 return nil, nil, err 225 } 226 rootAddrs[i] = rk 227 } 228 return rootAddrs, rfiles, nil 229 } 230 231 // 232 func generateRandomFile() (string, error) { 233 // 234 fileSize := rand.Intn(maxFileSize-minFileSize) + minFileSize 235 log.Debug(fmt.Sprintf("Generated file with filesize %d kB", fileSize)) 236 b := make([]byte, fileSize*1024) 237 _, err := crand.Read(b) 238 if err != nil { 239 log.Error("Error generating random file.", "err", err) 240 return "", err 241 } 242 return string(b), nil 243 } 244 245 // 246 func createTestLocalStorageForID(id discover.NodeID, addr *network.BzzAddr) (storage.ChunkStore, string, error) { 247 var datadir string 248 var err error 249 datadir, err = ioutil.TempDir("", fmt.Sprintf("syncer-test-%s", id.TerminalString())) 250 if err != nil { 251 return nil, "", err 252 } 253 var store storage.ChunkStore 254 params := storage.NewDefaultLocalStoreParams() 255 params.ChunkDbPath = datadir 256 params.BaseKey = addr.Over() 257 store, err = storage.NewTestLocalStoreForAddr(params) 258 if err != nil { 259 os.RemoveAll(datadir) 260 return nil, "", err 261 } 262 return store, datadir, nil 263 }