github.com/XinFinOrg/xdcchain@v1.1.0/cmd/swarm/swarm-smoke/util.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 "context" 22 "crypto/md5" 23 crand "crypto/rand" 24 "errors" 25 "fmt" 26 "io" 27 "io/ioutil" 28 "math/rand" 29 "net/http" 30 "net/http/httptrace" 31 "os" 32 "strings" 33 "time" 34 35 "github.com/ethereum/go-ethereum/log" 36 "github.com/ethereum/go-ethereum/metrics" 37 "github.com/ethereum/go-ethereum/swarm/api" 38 "github.com/ethereum/go-ethereum/swarm/api/client" 39 "github.com/ethereum/go-ethereum/swarm/spancontext" 40 opentracing "github.com/opentracing/opentracing-go" 41 "github.com/pborman/uuid" 42 cli "gopkg.in/urfave/cli.v1" 43 ) 44 45 var ( 46 commandName = "" 47 seed = int(time.Now().UTC().UnixNano()) 48 ) 49 50 func init() { 51 rand.Seed(int64(seed)) 52 } 53 54 func httpEndpoint(host string) string { 55 return fmt.Sprintf("http://%s:%d", host, httpPort) 56 } 57 58 func wsEndpoint(host string) string { 59 return fmt.Sprintf("ws://%s:%d", host, wsPort) 60 } 61 62 func wrapCliCommand(name string, command func(*cli.Context, string) error) func(*cli.Context) error { 63 return func(ctx *cli.Context) error { 64 log.PrintOrigins(true) 65 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(verbosity), log.StreamHandler(os.Stdout, log.TerminalFormat(false)))) 66 67 // test uuid 68 tuid := uuid.New()[:8] 69 70 commandName = name 71 72 hosts = strings.Split(allhosts, ",") 73 74 defer func(now time.Time) { 75 totalTime := time.Since(now) 76 log.Info("total time", "tuid", tuid, "time", totalTime, "kb", filesize) 77 metrics.GetOrRegisterResettingTimer(name+".total-time", nil).Update(totalTime) 78 }(time.Now()) 79 80 log.Info("smoke test starting", "tuid", tuid, "task", name, "timeout", timeout) 81 metrics.GetOrRegisterCounter(name, nil).Inc(1) 82 83 return command(ctx, tuid) 84 } 85 } 86 87 func fetchFeed(topic string, user string, endpoint string, original []byte, ruid string) error { 88 ctx, sp := spancontext.StartSpan(context.Background(), "feed-and-sync.fetch") 89 defer sp.Finish() 90 91 log.Trace("sleeping", "ruid", ruid) 92 time.Sleep(3 * time.Second) 93 94 log.Trace("http get request (feed)", "ruid", ruid, "api", endpoint, "topic", topic, "user", user) 95 96 var tn time.Time 97 reqUri := endpoint + "/bzz-feed:/?topic=" + topic + "&user=" + user 98 req, _ := http.NewRequest("GET", reqUri, nil) 99 100 opentracing.GlobalTracer().Inject( 101 sp.Context(), 102 opentracing.HTTPHeaders, 103 opentracing.HTTPHeadersCarrier(req.Header)) 104 105 trace := client.GetClientTrace("feed-and-sync - http get", "feed-and-sync", ruid, &tn) 106 107 req = req.WithContext(httptrace.WithClientTrace(ctx, trace)) 108 transport := http.DefaultTransport 109 110 //transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} 111 112 tn = time.Now() 113 res, err := transport.RoundTrip(req) 114 if err != nil { 115 log.Error(err.Error(), "ruid", ruid) 116 return err 117 } 118 119 log.Trace("http get response (feed)", "ruid", ruid, "api", endpoint, "topic", topic, "user", user, "code", res.StatusCode, "len", res.ContentLength) 120 121 if res.StatusCode != 200 { 122 return fmt.Errorf("expected status code %d, got %v (ruid %v)", 200, res.StatusCode, ruid) 123 } 124 125 defer res.Body.Close() 126 127 rdigest, err := digest(res.Body) 128 if err != nil { 129 log.Warn(err.Error(), "ruid", ruid) 130 return err 131 } 132 133 if !bytes.Equal(rdigest, original) { 134 err := fmt.Errorf("downloaded imported file md5=%x is not the same as the generated one=%x", rdigest, original) 135 log.Warn(err.Error(), "ruid", ruid) 136 return err 137 } 138 139 log.Trace("downloaded file matches random file", "ruid", ruid, "len", res.ContentLength) 140 141 return nil 142 } 143 144 // fetch is getting the requested `hash` from the `endpoint` and compares it with the `original` file 145 func fetch(hash string, endpoint string, original []byte, ruid string, tuid string) error { 146 ctx, sp := spancontext.StartSpan(context.Background(), "upload-and-sync.fetch") 147 defer sp.Finish() 148 149 log.Info("http get request", "tuid", tuid, "ruid", ruid, "endpoint", endpoint, "hash", hash) 150 151 var tn time.Time 152 reqUri := endpoint + "/bzz:/" + hash + "/" 153 req, _ := http.NewRequest("GET", reqUri, nil) 154 155 opentracing.GlobalTracer().Inject( 156 sp.Context(), 157 opentracing.HTTPHeaders, 158 opentracing.HTTPHeadersCarrier(req.Header)) 159 160 trace := client.GetClientTrace(commandName+" - http get", commandName, ruid, &tn) 161 162 req = req.WithContext(httptrace.WithClientTrace(ctx, trace)) 163 transport := http.DefaultTransport 164 165 //transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} 166 167 tn = time.Now() 168 res, err := transport.RoundTrip(req) 169 if err != nil { 170 log.Error(err.Error(), "ruid", ruid) 171 return err 172 } 173 log.Info("http get response", "tuid", tuid, "ruid", ruid, "endpoint", endpoint, "hash", hash, "code", res.StatusCode, "len", res.ContentLength) 174 175 if res.StatusCode != 200 { 176 err := fmt.Errorf("expected status code %d, got %v", 200, res.StatusCode) 177 log.Warn(err.Error(), "ruid", ruid) 178 return err 179 } 180 181 defer res.Body.Close() 182 183 rdigest, err := digest(res.Body) 184 if err != nil { 185 log.Warn(err.Error(), "ruid", ruid) 186 return err 187 } 188 189 if !bytes.Equal(rdigest, original) { 190 err := fmt.Errorf("downloaded imported file md5=%x is not the same as the generated one=%x", rdigest, original) 191 log.Warn(err.Error(), "ruid", ruid) 192 return err 193 } 194 195 log.Trace("downloaded file matches random file", "ruid", ruid, "len", res.ContentLength) 196 197 return nil 198 } 199 200 // upload an arbitrary byte as a plaintext file to `endpoint` using the api client 201 func upload(data []byte, endpoint string) (string, error) { 202 swarm := client.NewClient(endpoint) 203 f := &client.File{ 204 ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), 205 ManifestEntry: api.ManifestEntry{ 206 ContentType: "text/plain", 207 Mode: 0660, 208 Size: int64(len(data)), 209 }, 210 } 211 212 // upload data to bzz:// and retrieve the content-addressed manifest hash, hex-encoded. 213 return swarm.Upload(f, "", false) 214 } 215 216 func digest(r io.Reader) ([]byte, error) { 217 h := md5.New() 218 _, err := io.Copy(h, r) 219 if err != nil { 220 return nil, err 221 } 222 return h.Sum(nil), nil 223 } 224 225 // generates random data in heap buffer 226 func generateRandomData(datasize int) ([]byte, error) { 227 b := make([]byte, datasize) 228 c, err := crand.Read(b) 229 if err != nil { 230 return nil, err 231 } else if c != datasize { 232 return nil, errors.New("short read") 233 } 234 return b, nil 235 }