github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:31</date>
    10  //</624342606624591872>
    11  
    12  
    13  package main
    14  
    15  import (
    16  	"bytes"
    17  	"flag"
    18  	"fmt"
    19  	"io"
    20  	"io/ioutil"
    21  	"net/http"
    22  	"os"
    23  	"path"
    24  	"path/filepath"
    25  	"strings"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/ethereum/go-ethereum/log"
    30  	swarm "github.com/ethereum/go-ethereum/swarm/api/client"
    31  	colorable "github.com/mattn/go-colorable"
    32  )
    33  
    34  var loglevel = flag.Int("loglevel", 3, "verbosity of logs")
    35  
    36  func init() {
    37  	log.PrintOrigins(true)
    38  	log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true))))
    39  }
    40  
    41  //testcliswarmup测试运行“swarm up”生成的文件
    42  //可通过HTTP API从所有节点获取
    43  func TestCLISwarmUp(t *testing.T) {
    44  	testCLISwarmUp(false, t)
    45  }
    46  func TestCLISwarmUpRecursive(t *testing.T) {
    47  	testCLISwarmUpRecursive(false, t)
    48  }
    49  
    50  //testcliswarmupencypted测试运行“swarm encrypted up”生成的文件
    51  //可通过HTTP API从所有节点获取
    52  func TestCLISwarmUpEncrypted(t *testing.T) {
    53  	testCLISwarmUp(true, t)
    54  }
    55  func TestCLISwarmUpEncryptedRecursive(t *testing.T) {
    56  	testCLISwarmUpRecursive(true, t)
    57  }
    58  
    59  func testCLISwarmUp(toEncrypt bool, t *testing.T) {
    60  	log.Info("starting 3 node cluster")
    61  	cluster := newTestCluster(t, 3)
    62  	defer cluster.Shutdown()
    63  
    64  //创建tmp文件
    65  	tmp, err := ioutil.TempFile("", "swarm-test")
    66  	if err != nil {
    67  		t.Fatal(err)
    68  	}
    69  	defer tmp.Close()
    70  	defer os.Remove(tmp.Name())
    71  
    72  //将数据写入文件
    73  	data := "notsorandomdata"
    74  	_, err = io.WriteString(tmp, data)
    75  	if err != nil {
    76  		t.Fatal(err)
    77  	}
    78  
    79  	hashRegexp := `[a-f\d]{64}`
    80  	flags := []string{
    81  		"--bzzapi", cluster.Nodes[0].URL,
    82  		"up",
    83  		tmp.Name()}
    84  	if toEncrypt {
    85  		hashRegexp = `[a-f\d]{128}`
    86  		flags = []string{
    87  			"--bzzapi", cluster.Nodes[0].URL,
    88  			"up",
    89  			"--encrypt",
    90  			tmp.Name()}
    91  	}
    92  //用“swarm up”上传文件,并期望得到一个哈希值
    93  	log.Info(fmt.Sprintf("uploading file with 'swarm up'"))
    94  	up := runSwarm(t, flags...)
    95  	_, matches := up.ExpectRegexp(hashRegexp)
    96  	up.ExpectExit()
    97  	hash := matches[0]
    98  	log.Info("file uploaded", "hash", hash)
    99  
   100  //从每个节点的HTTP API获取文件
   101  	for _, node := range cluster.Nodes {
   102  		log.Info("getting file from node", "node", node.Name)
   103  
   104  		res, err := http.Get(node.URL + "/bzz:/" + hash)
   105  		if err != nil {
   106  			t.Fatal(err)
   107  		}
   108  		defer res.Body.Close()
   109  
   110  		reply, err := ioutil.ReadAll(res.Body)
   111  		if err != nil {
   112  			t.Fatal(err)
   113  		}
   114  		if res.StatusCode != 200 {
   115  			t.Fatalf("expected HTTP status 200, got %s", res.Status)
   116  		}
   117  		if string(reply) != data {
   118  			t.Fatalf("expected HTTP body %q, got %q", data, reply)
   119  		}
   120  		log.Debug("verifying uploaded file using `swarm down`")
   121  //试着用“蜂群下降”来获取内容
   122  		tmpDownload, err := ioutil.TempDir("", "swarm-test")
   123  		tmpDownload = path.Join(tmpDownload, "tmpfile.tmp")
   124  		if err != nil {
   125  			t.Fatal(err)
   126  		}
   127  		defer os.RemoveAll(tmpDownload)
   128  
   129  		bzzLocator := "bzz:/" + hash
   130  		flags = []string{
   131  			"--bzzapi", cluster.Nodes[0].URL,
   132  			"down",
   133  			bzzLocator,
   134  			tmpDownload,
   135  		}
   136  
   137  		down := runSwarm(t, flags...)
   138  		down.ExpectExit()
   139  
   140  		fi, err := os.Stat(tmpDownload)
   141  		if err != nil {
   142  			t.Fatalf("could not stat path: %v", err)
   143  		}
   144  
   145  		switch mode := fi.Mode(); {
   146  		case mode.IsRegular():
   147  			downloadedBytes, err := ioutil.ReadFile(tmpDownload)
   148  			if err != nil {
   149  				t.Fatalf("had an error reading the downloaded file: %v", err)
   150  			}
   151  			if !bytes.Equal(downloadedBytes, bytes.NewBufferString(data).Bytes()) {
   152  				t.Fatalf("retrieved data and posted data not equal!")
   153  			}
   154  
   155  		default:
   156  			t.Fatalf("expected to download regular file, got %s", fi.Mode())
   157  		}
   158  	}
   159  
   160  	timeout := time.Duration(2 * time.Second)
   161  	httpClient := http.Client{
   162  		Timeout: timeout,
   163  	}
   164  
   165  //
   166  	for _, node := range cluster.Nodes {
   167  		_, err := httpClient.Get(node.URL + "/bzz:/1023e8bae0f70be7d7b5f74343088ba408a218254391490c85ae16278e230340")
   168  //由于NetStore在请求时有60秒的超时时间,我们正在加快超时时间。
   169  		if err != nil && !strings.Contains(err.Error(), "Client.Timeout exceeded while awaiting headers") {
   170  			t.Fatal(err)
   171  		}
   172  //由于NetStore超时需要60秒,因此此选项被禁用。
   173  //
   174  //t.fatalf(“预期的HTTP状态404,得到%s”,res.status)
   175  //
   176  	}
   177  }
   178  
   179  func testCLISwarmUpRecursive(toEncrypt bool, t *testing.T) {
   180  	fmt.Println("starting 3 node cluster")
   181  	cluster := newTestCluster(t, 3)
   182  	defer cluster.Shutdown()
   183  
   184  	tmpUploadDir, err := ioutil.TempDir("", "swarm-test")
   185  	if err != nil {
   186  		t.Fatal(err)
   187  	}
   188  	defer os.RemoveAll(tmpUploadDir)
   189  //
   190  	data := "notsorandomdata"
   191  	for _, path := range []string{"tmp1", "tmp2"} {
   192  		if err := ioutil.WriteFile(filepath.Join(tmpUploadDir, path), bytes.NewBufferString(data).Bytes(), 0644); err != nil {
   193  			t.Fatal(err)
   194  		}
   195  	}
   196  
   197  	hashRegexp := `[a-f\d]{64}`
   198  	flags := []string{
   199  		"--bzzapi", cluster.Nodes[0].URL,
   200  		"--recursive",
   201  		"up",
   202  		tmpUploadDir}
   203  	if toEncrypt {
   204  		hashRegexp = `[a-f\d]{128}`
   205  		flags = []string{
   206  			"--bzzapi", cluster.Nodes[0].URL,
   207  			"--recursive",
   208  			"up",
   209  			"--encrypt",
   210  			tmpUploadDir}
   211  	}
   212  //用“swarm up”上传文件,并期望得到一个哈希值
   213  	log.Info(fmt.Sprintf("uploading file with 'swarm up'"))
   214  	up := runSwarm(t, flags...)
   215  	_, matches := up.ExpectRegexp(hashRegexp)
   216  	up.ExpectExit()
   217  	hash := matches[0]
   218  	log.Info("dir uploaded", "hash", hash)
   219  
   220  //从每个节点的HTTP API获取文件
   221  	for _, node := range cluster.Nodes {
   222  		log.Info("getting file from node", "node", node.Name)
   223  //试着用“蜂群下降”来获取内容
   224  		tmpDownload, err := ioutil.TempDir("", "swarm-test")
   225  		if err != nil {
   226  			t.Fatal(err)
   227  		}
   228  		defer os.RemoveAll(tmpDownload)
   229  		bzzLocator := "bzz:/" + hash
   230  		flagss := []string{}
   231  		flagss = []string{
   232  			"--bzzapi", cluster.Nodes[0].URL,
   233  			"down",
   234  			"--recursive",
   235  			bzzLocator,
   236  			tmpDownload,
   237  		}
   238  
   239  		fmt.Println("downloading from swarm with recursive")
   240  		down := runSwarm(t, flagss...)
   241  		down.ExpectExit()
   242  
   243  		files, err := ioutil.ReadDir(tmpDownload)
   244  		for _, v := range files {
   245  			fi, err := os.Stat(path.Join(tmpDownload, v.Name()))
   246  			if err != nil {
   247  				t.Fatalf("got an error: %v", err)
   248  			}
   249  
   250  			switch mode := fi.Mode(); {
   251  			case mode.IsRegular():
   252  				if file, err := swarm.Open(path.Join(tmpDownload, v.Name())); err != nil {
   253  					t.Fatalf("encountered an error opening the file returned from the CLI: %v", err)
   254  				} else {
   255  					ff := make([]byte, len(data))
   256  					io.ReadFull(file, ff)
   257  					buf := bytes.NewBufferString(data)
   258  
   259  					if !bytes.Equal(ff, buf.Bytes()) {
   260  						t.Fatalf("retrieved data and posted data not equal!")
   261  					}
   262  				}
   263  			default:
   264  				t.Fatalf("this shouldnt happen")
   265  			}
   266  		}
   267  		if err != nil {
   268  			t.Fatalf("could not list files at: %v", files)
   269  		}
   270  	}
   271  }
   272  
   273  //
   274  //默认路径和加密。
   275  func TestCLISwarmUpDefaultPath(t *testing.T) {
   276  	testCLISwarmUpDefaultPath(false, false, t)
   277  	testCLISwarmUpDefaultPath(false, true, t)
   278  	testCLISwarmUpDefaultPath(true, false, t)
   279  	testCLISwarmUpDefaultPath(true, true, t)
   280  }
   281  
   282  func testCLISwarmUpDefaultPath(toEncrypt bool, absDefaultPath bool, t *testing.T) {
   283  	cluster := newTestCluster(t, 1)
   284  	defer cluster.Shutdown()
   285  
   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 := swarm.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