github.com/XinFinOrg/xdcchain@v1.1.0/cmd/swarm/swarm-smoke/sliding_window.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "bytes" 21 "fmt" 22 "math/rand" 23 "time" 24 25 "github.com/ethereum/go-ethereum/log" 26 "github.com/ethereum/go-ethereum/metrics" 27 "github.com/ethereum/go-ethereum/swarm/testutil" 28 "github.com/pborman/uuid" 29 30 cli "gopkg.in/urfave/cli.v1" 31 ) 32 33 type uploadResult struct { 34 hash string 35 digest []byte 36 } 37 38 func slidingWindowCmd(ctx *cli.Context, tuid string) error { 39 errc := make(chan error) 40 41 go func() { 42 errc <- slidingWindow(ctx, tuid) 43 }() 44 45 select { 46 case err := <-errc: 47 if err != nil { 48 metrics.GetOrRegisterCounter(fmt.Sprintf("%s.fail", commandName), nil).Inc(1) 49 } 50 return err 51 case <-time.After(time.Duration(timeout) * time.Second): 52 metrics.GetOrRegisterCounter(fmt.Sprintf("%s.timeout", commandName), nil).Inc(1) 53 54 return fmt.Errorf("timeout after %v sec", timeout) 55 } 56 } 57 58 func slidingWindow(ctx *cli.Context, tuid string) error { 59 hashes := []uploadResult{} //swarm hashes of the uploads 60 nodes := len(hosts) 61 const iterationTimeout = 30 * time.Second 62 log.Info("sliding window test started", "tuid", tuid, "nodes", nodes, "filesize(kb)", filesize, "timeout", timeout) 63 uploadedBytes := 0 64 networkDepth := 0 65 errored := false 66 67 outer: 68 for { 69 log.Info("uploading to "+httpEndpoint(hosts[0])+" and syncing", "seed", seed) 70 71 t1 := time.Now() 72 73 randomBytes := testutil.RandomBytes(seed, filesize*1000) 74 75 hash, err := upload(randomBytes, httpEndpoint(hosts[0])) 76 if err != nil { 77 log.Error(err.Error()) 78 return err 79 } 80 81 metrics.GetOrRegisterResettingTimer("sliding-window.upload-time", nil).UpdateSince(t1) 82 83 fhash, err := digest(bytes.NewReader(randomBytes)) 84 if err != nil { 85 log.Error(err.Error()) 86 return err 87 } 88 89 log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fhash), "sleeping", syncDelay) 90 hashes = append(hashes, uploadResult{hash: hash, digest: fhash}) 91 time.Sleep(time.Duration(syncDelay) * time.Second) 92 uploadedBytes += filesize * 1000 93 94 for i, v := range hashes { 95 timeout := time.After(time.Duration(timeout) * time.Second) 96 errored = false 97 98 inner: 99 for { 100 select { 101 case <-timeout: 102 errored = true 103 log.Error("error retrieving hash. timeout", "hash idx", i, "err", err) 104 metrics.GetOrRegisterCounter("sliding-window.single.error", nil).Inc(1) 105 break inner 106 default: 107 idx := 1 + rand.Intn(len(hosts)-1) 108 ruid := uuid.New()[:8] 109 start := time.Now() 110 err := fetch(v.hash, httpEndpoint(hosts[idx]), v.digest, ruid, "") 111 if err != nil { 112 continue inner 113 } 114 metrics.GetOrRegisterResettingTimer("sliding-window.single.fetch-time", nil).UpdateSince(start) 115 break inner 116 } 117 } 118 119 if errored { 120 break outer 121 } 122 networkDepth = i 123 metrics.GetOrRegisterGauge("sliding-window.network-depth", nil).Update(int64(networkDepth)) 124 } 125 } 126 127 log.Info("sliding window test finished", "errored?", errored, "networkDepth", networkDepth, "networkDepth(kb)", networkDepth*filesize) 128 log.Info("stats", "uploadedFiles", len(hashes), "uploadedKb", uploadedBytes/1000, "filesizeKb", filesize) 129 130 return nil 131 }