From 765bc18cf837d85de8ea76bc8850e7874680ff7a Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Thu, 29 Mar 2018 20:43:22 +0200 Subject: [PATCH] cmd/swarm: very hacky export/import test --- cmd/swarm/export_test.go | 114 ++++++++++++++++++++++++++++++++++++++ cmd/swarm/run_test.go | 117 +++++++++++++++++++++++++++++++++++---- common/bytes.go | 7 ++- 3 files changed, 224 insertions(+), 14 deletions(-) create mode 100644 cmd/swarm/export_test.go diff --git a/cmd/swarm/export_test.go b/cmd/swarm/export_test.go new file mode 100644 index 0000000000..b60dbb575f --- /dev/null +++ b/cmd/swarm/export_test.go @@ -0,0 +1,114 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "crypto/rand" + "fmt" + "io/ioutil" + "net/http" + "os" + "testing" + + "github.com/davecgh/go-spew/spew" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm" +) + +func TestCLISwarmExport(t *testing.T) { + cluster := newTestCluster(t, 1) + defer cluster.Cleanup() + + // create a tmp file + tmp, err := ioutil.TempFile("", "swarm-test") + if err != nil { + t.Fatal(err) + } + defer tmp.Close() + defer os.Remove(tmp.Name()) + + // write 10mb random data to file + buf := make([]byte, 10000000) + _, err = rand.Read(buf) + if err != nil { + panic(err) + } + ioutil.WriteFile(tmp.Name(), buf, 0755) + + // upload the file with 'swarm up' and expect a hash + log.Info("uploading file with 'swarm up'") + up := runSwarm(t, "--bzzapi", cluster.Nodes[0].URL, "up", tmp.Name()) + _, matches := up.ExpectRegexp(`[a-f\d]{64}`) + up.ExpectExit() + hash := matches[0] + log.Info("file uploaded", "hash", hash) + + var info swarm.Info + if err := cluster.Nodes[0].Client.Call(&info, "bzz_info"); err != nil { + t.Fatal(err) + } + + spew.Dump(info) + + spew.Dump(cluster.TmpDir) + spew.Dump(cluster.Nodes[0].Name) + spew.Dump(cluster.Nodes[0].Addr) + spew.Dump(cluster.Nodes[0].URL) + spew.Dump(cluster.Nodes[0].Enode) + spew.Dump(cluster.Nodes[0].Dir) + + cluster.Stop() + defer cluster.Cleanup() + + file, err := ioutil.TempFile("", "swarm-test") + if err != nil { + t.Fatal(err) + } + defer file.Close() + defer os.Remove(file.Name()) + + fmt.Println("==================================") + + spew.Dump(info.BzzKey[2:]) + up2 := runSwarm(t, "db", "export", info.Path+"/chunks", file.Name(), info.BzzKey[2:]) + up2.ExpectExit() + + cluster2 := newTestCluster(t, 1) + + var info2 swarm.Info + if err := cluster2.Nodes[0].Client.Call(&info2, "bzz_info"); err != nil { + t.Fatal(err) + } + + cluster2.Stop() + defer cluster2.Cleanup() + + spew.Dump(info2.BzzKey[2:]) + up3 := runSwarm(t, "db", "import", info2.Path+"/chunks", file.Name(), info2.BzzKey[2:]) + up3.ExpectExit() + + cluster2.StartExistingNodes(t, 1, info2.BzzAccount[2:]) + + res, err := http.Get(cluster2.Nodes[0].URL + "/bzz:/" + hash) + if err != nil { + t.Fatal(err) + } + + if res.StatusCode != 200 { + t.Fatalf("expected HTTP status %d, got %s", 200, res.Status) + } +} diff --git a/cmd/swarm/run_test.go b/cmd/swarm/run_test.go index 594cfa55cb..26f1260b30 100644 --- a/cmd/swarm/run_test.go +++ b/cmd/swarm/run_test.go @@ -81,6 +81,7 @@ type testCluster struct { // // When starting more than one node, they are connected together using the // admin SetPeer RPC method. + func newTestCluster(t *testing.T, size int) *testCluster { cluster := &testCluster{} defer func() { @@ -96,18 +97,7 @@ func newTestCluster(t *testing.T, size int) *testCluster { cluster.TmpDir = tmpdir // start the nodes - cluster.Nodes = make([]*testNode, 0, size) - for i := 0; i < size; i++ { - dir := filepath.Join(cluster.TmpDir, fmt.Sprintf("swarm%02d", i)) - if err := os.Mkdir(dir, 0700); err != nil { - t.Fatal(err) - } - - node := newTestNode(t, dir) - node.Name = fmt.Sprintf("swarm%02d", i) - - cluster.Nodes = append(cluster.Nodes, node) - } + cluster.StartNewNodes(t, size) if size == 1 { return cluster @@ -145,6 +135,42 @@ func (c *testCluster) Shutdown() { os.RemoveAll(c.TmpDir) } +func (c *testCluster) Stop() { + for _, node := range c.Nodes { + node.Shutdown() + } +} + +func (c *testCluster) StartNewNodes(t *testing.T, size int) { + c.Nodes = make([]*testNode, 0, size) + for i := 0; i < size; i++ { + dir := filepath.Join(c.TmpDir, fmt.Sprintf("swarm%02d", i)) + if err := os.Mkdir(dir, 0700); err != nil { + t.Fatal(err) + } + + node := newTestNode(t, dir) + node.Name = fmt.Sprintf("swarm%02d", i) + + c.Nodes = append(c.Nodes, node) + } +} + +func (c *testCluster) StartExistingNodes(t *testing.T, size int, bzzaccount string) { + c.Nodes = make([]*testNode, 0, size) + for i := 0; i < size; i++ { + dir := filepath.Join(c.TmpDir, fmt.Sprintf("swarm%02d", i)) + node := existingTestNode(t, dir, bzzaccount) + node.Name = fmt.Sprintf("swarm%02d", i) + + c.Nodes = append(c.Nodes, node) + } +} + +func (c *testCluster) Cleanup() { + os.RemoveAll(c.TmpDir) +} + type testNode struct { Name string Addr string @@ -181,6 +207,73 @@ func getTestAccount(t *testing.T, dir string) (conf *node.Config, account accoun return conf, account } +func existingTestNode(t *testing.T, dir string, bzzaccount string) *testNode { + + conf, _ := getTestAccount(t, dir) + node := &testNode{Dir: dir} + + // use a unique IPCPath when running tests on Windows + if runtime.GOOS == "windows" { + conf.IPCPath = fmt.Sprintf("bzzd-%s.ipc", bzzaccount) + } + + // assign ports + httpPort, err := assignTCPPort() + if err != nil { + t.Fatal(err) + } + p2pPort, err := assignTCPPort() + if err != nil { + t.Fatal(err) + } + + // start the node + node.Cmd = runSwarm(t, + "--port", p2pPort, + "--nodiscover", + "--datadir", dir, + "--ipcpath", conf.IPCPath, + "--ens-api", "", + "--bzzaccount", bzzaccount, + "--bzznetworkid", "321", + "--bzzport", httpPort, + "--verbosity", "6", + ) + node.Cmd.InputLine(testPassphrase) + defer func() { + if t.Failed() { + node.Shutdown() + } + }() + + // wait for the node to start + for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) { + node.Client, err = rpc.Dial(conf.IPCEndpoint()) + if err == nil { + break + } + } + if node.Client == nil { + t.Fatal(err) + } + + // load info + var info swarm.Info + if err := node.Client.Call(&info, "bzz_info"); err != nil { + t.Fatal(err) + } + node.Addr = net.JoinHostPort("127.0.0.1", info.Port) + node.URL = "http://" + node.Addr + + var nodeInfo p2p.NodeInfo + if err := node.Client.Call(&nodeInfo, "admin_nodeInfo"); err != nil { + t.Fatal(err) + } + node.Enode = fmt.Sprintf("enode://%s@127.0.0.1:%s", nodeInfo.ID, p2pPort) + + return node +} + func newTestNode(t *testing.T, dir string) *testNode { conf, account := getTestAccount(t, dir) diff --git a/common/bytes.go b/common/bytes.go index f3e6aacf41..b9fd61a040 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -17,7 +17,10 @@ // Package common contains various helper functions. package common -import "encoding/hex" +import ( + "encoding/hex" + "fmt" +) func ToHex(b []byte) string { hex := Bytes2Hex(b) @@ -80,7 +83,7 @@ func Bytes2Hex(d []byte) string { func Hex2Bytes(str string) []byte { h, err := hex.DecodeString(str) if err != nil { - panic(err) + panic(fmt.Sprintf("cannot hex decode the string %s, got error %v", str, err)) } return h