From 8c59200edee15f1ca711eb68be45791cd5565177 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Mon, 5 Oct 2015 20:52:14 -0700 Subject: [PATCH] WIP: sharness iptb test License: MIT Signed-off-by: Jeromy --- test/dependencies/iptb/main.go | 106 +++++++++++++++++++++++++++---- test/sharness/t0130-multinode.sh | 88 +++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 14 deletions(-) create mode 100755 test/sharness/t0130-multinode.sh diff --git a/test/dependencies/iptb/main.go b/test/dependencies/iptb/main.go index 013c46f8ef21..3a038ed72f6f 100644 --- a/test/dependencies/iptb/main.go +++ b/test/dependencies/iptb/main.go @@ -16,11 +16,11 @@ import ( "syscall" "time" - kingpin "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/alecthomas/kingpin" + kingpin "github.com/alecthomas/kingpin" serial "github.com/ipfs/go-ipfs/repo/fsrepo/serialize" - ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" - manet "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net" + manet "github.com/jbenet/go-multiaddr-net" + ma "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" ) // GetNumNodes returns the number of testbed nodes configured in the testbed directory @@ -73,13 +73,19 @@ type initCfg struct { Bootstrap string PortStart int Mdns bool + Utp bool } func (c *initCfg) swarmAddrForPeer(i int) string { + str := "/ip4/0.0.0.0/tcp/%d" + if c.Utp { + str = "/ip4/0.0.0.0/udp/%d/utp" + } + if c.PortStart == 0 { - return "/ip4/0.0.0.0/tcp/0" + return fmt.Sprintf(str, 0) } - return fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", c.PortStart+i) + return fmt.Sprintf(str, c.PortStart+i) } func (c *initCfg) apiAddrForPeer(i int) string { @@ -250,6 +256,20 @@ func IpfsKillAll() error { return nil } +func envForDaemon(n int) []string { + envs := os.Environ() + npath := "IPFS_PATH=" + IpfsDirN(n) + for i, e := range envs { + p := strings.Split(e, "=") + if p[0] == "IPFS_PATH" { + envs[i] = npath + return envs + } + } + + return append(envs, npath) +} + func IpfsStart(waitall bool) error { var addrs []string n := GetNumNodes() @@ -257,7 +277,7 @@ func IpfsStart(waitall bool) error { dir := IpfsDirN(i) cmd := exec.Command("ipfs", "daemon") cmd.Dir = dir - cmd.Env = append(os.Environ(), "IPFS_PATH="+dir) + cmd.Env = envForDaemon(i) cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true} @@ -441,6 +461,11 @@ func IpfsShell(n int) error { } func ConnectNodes(from, to int) error { + if from == to { + // skip connecting to self.. + return nil + } + fmt.Printf("connecting %d -> %d\n", from, to) cmd := exec.Command("ipfs", "id", "-f", "") cmd.Env = []string{"IPFS_PATH=" + IpfsDirN(to)} out, err := cmd.Output() @@ -449,7 +474,6 @@ func ConnectNodes(from, to int) error { return err } addr := strings.Split(string(out), "\n")[0] - fmt.Println("ADDR: ", addr) connectcmd := exec.Command("ipfs", "swarm", "connect", addr) connectcmd.Env = []string{"IPFS_PATH=" + IpfsDirN(from)} @@ -461,6 +485,55 @@ func ConnectNodes(from, to int) error { return nil } +func parseRange(s string) ([]int, error) { + if strings.HasPrefix(s, "[") && strings.HasSuffix(s, "]") { + ranges := strings.Split(s[1:len(s)-1], ",") + var out []int + for _, r := range ranges { + rng, err := expandDashRange(r) + if err != nil { + return nil, err + } + + out = append(out, rng...) + } + return out, nil + } else { + i, err := strconv.Atoi(s) + if err != nil { + return nil, err + } + + return []int{i}, nil + } +} + +func expandDashRange(s string) ([]int, error) { + parts := strings.Split(s, "-") + if len(parts) == 0 { + i, err := strconv.Atoi(s) + if err != nil { + return nil, err + } + return []int{i}, nil + } + low, err := strconv.Atoi(parts[0]) + if err != nil { + return nil, err + } + + hi, err := strconv.Atoi(parts[1]) + if err != nil { + return nil, err + } + + var out []int + for i := low; i <= hi; i++ { + out = append(out, i) + } + return out, nil +} + func GetAttr(attr string, node int) (string, error) { switch attr { case "id": @@ -518,9 +591,10 @@ func main() { cfg := new(initCfg) kingpin.Flag("n", "number of ipfs nodes to initialize").Short('n').IntVar(&cfg.Count) kingpin.Flag("port", "port to start allocations from").Default("4002").Short('p').IntVar(&cfg.PortStart) - kingpin.Flag("f", "force initialization (overwrite existing configs)").BoolVar(&cfg.Force) + kingpin.Flag("force", "force initialization (overwrite existing configs)").Short('f').BoolVar(&cfg.Force) kingpin.Flag("mdns", "turn on mdns for nodes").BoolVar(&cfg.Mdns) kingpin.Flag("bootstrap", "select bootstrapping style for cluster").Default("star").StringVar(&cfg.Bootstrap) + kingpin.Flag("utp", "use utp for addresses").BoolVar(&cfg.Utp) wait := kingpin.Flag("wait", "wait for nodes to come fully online before exiting").Bool() @@ -576,22 +650,26 @@ func main() { os.Exit(1) } - from, err := strconv.Atoi(args[1]) + from, err := parseRange(args[1]) if err != nil { fmt.Printf("failed to parse: %s\n", err) return } - to, err := strconv.Atoi(args[2]) + to, err := parseRange(args[2]) if err != nil { fmt.Printf("failed to parse: %s\n", err) return } - err = ConnectNodes(from, to) - if err != nil { - fmt.Printf("failed to connect: %s\n", err) - return + for _, f := range from { + for _, t := range to { + err = ConnectNodes(f, t) + if err != nil { + fmt.Printf("failed to connect: %s\n", err) + return + } + } } case "get": diff --git a/test/sharness/t0130-multinode.sh b/test/sharness/t0130-multinode.sh new file mode 100755 index 000000000000..1349efbbd637 --- /dev/null +++ b/test/sharness/t0130-multinode.sh @@ -0,0 +1,88 @@ +#!/bin/sh +# +# Copyright (c) 2015 Jeromy Johnson +# MIT Licensed; see the LICENSE file in this repository. +# + +test_description="Test multiple ipfs nodes" + +. lib/test-lib.sh + +export IPTB_ROOT="`pwd`/.iptb" + +ipfsi() { + dir="$1" + shift + IPFS_PATH="$IPTB_ROOT/$dir" ipfs $@ +} + +check_has_connection() { + node=$1 + ipfsi $node swarm peers | grep ipfs > /dev/null +} + +startup_cluster() { + test_expect_success "start up nodes" ' + iptb start + ' + + test_expect_success "connect nodes to eachother" ' + # todo: find out why it fails when you do "[1-4] 0" + iptb connect [0-4] [0-4] + ' + + test_expect_success "nodes are connected" ' + check_has_connection 0 && + check_has_connection 1 && + check_has_connection 2 && + check_has_connection 3 && + check_has_connection 4 + ' +} + +check_file_fetch() { + node=$1 + fhash=$2 + fname=$3 + + test_expect_success "can fetch file" ' + ipfsi $node cat $fhash > fetch_out + ' + + test_expect_success "file looks good" ' + test_cmp $fname fetch_out + ' +} + +run_basic_test() { + startup_cluster + + test_expect_success "add a file on node1" ' + random 1000000 > filea && + FILEA_HASH=$(ipfsi 1 add -q filea) + ' + + check_file_fetch 0 $FILEA_HASH filea + check_file_fetch 1 $FILEA_HASH filea + check_file_fetch 2 $FILEA_HASH filea + check_file_fetch 3 $FILEA_HASH filea + check_file_fetch 4 $FILEA_HASH filea + + test_expect_success "shut down nodes" ' + iptb stop + ' +} + +test_expect_success "set up tcp testbed" ' + iptb init -n 5 -p 0 -f --bootstrap=none +' + +run_basic_test + +test_expect_success "set up utp testbed" ' + iptb init -n 5 -p 0 -f --bootstrap=none --utp +' + +run_basic_test + +test_done