github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/cmd/swarm/upload_test.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 //</624342606624591872> 11 12 13 package main 14 15 import ( 16 "bytes" 17 "flag" 18 "fmt" 19 "io" 20 "io/ioutil" 21 "net/http" 22 "os" 23 "path" 24 "path/filepath" 25 "strings" 26 "testing" 27 "time" 28 29 "github.com/ethereum/go-ethereum/log" 30 swarm "github.com/ethereum/go-ethereum/swarm/api/client" 31 colorable "github.com/mattn/go-colorable" 32 ) 33 34 var loglevel = flag.Int("loglevel", 3, "verbosity of logs") 35 36 func init() { 37 log.PrintOrigins(true) 38 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) 39 } 40 41 //testcliswarmup测试运行“swarm up”生成的文件 42 //可通过HTTP API从所有节点获取 43 func TestCLISwarmUp(t *testing.T) { 44 testCLISwarmUp(false, t) 45 } 46 func TestCLISwarmUpRecursive(t *testing.T) { 47 testCLISwarmUpRecursive(false, t) 48 } 49 50 //testcliswarmupencypted测试运行“swarm encrypted up”生成的文件 51 //可通过HTTP API从所有节点获取 52 func TestCLISwarmUpEncrypted(t *testing.T) { 53 testCLISwarmUp(true, t) 54 } 55 func TestCLISwarmUpEncryptedRecursive(t *testing.T) { 56 testCLISwarmUpRecursive(true, t) 57 } 58 59 func testCLISwarmUp(toEncrypt bool, t *testing.T) { 60 log.Info("starting 3 node cluster") 61 cluster := newTestCluster(t, 3) 62 defer cluster.Shutdown() 63 64 //创建tmp文件 65 tmp, err := ioutil.TempFile("", "swarm-test") 66 if err != nil { 67 t.Fatal(err) 68 } 69 defer tmp.Close() 70 defer os.Remove(tmp.Name()) 71 72 //将数据写入文件 73 data := "notsorandomdata" 74 _, err = io.WriteString(tmp, data) 75 if err != nil { 76 t.Fatal(err) 77 } 78 79 hashRegexp := `[a-f\d]{64}` 80 flags := []string{ 81 "--bzzapi", cluster.Nodes[0].URL, 82 "up", 83 tmp.Name()} 84 if toEncrypt { 85 hashRegexp = `[a-f\d]{128}` 86 flags = []string{ 87 "--bzzapi", cluster.Nodes[0].URL, 88 "up", 89 "--encrypt", 90 tmp.Name()} 91 } 92 //用“swarm up”上传文件,并期望得到一个哈希值 93 log.Info(fmt.Sprintf("uploading file with 'swarm up'")) 94 up := runSwarm(t, flags...) 95 _, matches := up.ExpectRegexp(hashRegexp) 96 up.ExpectExit() 97 hash := matches[0] 98 log.Info("file uploaded", "hash", hash) 99 100 //从每个节点的HTTP API获取文件 101 for _, node := range cluster.Nodes { 102 log.Info("getting file from node", "node", node.Name) 103 104 res, err := http.Get(node.URL + "/bzz:/" + hash) 105 if err != nil { 106 t.Fatal(err) 107 } 108 defer res.Body.Close() 109 110 reply, err := ioutil.ReadAll(res.Body) 111 if err != nil { 112 t.Fatal(err) 113 } 114 if res.StatusCode != 200 { 115 t.Fatalf("expected HTTP status 200, got %s", res.Status) 116 } 117 if string(reply) != data { 118 t.Fatalf("expected HTTP body %q, got %q", data, reply) 119 } 120 log.Debug("verifying uploaded file using `swarm down`") 121 //试着用“蜂群下降”来获取内容 122 tmpDownload, err := ioutil.TempDir("", "swarm-test") 123 tmpDownload = path.Join(tmpDownload, "tmpfile.tmp") 124 if err != nil { 125 t.Fatal(err) 126 } 127 defer os.RemoveAll(tmpDownload) 128 129 bzzLocator := "bzz:/" + hash 130 flags = []string{ 131 "--bzzapi", cluster.Nodes[0].URL, 132 "down", 133 bzzLocator, 134 tmpDownload, 135 } 136 137 down := runSwarm(t, flags...) 138 down.ExpectExit() 139 140 fi, err := os.Stat(tmpDownload) 141 if err != nil { 142 t.Fatalf("could not stat path: %v", err) 143 } 144 145 switch mode := fi.Mode(); { 146 case mode.IsRegular(): 147 downloadedBytes, err := ioutil.ReadFile(tmpDownload) 148 if err != nil { 149 t.Fatalf("had an error reading the downloaded file: %v", err) 150 } 151 if !bytes.Equal(downloadedBytes, bytes.NewBufferString(data).Bytes()) { 152 t.Fatalf("retrieved data and posted data not equal!") 153 } 154 155 default: 156 t.Fatalf("expected to download regular file, got %s", fi.Mode()) 157 } 158 } 159 160 timeout := time.Duration(2 * time.Second) 161 httpClient := http.Client{ 162 Timeout: timeout, 163 } 164 165 // 166 for _, node := range cluster.Nodes { 167 _, err := httpClient.Get(node.URL + "/bzz:/1023e8bae0f70be7d7b5f74343088ba408a218254391490c85ae16278e230340") 168 //由于NetStore在请求时有60秒的超时时间,我们正在加快超时时间。 169 if err != nil && !strings.Contains(err.Error(), "Client.Timeout exceeded while awaiting headers") { 170 t.Fatal(err) 171 } 172 //由于NetStore超时需要60秒,因此此选项被禁用。 173 // 174 //t.fatalf(“预期的HTTP状态404,得到%s”,res.status) 175 // 176 } 177 } 178 179 func testCLISwarmUpRecursive(toEncrypt bool, t *testing.T) { 180 fmt.Println("starting 3 node cluster") 181 cluster := newTestCluster(t, 3) 182 defer cluster.Shutdown() 183 184 tmpUploadDir, err := ioutil.TempDir("", "swarm-test") 185 if err != nil { 186 t.Fatal(err) 187 } 188 defer os.RemoveAll(tmpUploadDir) 189 // 190 data := "notsorandomdata" 191 for _, path := range []string{"tmp1", "tmp2"} { 192 if err := ioutil.WriteFile(filepath.Join(tmpUploadDir, path), bytes.NewBufferString(data).Bytes(), 0644); err != nil { 193 t.Fatal(err) 194 } 195 } 196 197 hashRegexp := `[a-f\d]{64}` 198 flags := []string{ 199 "--bzzapi", cluster.Nodes[0].URL, 200 "--recursive", 201 "up", 202 tmpUploadDir} 203 if toEncrypt { 204 hashRegexp = `[a-f\d]{128}` 205 flags = []string{ 206 "--bzzapi", cluster.Nodes[0].URL, 207 "--recursive", 208 "up", 209 "--encrypt", 210 tmpUploadDir} 211 } 212 //用“swarm up”上传文件,并期望得到一个哈希值 213 log.Info(fmt.Sprintf("uploading file with 'swarm up'")) 214 up := runSwarm(t, flags...) 215 _, matches := up.ExpectRegexp(hashRegexp) 216 up.ExpectExit() 217 hash := matches[0] 218 log.Info("dir uploaded", "hash", hash) 219 220 //从每个节点的HTTP API获取文件 221 for _, node := range cluster.Nodes { 222 log.Info("getting file from node", "node", node.Name) 223 //试着用“蜂群下降”来获取内容 224 tmpDownload, err := ioutil.TempDir("", "swarm-test") 225 if err != nil { 226 t.Fatal(err) 227 } 228 defer os.RemoveAll(tmpDownload) 229 bzzLocator := "bzz:/" + hash 230 flagss := []string{} 231 flagss = []string{ 232 "--bzzapi", cluster.Nodes[0].URL, 233 "down", 234 "--recursive", 235 bzzLocator, 236 tmpDownload, 237 } 238 239 fmt.Println("downloading from swarm with recursive") 240 down := runSwarm(t, flagss...) 241 down.ExpectExit() 242 243 files, err := ioutil.ReadDir(tmpDownload) 244 for _, v := range files { 245 fi, err := os.Stat(path.Join(tmpDownload, v.Name())) 246 if err != nil { 247 t.Fatalf("got an error: %v", err) 248 } 249 250 switch mode := fi.Mode(); { 251 case mode.IsRegular(): 252 if file, err := swarm.Open(path.Join(tmpDownload, v.Name())); err != nil { 253 t.Fatalf("encountered an error opening the file returned from the CLI: %v", err) 254 } else { 255 ff := make([]byte, len(data)) 256 io.ReadFull(file, ff) 257 buf := bytes.NewBufferString(data) 258 259 if !bytes.Equal(ff, buf.Bytes()) { 260 t.Fatalf("retrieved data and posted data not equal!") 261 } 262 } 263 default: 264 t.Fatalf("this shouldnt happen") 265 } 266 } 267 if err != nil { 268 t.Fatalf("could not list files at: %v", files) 269 } 270 } 271 } 272 273 // 274 //默认路径和加密。 275 func TestCLISwarmUpDefaultPath(t *testing.T) { 276 testCLISwarmUpDefaultPath(false, false, t) 277 testCLISwarmUpDefaultPath(false, true, t) 278 testCLISwarmUpDefaultPath(true, false, t) 279 testCLISwarmUpDefaultPath(true, true, t) 280 } 281 282 func testCLISwarmUpDefaultPath(toEncrypt bool, absDefaultPath bool, t *testing.T) { 283 cluster := newTestCluster(t, 1) 284 defer cluster.Shutdown() 285 286 tmp, err := ioutil.TempDir("", "swarm-defaultpath-test") 287 if err != nil { 288 t.Fatal(err) 289 } 290 defer os.RemoveAll(tmp) 291 292 err = ioutil.WriteFile(filepath.Join(tmp, "index.html"), []byte("<h1>Test</h1>"), 0666) 293 if err != nil { 294 t.Fatal(err) 295 } 296 err = ioutil.WriteFile(filepath.Join(tmp, "robots.txt"), []byte("Disallow: /"), 0666) 297 if err != nil { 298 t.Fatal(err) 299 } 300 301 defaultPath := "index.html" 302 if absDefaultPath { 303 defaultPath = filepath.Join(tmp, defaultPath) 304 } 305 306 args := []string{ 307 "--bzzapi", 308 cluster.Nodes[0].URL, 309 "--recursive", 310 "--defaultpath", 311 defaultPath, 312 "up", 313 tmp, 314 } 315 if toEncrypt { 316 args = append(args, "--encrypt") 317 } 318 319 up := runSwarm(t, args...) 320 hashRegexp := `[a-f\d]{64,128}` 321 _, matches := up.ExpectRegexp(hashRegexp) 322 up.ExpectExit() 323 hash := matches[0] 324 325 client := swarm.NewClient(cluster.Nodes[0].URL) 326 327 m, isEncrypted, err := client.DownloadManifest(hash) 328 if err != nil { 329 t.Fatal(err) 330 } 331 332 if toEncrypt != isEncrypted { 333 t.Error("downloaded manifest is not encrypted") 334 } 335 336 var found bool 337 var entriesCount int 338 for _, e := range m.Entries { 339 entriesCount++ 340 if e.Path == "" { 341 found = true 342 } 343 } 344 345 if !found { 346 t.Error("manifest default entry was not found") 347 } 348 349 if entriesCount != 3 { 350 t.Errorf("manifest contains %v entries, expected %v", entriesCount, 3) 351 } 352 } 353