github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/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 19:16:33</date> 10 //</624450072133767168> 11 12 13 package main 14 15 import ( 16 "bytes" 17 "fmt" 18 "io" 19 "io/ioutil" 20 "net/http" 21 "os" 22 "path" 23 "path/filepath" 24 "runtime" 25 "strings" 26 "testing" 27 "time" 28 29 "github.com/ethereum/go-ethereum/log" 30 swarmapi "github.com/ethereum/go-ethereum/swarm/api/client" 31 "github.com/ethereum/go-ethereum/swarm/testutil" 32 "github.com/mattn/go-colorable" 33 ) 34 35 func init() { 36 log.PrintOrigins(true) 37 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) 38 } 39 40 func TestSwarmUp(t *testing.T) { 41 if runtime.GOOS == "windows" { 42 t.Skip() 43 } 44 45 initCluster(t) 46 47 cases := []struct { 48 name string 49 f func(t *testing.T) 50 }{ 51 {"NoEncryption", testNoEncryption}, 52 {"Encrypted", testEncrypted}, 53 {"RecursiveNoEncryption", testRecursiveNoEncryption}, 54 {"RecursiveEncrypted", testRecursiveEncrypted}, 55 {"DefaultPathAll", testDefaultPathAll}, 56 } 57 58 for _, tc := range cases { 59 t.Run(tc.name, tc.f) 60 } 61 } 62 63 //testnoEncryption运行“swarm up”生成结果文件的测试 64 //可通过HTTP API从所有节点获取 65 func testNoEncryption(t *testing.T) { 66 testDefault(false, t) 67 } 68 69 //运行“swarm-up--encrypted”的测试加密的测试生成结果文件 70 //可通过HTTP API从所有节点获取 71 func testEncrypted(t *testing.T) { 72 testDefault(true, t) 73 } 74 75 func testRecursiveNoEncryption(t *testing.T) { 76 testRecursive(false, t) 77 } 78 79 func testRecursiveEncrypted(t *testing.T) { 80 testRecursive(true, t) 81 } 82 83 func testDefault(toEncrypt bool, t *testing.T) { 84 tmpFileName := testutil.TempFileWithContent(t, data) 85 defer os.Remove(tmpFileName) 86 87 //将数据写入文件 88 hashRegexp := `[a-f\d]{64}` 89 flags := []string{ 90 "--bzzapi", cluster.Nodes[0].URL, 91 "up", 92 tmpFileName} 93 if toEncrypt { 94 hashRegexp = `[a-f\d]{128}` 95 flags = []string{ 96 "--bzzapi", cluster.Nodes[0].URL, 97 "up", 98 "--encrypt", 99 tmpFileName} 100 } 101 //用“swarm up”上传文件,并期望得到一个哈希值 102 log.Info(fmt.Sprintf("uploading file with 'swarm up'")) 103 up := runSwarm(t, flags...) 104 _, matches := up.ExpectRegexp(hashRegexp) 105 up.ExpectExit() 106 hash := matches[0] 107 log.Info("file uploaded", "hash", hash) 108 109 //从每个节点的HTTP API获取文件 110 for _, node := range cluster.Nodes { 111 log.Info("getting file from node", "node", node.Name) 112 113 res, err := http.Get(node.URL + "/bzz:/" + hash) 114 if err != nil { 115 t.Fatal(err) 116 } 117 defer res.Body.Close() 118 119 reply, err := ioutil.ReadAll(res.Body) 120 if err != nil { 121 t.Fatal(err) 122 } 123 if res.StatusCode != 200 { 124 t.Fatalf("expected HTTP status 200, got %s", res.Status) 125 } 126 if string(reply) != data { 127 t.Fatalf("expected HTTP body %q, got %q", data, reply) 128 } 129 log.Debug("verifying uploaded file using `swarm down`") 130 //试着用“蜂群下降”来获取内容 131 tmpDownload, err := ioutil.TempDir("", "swarm-test") 132 tmpDownload = path.Join(tmpDownload, "tmpfile.tmp") 133 if err != nil { 134 t.Fatal(err) 135 } 136 defer os.RemoveAll(tmpDownload) 137 138 bzzLocator := "bzz:/" + hash 139 flags = []string{ 140 "--bzzapi", cluster.Nodes[0].URL, 141 "down", 142 bzzLocator, 143 tmpDownload, 144 } 145 146 down := runSwarm(t, flags...) 147 down.ExpectExit() 148 149 fi, err := os.Stat(tmpDownload) 150 if err != nil { 151 t.Fatalf("could not stat path: %v", err) 152 } 153 154 switch mode := fi.Mode(); { 155 case mode.IsRegular(): 156 downloadedBytes, err := ioutil.ReadFile(tmpDownload) 157 if err != nil { 158 t.Fatalf("had an error reading the downloaded file: %v", err) 159 } 160 if !bytes.Equal(downloadedBytes, bytes.NewBufferString(data).Bytes()) { 161 t.Fatalf("retrieved data and posted data not equal!") 162 } 163 164 default: 165 t.Fatalf("expected to download regular file, got %s", fi.Mode()) 166 } 167 } 168 169 timeout := time.Duration(2 * time.Second) 170 httpClient := http.Client{ 171 Timeout: timeout, 172 } 173 174 //尝试通过从每个节点获取不存在的哈希来挤压超时 175 for _, node := range cluster.Nodes { 176 _, err := httpClient.Get(node.URL + "/bzz:/1023e8bae0f70be7d7b5f74343088ba408a218254391490c85ae16278e230340") 177 //由于NetStore在请求时有60秒的超时时间,我们正在加快超时时间。 178 if err != nil && !strings.Contains(err.Error(), "Client.Timeout exceeded while awaiting headers") { 179 t.Fatal(err) 180 } 181 //由于NetStore超时需要60秒,因此此选项被禁用。 182 //如果是Res.StatusCode!= 404 { 183 //t.fatalf(“预期的HTTP状态404,得到%s”,res.status) 184 //} 185 } 186 } 187 188 func testRecursive(toEncrypt bool, t *testing.T) { 189 tmpUploadDir, err := ioutil.TempDir("", "swarm-test") 190 if err != nil { 191 t.Fatal(err) 192 } 193 defer os.RemoveAll(tmpUploadDir) 194 //创建tmp文件 195 for _, path := range []string{"tmp1", "tmp2"} { 196 if err := ioutil.WriteFile(filepath.Join(tmpUploadDir, path), bytes.NewBufferString(data).Bytes(), 0644); err != nil { 197 t.Fatal(err) 198 } 199 } 200 201 hashRegexp := `[a-f\d]{64}` 202 flags := []string{ 203 "--bzzapi", cluster.Nodes[0].URL, 204 "--recursive", 205 "up", 206 tmpUploadDir} 207 if toEncrypt { 208 hashRegexp = `[a-f\d]{128}` 209 flags = []string{ 210 "--bzzapi", cluster.Nodes[0].URL, 211 "--recursive", 212 "up", 213 "--encrypt", 214 tmpUploadDir} 215 } 216 //用“swarm up”上传文件,并期望得到一个哈希值 217 log.Info(fmt.Sprintf("uploading file with 'swarm up'")) 218 up := runSwarm(t, flags...) 219 _, matches := up.ExpectRegexp(hashRegexp) 220 up.ExpectExit() 221 hash := matches[0] 222 log.Info("dir uploaded", "hash", hash) 223 224 //从每个节点的HTTP API获取文件 225 for _, node := range cluster.Nodes { 226 log.Info("getting file from node", "node", node.Name) 227 //试着用“蜂群下降”来获取内容 228 tmpDownload, err := ioutil.TempDir("", "swarm-test") 229 if err != nil { 230 t.Fatal(err) 231 } 232 defer os.RemoveAll(tmpDownload) 233 bzzLocator := "bzz:/" + hash 234 flagss := []string{ 235 "--bzzapi", cluster.Nodes[0].URL, 236 "down", 237 "--recursive", 238 bzzLocator, 239 tmpDownload, 240 } 241 242 fmt.Println("downloading from swarm with recursive") 243 down := runSwarm(t, flagss...) 244 down.ExpectExit() 245 246 files, err := ioutil.ReadDir(tmpDownload) 247 for _, v := range files { 248 fi, err := os.Stat(path.Join(tmpDownload, v.Name())) 249 if err != nil { 250 t.Fatalf("got an error: %v", err) 251 } 252 253 switch mode := fi.Mode(); { 254 case mode.IsRegular(): 255 if file, err := swarmapi.Open(path.Join(tmpDownload, v.Name())); err != nil { 256 t.Fatalf("encountered an error opening the file returned from the CLI: %v", err) 257 } else { 258 ff := make([]byte, len(data)) 259 io.ReadFull(file, ff) 260 buf := bytes.NewBufferString(data) 261 262 if !bytes.Equal(ff, buf.Bytes()) { 263 t.Fatalf("retrieved data and posted data not equal!") 264 } 265 } 266 default: 267 t.Fatalf("this shouldnt happen") 268 } 269 } 270 if err != nil { 271 t.Fatalf("could not list files at: %v", files) 272 } 273 } 274 } 275 276 //testdefaultpathall测试群递归上传,具有相对和绝对 277 //默认路径和加密。 278 func testDefaultPathAll(t *testing.T) { 279 testDefaultPath(false, false, t) 280 testDefaultPath(false, true, t) 281 testDefaultPath(true, false, t) 282 testDefaultPath(true, true, t) 283 } 284 285 func testDefaultPath(toEncrypt bool, absDefaultPath bool, t *testing.T) { 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 := swarmapi.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