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