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