github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/cmd/swarm/manifest_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 //</624450071206825984> 11 12 13 package main 14 15 import ( 16 "bytes" 17 "io/ioutil" 18 "os" 19 "path/filepath" 20 "runtime" 21 "testing" 22 23 "github.com/ethereum/go-ethereum/swarm/api" 24 swarm "github.com/ethereum/go-ethereum/swarm/api/client" 25 swarmhttp "github.com/ethereum/go-ethereum/swarm/api/http" 26 ) 27 28 //测试清单更改测试清单添加、更新和删除 29 //不加密的CLI命令。 30 func TestManifestChange(t *testing.T) { 31 if runtime.GOOS == "windows" { 32 t.Skip() 33 } 34 35 testManifestChange(t, false) 36 } 37 38 //测试清单更改测试清单添加、更新和删除 39 // 40 func TestManifestChangeEncrypted(t *testing.T) { 41 if runtime.GOOS == "windows" { 42 t.Skip() 43 } 44 45 testManifestChange(t, true) 46 } 47 48 // 49 //-清单添加 50 // 51 //-清单删除 52 // 53 //根清单或嵌套清单中的路径上的命令。 54 //参数encrypt控制是否使用加密。 55 func testManifestChange(t *testing.T, encrypt bool) { 56 t.Parallel() 57 srv := swarmhttp.NewTestSwarmServer(t, serverFunc, nil) 58 defer srv.Close() 59 60 tmp, err := ioutil.TempDir("", "swarm-manifest-test") 61 if err != nil { 62 t.Fatal(err) 63 } 64 defer os.RemoveAll(tmp) 65 66 origDir := filepath.Join(tmp, "orig") 67 if err := os.Mkdir(origDir, 0777); err != nil { 68 t.Fatal(err) 69 } 70 71 indexDataFilename := filepath.Join(origDir, "index.html") 72 err = ioutil.WriteFile(indexDataFilename, []byte("<h1>Test</h1>"), 0666) 73 if err != nil { 74 t.Fatal(err) 75 } 76 // 77 //这将在路径“robots.”下生成一个嵌套清单的清单。 78 //这将允许在根清单和嵌套清单上测试清单更改。 79 err = ioutil.WriteFile(filepath.Join(origDir, "robots.txt"), []byte("Disallow: /"), 0666) 80 if err != nil { 81 t.Fatal(err) 82 } 83 err = ioutil.WriteFile(filepath.Join(origDir, "robots.html"), []byte("<strong>No Robots Allowed</strong>"), 0666) 84 if err != nil { 85 t.Fatal(err) 86 } 87 err = ioutil.WriteFile(filepath.Join(origDir, "mutants.txt"), []byte("Frank\nMarcus"), 0666) 88 if err != nil { 89 t.Fatal(err) 90 } 91 92 args := []string{ 93 "--bzzapi", 94 srv.URL, 95 "--recursive", 96 "--defaultpath", 97 indexDataFilename, 98 "up", 99 origDir, 100 } 101 if encrypt { 102 args = append(args, "--encrypt") 103 } 104 105 origManifestHash := runSwarmExpectHash(t, args...) 106 107 checkHashLength(t, origManifestHash, encrypt) 108 109 client := swarm.NewClient(srv.URL) 110 111 //上载新文件并使用其清单将其添加到原始清单。 112 t.Run("add", func(t *testing.T) { 113 humansData := []byte("Ann\nBob") 114 humansDataFilename := filepath.Join(tmp, "humans.txt") 115 err = ioutil.WriteFile(humansDataFilename, humansData, 0666) 116 if err != nil { 117 t.Fatal(err) 118 } 119 120 humansManifestHash := runSwarmExpectHash(t, 121 "--bzzapi", 122 srv.URL, 123 "up", 124 humansDataFilename, 125 ) 126 127 newManifestHash := runSwarmExpectHash(t, 128 "--bzzapi", 129 srv.URL, 130 "manifest", 131 "add", 132 origManifestHash, 133 "humans.txt", 134 humansManifestHash, 135 ) 136 137 checkHashLength(t, newManifestHash, encrypt) 138 139 newManifest := downloadManifest(t, client, newManifestHash, encrypt) 140 141 var found bool 142 for _, e := range newManifest.Entries { 143 if e.Path == "humans.txt" { 144 found = true 145 if e.Size != int64(len(humansData)) { 146 t.Errorf("expected humans.txt size %v, got %v", len(humansData), e.Size) 147 } 148 if e.ModTime.IsZero() { 149 t.Errorf("got zero mod time for humans.txt") 150 } 151 ct := "text/plain; charset=utf-8" 152 if e.ContentType != ct { 153 t.Errorf("expected content type %q, got %q", ct, e.ContentType) 154 } 155 break 156 } 157 } 158 if !found { 159 t.Fatal("no humans.txt in new manifest") 160 } 161 162 checkFile(t, client, newManifestHash, "humans.txt", humansData) 163 }) 164 165 //上载新文件并使用其清单添加原始清单, 166 //但请确保该文件将位于原始文件的嵌套清单中。 167 t.Run("add nested", func(t *testing.T) { 168 robotsData := []byte(`{"disallow": "/"}`) 169 robotsDataFilename := filepath.Join(tmp, "robots.json") 170 err = ioutil.WriteFile(robotsDataFilename, robotsData, 0666) 171 if err != nil { 172 t.Fatal(err) 173 } 174 175 robotsManifestHash := runSwarmExpectHash(t, 176 "--bzzapi", 177 srv.URL, 178 "up", 179 robotsDataFilename, 180 ) 181 182 newManifestHash := runSwarmExpectHash(t, 183 "--bzzapi", 184 srv.URL, 185 "manifest", 186 "add", 187 origManifestHash, 188 "robots.json", 189 robotsManifestHash, 190 ) 191 192 checkHashLength(t, newManifestHash, encrypt) 193 194 newManifest := downloadManifest(t, client, newManifestHash, encrypt) 195 196 var found bool 197 loop: 198 for _, e := range newManifest.Entries { 199 if e.Path == "robots." { 200 nestedManifest := downloadManifest(t, client, e.Hash, encrypt) 201 for _, e := range nestedManifest.Entries { 202 if e.Path == "json" { 203 found = true 204 if e.Size != int64(len(robotsData)) { 205 t.Errorf("expected robots.json size %v, got %v", len(robotsData), e.Size) 206 } 207 if e.ModTime.IsZero() { 208 t.Errorf("got zero mod time for robots.json") 209 } 210 ct := "application/json" 211 if e.ContentType != ct { 212 t.Errorf("expected content type %q, got %q", ct, e.ContentType) 213 } 214 break loop 215 } 216 } 217 } 218 } 219 if !found { 220 t.Fatal("no robots.json in new manifest") 221 } 222 223 checkFile(t, client, newManifestHash, "robots.json", robotsData) 224 }) 225 226 // 227 t.Run("update", func(t *testing.T) { 228 indexData := []byte("<h1>Ethereum Swarm</h1>") 229 indexDataFilename := filepath.Join(tmp, "index.html") 230 err = ioutil.WriteFile(indexDataFilename, indexData, 0666) 231 if err != nil { 232 t.Fatal(err) 233 } 234 235 indexManifestHash := runSwarmExpectHash(t, 236 "--bzzapi", 237 srv.URL, 238 "up", 239 indexDataFilename, 240 ) 241 242 newManifestHash := runSwarmExpectHash(t, 243 "--bzzapi", 244 srv.URL, 245 "manifest", 246 "update", 247 origManifestHash, 248 "index.html", 249 indexManifestHash, 250 ) 251 252 checkHashLength(t, newManifestHash, encrypt) 253 254 newManifest := downloadManifest(t, client, newManifestHash, encrypt) 255 256 var found bool 257 for _, e := range newManifest.Entries { 258 if e.Path == "index.html" { 259 found = true 260 if e.Size != int64(len(indexData)) { 261 t.Errorf("expected index.html size %v, got %v", len(indexData), e.Size) 262 } 263 if e.ModTime.IsZero() { 264 t.Errorf("got zero mod time for index.html") 265 } 266 ct := "text/html; charset=utf-8" 267 if e.ContentType != ct { 268 t.Errorf("expected content type %q, got %q", ct, e.ContentType) 269 } 270 break 271 } 272 } 273 if !found { 274 t.Fatal("no index.html in new manifest") 275 } 276 277 checkFile(t, client, newManifestHash, "index.html", indexData) 278 279 //检查默认条目更改 280 checkFile(t, client, newManifestHash, "", indexData) 281 }) 282 283 //上载新文件并使用其清单将文件更改为原始清单, 284 // 285 t.Run("update nested", func(t *testing.T) { 286 robotsData := []byte(`<string>Only humans allowed!!!</strong>`) 287 robotsDataFilename := filepath.Join(tmp, "robots.html") 288 err = ioutil.WriteFile(robotsDataFilename, robotsData, 0666) 289 if err != nil { 290 t.Fatal(err) 291 } 292 293 humansManifestHash := runSwarmExpectHash(t, 294 "--bzzapi", 295 srv.URL, 296 "up", 297 robotsDataFilename, 298 ) 299 300 newManifestHash := runSwarmExpectHash(t, 301 "--bzzapi", 302 srv.URL, 303 "manifest", 304 "update", 305 origManifestHash, 306 "robots.html", 307 humansManifestHash, 308 ) 309 310 checkHashLength(t, newManifestHash, encrypt) 311 312 newManifest := downloadManifest(t, client, newManifestHash, encrypt) 313 314 var found bool 315 loop: 316 for _, e := range newManifest.Entries { 317 if e.Path == "robots." { 318 nestedManifest := downloadManifest(t, client, e.Hash, encrypt) 319 for _, e := range nestedManifest.Entries { 320 if e.Path == "html" { 321 found = true 322 if e.Size != int64(len(robotsData)) { 323 t.Errorf("expected robots.html size %v, got %v", len(robotsData), e.Size) 324 } 325 if e.ModTime.IsZero() { 326 t.Errorf("got zero mod time for robots.html") 327 } 328 ct := "text/html; charset=utf-8" 329 if e.ContentType != ct { 330 t.Errorf("expected content type %q, got %q", ct, e.ContentType) 331 } 332 break loop 333 } 334 } 335 } 336 } 337 if !found { 338 t.Fatal("no robots.html in new manifest") 339 } 340 341 checkFile(t, client, newManifestHash, "robots.html", robotsData) 342 }) 343 344 //从清单中删除文件。 345 t.Run("remove", func(t *testing.T) { 346 newManifestHash := runSwarmExpectHash(t, 347 "--bzzapi", 348 srv.URL, 349 "manifest", 350 "remove", 351 origManifestHash, 352 "mutants.txt", 353 ) 354 355 checkHashLength(t, newManifestHash, encrypt) 356 357 newManifest := downloadManifest(t, client, newManifestHash, encrypt) 358 359 var found bool 360 for _, e := range newManifest.Entries { 361 if e.Path == "mutants.txt" { 362 found = true 363 break 364 } 365 } 366 if found { 367 t.Fatal("mutants.txt is not removed") 368 } 369 }) 370 371 //从清单中删除文件,但确保该文件位于 372 //原始清单的嵌套清单。 373 t.Run("remove nested", func(t *testing.T) { 374 newManifestHash := runSwarmExpectHash(t, 375 "--bzzapi", 376 srv.URL, 377 "manifest", 378 "remove", 379 origManifestHash, 380 "robots.html", 381 ) 382 383 checkHashLength(t, newManifestHash, encrypt) 384 385 newManifest := downloadManifest(t, client, newManifestHash, encrypt) 386 387 var found bool 388 loop: 389 for _, e := range newManifest.Entries { 390 if e.Path == "robots." { 391 nestedManifest := downloadManifest(t, client, e.Hash, encrypt) 392 for _, e := range nestedManifest.Entries { 393 if e.Path == "html" { 394 found = true 395 break loop 396 } 397 } 398 } 399 } 400 if found { 401 t.Fatal("robots.html in not removed") 402 } 403 }) 404 } 405 406 // 407 // 408 func TestNestedDefaultEntryUpdate(t *testing.T) { 409 if runtime.GOOS == "windows" { 410 t.Skip() 411 } 412 413 testNestedDefaultEntryUpdate(t, false) 414 } 415 416 //如果默认项为 417 //如果嵌套清单中的文件 418 // 419 func TestNestedDefaultEntryUpdateEncrypted(t *testing.T) { 420 if runtime.GOOS == "windows" { 421 t.Skip() 422 } 423 424 testNestedDefaultEntryUpdate(t, true) 425 } 426 427 func testNestedDefaultEntryUpdate(t *testing.T, encrypt bool) { 428 t.Parallel() 429 srv := swarmhttp.NewTestSwarmServer(t, serverFunc, nil) 430 defer srv.Close() 431 432 tmp, err := ioutil.TempDir("", "swarm-manifest-test") 433 if err != nil { 434 t.Fatal(err) 435 } 436 defer os.RemoveAll(tmp) 437 438 origDir := filepath.Join(tmp, "orig") 439 if err := os.Mkdir(origDir, 0777); err != nil { 440 t.Fatal(err) 441 } 442 443 indexData := []byte("<h1>Test</h1>") 444 indexDataFilename := filepath.Join(origDir, "index.html") 445 err = ioutil.WriteFile(indexDataFilename, indexData, 0666) 446 if err != nil { 447 t.Fatal(err) 448 } 449 //添加另一个具有公共前缀的文件作为默认项,以测试 450 // 451 err = ioutil.WriteFile(filepath.Join(origDir, "index.txt"), []byte("Test"), 0666) 452 if err != nil { 453 t.Fatal(err) 454 } 455 456 args := []string{ 457 "--bzzapi", 458 srv.URL, 459 "--recursive", 460 "--defaultpath", 461 indexDataFilename, 462 "up", 463 origDir, 464 } 465 if encrypt { 466 args = append(args, "--encrypt") 467 } 468 469 origManifestHash := runSwarmExpectHash(t, args...) 470 471 checkHashLength(t, origManifestHash, encrypt) 472 473 client := swarm.NewClient(srv.URL) 474 475 newIndexData := []byte("<h1>Ethereum Swarm</h1>") 476 newIndexDataFilename := filepath.Join(tmp, "index.html") 477 err = ioutil.WriteFile(newIndexDataFilename, newIndexData, 0666) 478 if err != nil { 479 t.Fatal(err) 480 } 481 482 newIndexManifestHash := runSwarmExpectHash(t, 483 "--bzzapi", 484 srv.URL, 485 "up", 486 newIndexDataFilename, 487 ) 488 489 newManifestHash := runSwarmExpectHash(t, 490 "--bzzapi", 491 srv.URL, 492 "manifest", 493 "update", 494 origManifestHash, 495 "index.html", 496 newIndexManifestHash, 497 ) 498 499 checkHashLength(t, newManifestHash, encrypt) 500 501 newManifest := downloadManifest(t, client, newManifestHash, encrypt) 502 503 var found bool 504 for _, e := range newManifest.Entries { 505 if e.Path == "index." { 506 found = true 507 newManifest = downloadManifest(t, client, e.Hash, encrypt) 508 break 509 } 510 } 511 if !found { 512 t.Fatal("no index. path in new manifest") 513 } 514 515 found = false 516 for _, e := range newManifest.Entries { 517 if e.Path == "html" { 518 found = true 519 if e.Size != int64(len(newIndexData)) { 520 t.Errorf("expected index.html size %v, got %v", len(newIndexData), e.Size) 521 } 522 if e.ModTime.IsZero() { 523 t.Errorf("got zero mod time for index.html") 524 } 525 ct := "text/html; charset=utf-8" 526 if e.ContentType != ct { 527 t.Errorf("expected content type %q, got %q", ct, e.ContentType) 528 } 529 break 530 } 531 } 532 if !found { 533 t.Fatal("no html in new manifest") 534 } 535 536 checkFile(t, client, newManifestHash, "index.html", newIndexData) 537 538 //检查默认条目更改 539 checkFile(t, client, newManifestHash, "", newIndexData) 540 } 541 542 func runSwarmExpectHash(t *testing.T, args ...string) (hash string) { 543 t.Helper() 544 hashRegexp := `[a-f\d]{64,128}` 545 up := runSwarm(t, args...) 546 _, matches := up.ExpectRegexp(hashRegexp) 547 up.ExpectExit() 548 549 if len(matches) < 1 { 550 t.Fatal("no matches found") 551 } 552 return matches[0] 553 } 554 555 func checkHashLength(t *testing.T, hash string, encrypted bool) { 556 t.Helper() 557 l := len(hash) 558 if encrypted && l != 128 { 559 t.Errorf("expected hash length 128, got %v", l) 560 } 561 if !encrypted && l != 64 { 562 t.Errorf("expected hash length 64, got %v", l) 563 } 564 } 565 566 func downloadManifest(t *testing.T, client *swarm.Client, hash string, encrypted bool) (manifest *api.Manifest) { 567 t.Helper() 568 m, isEncrypted, err := client.DownloadManifest(hash) 569 if err != nil { 570 t.Fatal(err) 571 } 572 573 if encrypted != isEncrypted { 574 t.Error("new manifest encryption flag is not correct") 575 } 576 return m 577 } 578 579 func checkFile(t *testing.T, client *swarm.Client, hash, path string, expected []byte) { 580 t.Helper() 581 f, err := client.Download(hash, path) 582 if err != nil { 583 t.Fatal(err) 584 } 585 586 got, err := ioutil.ReadAll(f) 587 if err != nil { 588 t.Fatal(err) 589 } 590 if !bytes.Equal(got, expected) { 591 t.Errorf("expected file content %q, got %q", expected, got) 592 } 593 } 594