github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/cmd/swarm/swarm-smoke/upload_and_sync.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 12:09:31</date> 10 //</624342606402293760> 11 12 13 package main 14 15 import ( 16 "bytes" 17 "crypto/md5" 18 "crypto/rand" 19 "fmt" 20 "io" 21 "io/ioutil" 22 "net/http" 23 "os" 24 "os/exec" 25 "strings" 26 "sync" 27 "time" 28 29 "github.com/ethereum/go-ethereum/log" 30 "github.com/pborman/uuid" 31 32 cli "gopkg.in/urfave/cli.v1" 33 ) 34 35 func generateEndpoints(scheme string, cluster string, from int, to int) { 36 if cluster == "prod" { 37 cluster = "" 38 } else { 39 cluster = cluster + "." 40 } 41 42 for port := from; port <= to; port++ { 43 endpoints = append(endpoints, fmt.Sprintf("%s://%v.%sswarm gateways.net“,方案,端口,群集) 44 } 45 46 if includeLocalhost { 47 endpoints = append(endpoints, "http://本地主机:8500“) 48 } 49 } 50 51 func cliUploadAndSync(c *cli.Context) error { 52 defer func(now time.Time) { log.Info("total time", "time", time.Since(now), "size", filesize) }(time.Now()) 53 54 generateEndpoints(scheme, cluster, from, to) 55 56 log.Info("uploading to " + endpoints[0] + " and syncing") 57 58 f, cleanup := generateRandomFile(filesize * 1000000) 59 defer cleanup() 60 61 hash, err := upload(f, endpoints[0]) 62 if err != nil { 63 log.Error(err.Error()) 64 return err 65 } 66 67 fhash, err := digest(f) 68 if err != nil { 69 log.Error(err.Error()) 70 return err 71 } 72 73 log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fhash)) 74 75 if filesize < 10 { 76 time.Sleep(35 * time.Second) 77 } else { 78 time.Sleep(15 * time.Second) 79 time.Sleep(2 * time.Duration(filesize) * time.Second) 80 } 81 82 wg := sync.WaitGroup{} 83 for _, endpoint := range endpoints { 84 endpoint := endpoint 85 ruid := uuid.New()[:8] 86 wg.Add(1) 87 go func(endpoint string, ruid string) { 88 for { 89 err := fetch(hash, endpoint, fhash, ruid) 90 if err != nil { 91 continue 92 } 93 94 wg.Done() 95 return 96 } 97 }(endpoint, ruid) 98 } 99 wg.Wait() 100 log.Info("all endpoints synced random file successfully") 101 102 return nil 103 } 104 105 // 106 func fetch(hash string, endpoint string, original []byte, ruid string) error { 107 log.Trace("sleeping", "ruid", ruid) 108 time.Sleep(5 * time.Second) 109 110 log.Trace("http get request", "ruid", ruid, "api", endpoint, "hash", hash) 111 res, err := http.Get(endpoint + "/bzz:/" + hash + "/") 112 if err != nil { 113 log.Warn(err.Error(), "ruid", ruid) 114 return err 115 } 116 log.Trace("http get response", "ruid", ruid, "api", endpoint, "hash", hash, "code", res.StatusCode, "len", res.ContentLength) 117 118 if res.StatusCode != 200 { 119 err := fmt.Errorf("expected status code %d, got %v", 200, res.StatusCode) 120 log.Warn(err.Error(), "ruid", ruid) 121 return err 122 } 123 124 defer res.Body.Close() 125 126 rdigest, err := digest(res.Body) 127 if err != nil { 128 log.Warn(err.Error(), "ruid", ruid) 129 return err 130 } 131 132 if !bytes.Equal(rdigest, original) { 133 err := fmt.Errorf("downloaded imported file md5=%x is not the same as the generated one=%x", rdigest, original) 134 log.Warn(err.Error(), "ruid", ruid) 135 return err 136 } 137 138 log.Trace("downloaded file matches random file", "ruid", ruid, "len", res.ContentLength) 139 140 return nil 141 } 142 143 //upload正在通过“swarm up”命令将文件“f”上载到“endpoint” 144 func upload(f *os.File, endpoint string) (string, error) { 145 var out bytes.Buffer 146 cmd := exec.Command("swarm", "--bzzapi", endpoint, "up", f.Name()) 147 cmd.Stdout = &out 148 err := cmd.Run() 149 if err != nil { 150 return "", err 151 } 152 hash := strings.TrimRight(out.String(), "\r\n") 153 return hash, nil 154 } 155 156 func digest(r io.Reader) ([]byte, error) { 157 h := md5.New() 158 _, err := io.Copy(h, r) 159 if err != nil { 160 return nil, err 161 } 162 return h.Sum(nil), nil 163 } 164 165 //GenerateRandomFile正在创建具有请求字节大小的临时文件 166 func generateRandomFile(size int) (f *os.File, teardown func()) { 167 //创建tmp文件 168 tmp, err := ioutil.TempFile("", "swarm-test") 169 if err != nil { 170 panic(err) 171 } 172 173 //tmp文件清理回调 174 teardown = func() { 175 tmp.Close() 176 os.Remove(tmp.Name()) 177 } 178 179 buf := make([]byte, size) 180 _, err = rand.Read(buf) 181 if err != nil { 182 panic(err) 183 } 184 ioutil.WriteFile(tmp.Name(), buf, 0755) 185 186 return tmp, teardown 187 } 188