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