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  }