github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/api/client/client_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-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package client 26 27 import ( 28 "bytes" 29 "io/ioutil" 30 "os" 31 "path/filepath" 32 "reflect" 33 "sort" 34 "testing" 35 36 "github.com/ethereum/go-ethereum/common" 37 "github.com/ethereum/go-ethereum/crypto" 38 "github.com/ethereum/go-ethereum/swarm/api" 39 swarmhttp "github.com/ethereum/go-ethereum/swarm/api/http" 40 "github.com/ethereum/go-ethereum/swarm/multihash" 41 "github.com/ethereum/go-ethereum/swarm/storage/mru" 42 "github.com/ethereum/go-ethereum/swarm/testutil" 43 ) 44 45 func serverFunc(api *api.API) testutil.TestServer { 46 return swarmhttp.NewServer(api, "") 47 } 48 49 //测试客户端上传下载原始测试上传和下载原始数据到Swarm 50 func TestClientUploadDownloadRaw(t *testing.T) { 51 testClientUploadDownloadRaw(false, t) 52 } 53 func TestClientUploadDownloadRawEncrypted(t *testing.T) { 54 testClientUploadDownloadRaw(true, t) 55 } 56 57 func testClientUploadDownloadRaw(toEncrypt bool, t *testing.T) { 58 srv := testutil.NewTestSwarmServer(t, serverFunc) 59 defer srv.Close() 60 61 client := NewClient(srv.URL) 62 63 //上传一些原始数据 64 data := []byte("foo123") 65 hash, err := client.UploadRaw(bytes.NewReader(data), int64(len(data)), toEncrypt) 66 if err != nil { 67 t.Fatal(err) 68 } 69 70 //检查我们是否可以下载相同的数据 71 res, isEncrypted, err := client.DownloadRaw(hash) 72 if err != nil { 73 t.Fatal(err) 74 } 75 if isEncrypted != toEncrypt { 76 t.Fatalf("Expected encyption status %v got %v", toEncrypt, isEncrypted) 77 } 78 defer res.Close() 79 gotData, err := ioutil.ReadAll(res) 80 if err != nil { 81 t.Fatal(err) 82 } 83 if !bytes.Equal(gotData, data) { 84 t.Fatalf("expected downloaded data to be %q, got %q", data, gotData) 85 } 86 } 87 88 //测试客户端上传下载文件测试上传和下载文件到Swarm 89 //清单 90 func TestClientUploadDownloadFiles(t *testing.T) { 91 testClientUploadDownloadFiles(false, t) 92 } 93 94 func TestClientUploadDownloadFilesEncrypted(t *testing.T) { 95 testClientUploadDownloadFiles(true, t) 96 } 97 98 func testClientUploadDownloadFiles(toEncrypt bool, t *testing.T) { 99 srv := testutil.NewTestSwarmServer(t, serverFunc) 100 defer srv.Close() 101 102 client := NewClient(srv.URL) 103 upload := func(manifest, path string, data []byte) string { 104 file := &File{ 105 ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), 106 ManifestEntry: api.ManifestEntry{ 107 Path: path, 108 ContentType: "text/plain", 109 Size: int64(len(data)), 110 }, 111 } 112 hash, err := client.Upload(file, manifest, toEncrypt) 113 if err != nil { 114 t.Fatal(err) 115 } 116 return hash 117 } 118 checkDownload := func(manifest, path string, expected []byte) { 119 file, err := client.Download(manifest, path) 120 if err != nil { 121 t.Fatal(err) 122 } 123 defer file.Close() 124 if file.Size != int64(len(expected)) { 125 t.Fatalf("expected downloaded file to be %d bytes, got %d", len(expected), file.Size) 126 } 127 if file.ContentType != "text/plain" { 128 t.Fatalf("expected downloaded file to have type %q, got %q", "text/plain", file.ContentType) 129 } 130 data, err := ioutil.ReadAll(file) 131 if err != nil { 132 t.Fatal(err) 133 } 134 if !bytes.Equal(data, expected) { 135 t.Fatalf("expected downloaded data to be %q, got %q", expected, data) 136 } 137 } 138 139 //将文件上载到清单的根目录 140 rootData := []byte("some-data") 141 rootHash := upload("", "", rootData) 142 143 //检查我们是否可以下载根文件 144 checkDownload(rootHash, "", rootData) 145 146 //将另一个文件上载到同一清单 147 otherData := []byte("some-other-data") 148 newHash := upload(rootHash, "some/other/path", otherData) 149 150 //检查我们可以从新清单下载这两个文件 151 checkDownload(newHash, "", rootData) 152 checkDownload(newHash, "some/other/path", otherData) 153 154 //用不同的数据替换根文件 155 newHash = upload(newHash, "", otherData) 156 157 //检查两个文件是否都有其他数据 158 checkDownload(newHash, "", otherData) 159 checkDownload(newHash, "some/other/path", otherData) 160 } 161 162 var testDirFiles = []string{ 163 "file1.txt", 164 "file2.txt", 165 "dir1/file3.txt", 166 "dir1/file4.txt", 167 "dir2/file5.txt", 168 "dir2/dir3/file6.txt", 169 "dir2/dir4/file7.txt", 170 "dir2/dir4/file8.txt", 171 } 172 173 func newTestDirectory(t *testing.T) string { 174 dir, err := ioutil.TempDir("", "swarm-client-test") 175 if err != nil { 176 t.Fatal(err) 177 } 178 179 for _, file := range testDirFiles { 180 path := filepath.Join(dir, file) 181 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { 182 os.RemoveAll(dir) 183 t.Fatalf("error creating dir for %s: %s", path, err) 184 } 185 if err := ioutil.WriteFile(path, []byte(file), 0644); err != nil { 186 os.RemoveAll(dir) 187 t.Fatalf("error writing file %s: %s", path, err) 188 } 189 } 190 191 return dir 192 } 193 194 //测试客户端上载下载目录测试上载和下载 195 //Swarm清单的文件目录 196 func TestClientUploadDownloadDirectory(t *testing.T) { 197 srv := testutil.NewTestSwarmServer(t, serverFunc) 198 defer srv.Close() 199 200 dir := newTestDirectory(t) 201 defer os.RemoveAll(dir) 202 203 //上传目录 204 client := NewClient(srv.URL) 205 defaultPath := testDirFiles[0] 206 hash, err := client.UploadDirectory(dir, defaultPath, "", false) 207 if err != nil { 208 t.Fatalf("error uploading directory: %s", err) 209 } 210 211 //检查我们是否可以下载单独的文件 212 checkDownloadFile := func(path string, expected []byte) { 213 file, err := client.Download(hash, path) 214 if err != nil { 215 t.Fatal(err) 216 } 217 defer file.Close() 218 data, err := ioutil.ReadAll(file) 219 if err != nil { 220 t.Fatal(err) 221 } 222 if !bytes.Equal(data, expected) { 223 t.Fatalf("expected data to be %q, got %q", expected, data) 224 } 225 } 226 for _, file := range testDirFiles { 227 checkDownloadFile(file, []byte(file)) 228 } 229 230 //检查我们是否可以下载默认路径 231 checkDownloadFile("", []byte(testDirFiles[0])) 232 233 //检查我们可以下载目录 234 tmp, err := ioutil.TempDir("", "swarm-client-test") 235 if err != nil { 236 t.Fatal(err) 237 } 238 defer os.RemoveAll(tmp) 239 if err := client.DownloadDirectory(hash, "", tmp, ""); err != nil { 240 t.Fatal(err) 241 } 242 for _, file := range testDirFiles { 243 data, err := ioutil.ReadFile(filepath.Join(tmp, file)) 244 if err != nil { 245 t.Fatal(err) 246 } 247 if !bytes.Equal(data, []byte(file)) { 248 t.Fatalf("expected data to be %q, got %q", file, data) 249 } 250 } 251 } 252 253 //testclientfilelist在swarm清单中列出文件的测试 254 func TestClientFileList(t *testing.T) { 255 testClientFileList(false, t) 256 } 257 258 func TestClientFileListEncrypted(t *testing.T) { 259 testClientFileList(true, t) 260 } 261 262 func testClientFileList(toEncrypt bool, t *testing.T) { 263 srv := testutil.NewTestSwarmServer(t, serverFunc) 264 defer srv.Close() 265 266 dir := newTestDirectory(t) 267 defer os.RemoveAll(dir) 268 269 client := NewClient(srv.URL) 270 hash, err := client.UploadDirectory(dir, "", "", toEncrypt) 271 if err != nil { 272 t.Fatalf("error uploading directory: %s", err) 273 } 274 275 ls := func(prefix string) []string { 276 list, err := client.List(hash, prefix, "") 277 if err != nil { 278 t.Fatal(err) 279 } 280 paths := make([]string, 0, len(list.CommonPrefixes)+len(list.Entries)) 281 paths = append(paths, list.CommonPrefixes...) 282 for _, entry := range list.Entries { 283 paths = append(paths, entry.Path) 284 } 285 sort.Strings(paths) 286 return paths 287 } 288 289 tests := map[string][]string{ 290 "": {"dir1/", "dir2/", "file1.txt", "file2.txt"}, 291 "file": {"file1.txt", "file2.txt"}, 292 "file1": {"file1.txt"}, 293 "file2.txt": {"file2.txt"}, 294 "file12": {}, 295 "dir": {"dir1/", "dir2/"}, 296 "dir1": {"dir1/"}, 297 "dir1/": {"dir1/file3.txt", "dir1/file4.txt"}, 298 "dir1/file": {"dir1/file3.txt", "dir1/file4.txt"}, 299 "dir1/file3.txt": {"dir1/file3.txt"}, 300 "dir1/file34": {}, 301 "dir2/": {"dir2/dir3/", "dir2/dir4/", "dir2/file5.txt"}, 302 "dir2/file": {"dir2/file5.txt"}, 303 "dir2/dir": {"dir2/dir3/", "dir2/dir4/"}, 304 "dir2/dir3/": {"dir2/dir3/file6.txt"}, 305 "dir2/dir4/": {"dir2/dir4/file7.txt", "dir2/dir4/file8.txt"}, 306 "dir2/dir4/file": {"dir2/dir4/file7.txt", "dir2/dir4/file8.txt"}, 307 "dir2/dir4/file7.txt": {"dir2/dir4/file7.txt"}, 308 "dir2/dir4/file78": {}, 309 } 310 for prefix, expected := range tests { 311 actual := ls(prefix) 312 if !reflect.DeepEqual(actual, expected) { 313 t.Fatalf("expected prefix %q to return %v, got %v", prefix, expected, actual) 314 } 315 } 316 } 317 318 //testclientmultipartupload测试使用多部分将文件上载到swarm 319 //上传 320 func TestClientMultipartUpload(t *testing.T) { 321 srv := testutil.NewTestSwarmServer(t, serverFunc) 322 defer srv.Close() 323 324 //定义上载程序,该上载程序使用某些数据上载testdir文件 325 data := []byte("some-data") 326 uploader := UploaderFunc(func(upload UploadFn) error { 327 for _, name := range testDirFiles { 328 file := &File{ 329 ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), 330 ManifestEntry: api.ManifestEntry{ 331 Path: name, 332 ContentType: "text/plain", 333 Size: int64(len(data)), 334 }, 335 } 336 if err := upload(file); err != nil { 337 return err 338 } 339 } 340 return nil 341 }) 342 343 //以多部分上载方式上载文件 344 client := NewClient(srv.URL) 345 hash, err := client.MultipartUpload("", uploader) 346 if err != nil { 347 t.Fatal(err) 348 } 349 350 //检查我们是否可以下载单独的文件 351 checkDownloadFile := func(path string) { 352 file, err := client.Download(hash, path) 353 if err != nil { 354 t.Fatal(err) 355 } 356 defer file.Close() 357 gotData, err := ioutil.ReadAll(file) 358 if err != nil { 359 t.Fatal(err) 360 } 361 if !bytes.Equal(gotData, data) { 362 t.Fatalf("expected data to be %q, got %q", data, gotData) 363 } 364 } 365 for _, file := range testDirFiles { 366 checkDownloadFile(file) 367 } 368 } 369 370 func newTestSigner() (*mru.GenericSigner, error) { 371 privKey, err := crypto.HexToECDSA("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef") 372 if err != nil { 373 return nil, err 374 } 375 return mru.NewGenericSigner(privKey), nil 376 } 377 378 //使用bzz://scheme测试多哈希资源类型的透明解析 379 // 380 //首先上载数据,并将多哈希存储到资源更新中的结果清单中 381 //使用multihash检索更新时,应返回直接指向数据的清单。 382 //对散列的原始检索应该返回数据 383 func TestClientCreateResourceMultihash(t *testing.T) { 384 385 signer, _ := newTestSigner() 386 387 srv := testutil.NewTestSwarmServer(t, serverFunc) 388 client := NewClient(srv.URL) 389 defer srv.Close() 390 391 //添加我们的多哈希别名清单将指向的数据 392 databytes := []byte("bar") 393 394 swarmHash, err := client.UploadRaw(bytes.NewReader(databytes), int64(len(databytes)), false) 395 if err != nil { 396 t.Fatalf("Error uploading raw test data: %s", err) 397 } 398 399 s := common.FromHex(swarmHash) 400 mh := multihash.ToMultihash(s) 401 402 //我们的可变资源“名称” 403 resourceName := "foo.eth" 404 405 createRequest, err := mru.NewCreateUpdateRequest(&mru.ResourceMetadata{ 406 Name: resourceName, 407 Frequency: 13, 408 StartTime: srv.GetCurrentTime(), 409 Owner: signer.Address(), 410 }) 411 if err != nil { 412 t.Fatal(err) 413 } 414 createRequest.SetData(mh, true) 415 if err := createRequest.Sign(signer); err != nil { 416 t.Fatalf("Error signing update: %s", err) 417 } 418 419 resourceManifestHash, err := client.CreateResource(createRequest) 420 421 if err != nil { 422 t.Fatalf("Error creating resource: %s", err) 423 } 424 425 correctManifestAddrHex := "6d3bc4664c97d8b821cb74bcae43f592494fb46d2d9cd31e69f3c7c802bbbd8e" 426 if resourceManifestHash != correctManifestAddrHex { 427 t.Fatalf("Response resource key mismatch, expected '%s', got '%s'", correctManifestAddrHex, resourceManifestHash) 428 } 429 430 reader, err := client.GetResource(correctManifestAddrHex) 431 if err != nil { 432 t.Fatalf("Error retrieving resource: %s", err) 433 } 434 defer reader.Close() 435 gotData, err := ioutil.ReadAll(reader) 436 if err != nil { 437 t.Fatal(err) 438 } 439 if !bytes.Equal(mh, gotData) { 440 t.Fatalf("Expected: %v, got %v", mh, gotData) 441 } 442 443 } 444 445 //TestClientCreateUpdateResource将检查是否可以通过HTTP客户端创建和更新可变资源。 446 func TestClientCreateUpdateResource(t *testing.T) { 447 448 signer, _ := newTestSigner() 449 450 srv := testutil.NewTestSwarmServer(t, serverFunc) 451 client := NewClient(srv.URL) 452 defer srv.Close() 453 454 //设置资源的原始数据 455 databytes := []byte("En un lugar de La Mancha, de cuyo nombre no quiero acordarme...") 456 457 //我们的可变资源名称 458 resourceName := "El Quijote" 459 460 createRequest, err := mru.NewCreateUpdateRequest(&mru.ResourceMetadata{ 461 Name: resourceName, 462 Frequency: 13, 463 StartTime: srv.GetCurrentTime(), 464 Owner: signer.Address(), 465 }) 466 if err != nil { 467 t.Fatal(err) 468 } 469 createRequest.SetData(databytes, false) 470 if err := createRequest.Sign(signer); err != nil { 471 t.Fatalf("Error signing update: %s", err) 472 } 473 474 resourceManifestHash, err := client.CreateResource(createRequest) 475 476 correctManifestAddrHex := "cc7904c17b49f9679e2d8006fe25e87e3f5c2072c2b49cab50f15e544471b30a" 477 if resourceManifestHash != correctManifestAddrHex { 478 t.Fatalf("Response resource key mismatch, expected '%s', got '%s'", correctManifestAddrHex, resourceManifestHash) 479 } 480 481 reader, err := client.GetResource(correctManifestAddrHex) 482 if err != nil { 483 t.Fatalf("Error retrieving resource: %s", err) 484 } 485 defer reader.Close() 486 gotData, err := ioutil.ReadAll(reader) 487 if err != nil { 488 t.Fatal(err) 489 } 490 if !bytes.Equal(databytes, gotData) { 491 t.Fatalf("Expected: %v, got %v", databytes, gotData) 492 } 493 494 //定义不同的数据 495 databytes = []byte("... no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero ...") 496 497 updateRequest, err := client.GetResourceMetadata(correctManifestAddrHex) 498 if err != nil { 499 t.Fatalf("Error retrieving update request template: %s", err) 500 } 501 502 updateRequest.SetData(databytes, false) 503 if err := updateRequest.Sign(signer); err != nil { 504 t.Fatalf("Error signing update: %s", err) 505 } 506 507 if err = client.UpdateResource(updateRequest); err != nil { 508 t.Fatalf("Error updating resource: %s", err) 509 } 510 511 reader, err = client.GetResource(correctManifestAddrHex) 512 if err != nil { 513 t.Fatalf("Error retrieving resource: %s", err) 514 } 515 defer reader.Close() 516 gotData, err = ioutil.ReadAll(reader) 517 if err != nil { 518 t.Fatal(err) 519 } 520 if !bytes.Equal(databytes, gotData) { 521 t.Fatalf("Expected: %v, got %v", databytes, gotData) 522 } 523 524 }