Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stat collection to IPTB #65

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
*.so
iptb
.vscode
topologies/*
deb.sh
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .vscode I think is fine, but I don't think we need the other two.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ libp2p networks easy!
### Example

```
$ iptb auto -count 5 >/dev/null
$ iptb auto -count 5 -type <plugin_name>

$ iptb start

Expand All @@ -26,7 +26,7 @@ $ iptb shell 4
$ ipfs cat QmNqugRcYjwh9pEQUK7MLuxvLjxDNZL1DH8PJJgWtQXxuF
hey!
```

Available plugins now: Local IPFS node (plugin_name: localipfs), Docker IPFS node (plugin_name: dockeripfs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also be nice to be able to list available plugins via the CLI. Doesn't have to be in this PR though, just mentioning.

### Usage
```
NAME:
Expand Down
6 changes: 3 additions & 3 deletions commands/auto.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ $ iptb auto -count 5 -type <type>
Action: func(c *cli.Context) error {
flagRoot := c.GlobalString("IPTB_ROOT")
flagTestbed := c.GlobalString("testbed")
flagEncoding := c.GlobalString("encoding")
flagType := c.String("type")
flagStart := c.Bool("start")
flagCount := c.Int("count")
flagForce := c.Bool("force")

tb := testbed.NewTestbed(path.Join(flagRoot, "testbeds", flagTestbed))

if err := testbed.AlreadyInitCheck(tb.Dir(), flagForce); err != nil {
return err
}
Expand Down Expand Up @@ -89,7 +89,7 @@ $ iptb auto -count 5 -type <type>
return err
}

if err := buildReport(results); err != nil {
if err := buildReport(results, flagEncoding); err != nil {
return err
}

Expand All @@ -103,7 +103,7 @@ $ iptb auto -count 5 -type <type>
return err
}

if err := buildReport(results); err != nil {
if err := buildReport(results, flagEncoding); err != nil {
return err
}
}
Expand Down
39 changes: 24 additions & 15 deletions commands/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ Every node listed in the first set, will try to connect to every node
listed in the second set.

There are three variants of the command. It can accept no arugments,
a single argument, or two arguments. The no argument and single argument
expands out to the two argument usage.

a single argument, two arguments. The no argument and single argument
expands out to the two argument usage
$ iptb connect => iptb connect [0-C] [0-C]
$ iptb connect [n-m] => iptb connect [n-m] [n-m]
$ iptb connect [n-m] [i-k]
Expand All @@ -51,16 +50,19 @@ INPUT EXPANDED
Action: func(c *cli.Context) error {
flagRoot := c.GlobalString("IPTB_ROOT")
flagTestbed := c.GlobalString("testbed")
flagEncoding := c.GlobalString("encoding")

flagTimeout := c.String("timeout")

timeout, err := time.ParseDuration(flagTimeout)
if err != nil {
return err
}

tb := testbed.NewTestbed(path.Join(flagRoot, "testbeds", flagTestbed))
args := c.Args()

var results []Result
// Case range is specified
args := c.Args()
switch c.NArg() {
case 0:
nodes, err := tb.Nodes()
Expand All @@ -73,14 +75,19 @@ INPUT EXPANDED
return err
}

return connectNodes(tb, fromto, fromto, timeout)
results, err = connectNodes(tb, fromto, fromto, timeout)
if err != nil {
return err
}
case 1:
fromto, err := parseRange(args[0])
if err != nil {
return err
}

return connectNodes(tb, fromto, fromto, timeout)
results, err = connectNodes(tb, fromto, fromto, timeout)
if err != nil {
return err
}
case 2:
from, err := parseRange(args[0])
if err != nil {
Expand All @@ -91,21 +98,23 @@ INPUT EXPANDED
if err != nil {
return err
}

return connectNodes(tb, from, to, timeout)
results, err = connectNodes(tb, from, to, timeout)
if err != nil {
return err
}
default:
return NewUsageError("connet accepts between 0 and 2 arguments")
}
return buildReport(results, flagEncoding)
},
}

func connectNodes(tb testbed.BasicTestbed, from, to []int, timeout time.Duration) error {
func connectNodes(tb testbed.BasicTestbed, from, to []int, timeout time.Duration) ([]Result, error) {
var results []Result
nodes, err := tb.Nodes()
if err != nil {
return err
return results, err
}

var results []Result
for _, f := range from {
for _, t := range to {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
Expand All @@ -121,5 +130,5 @@ func connectNodes(tb testbed.BasicTestbed, from, to []int, timeout time.Duration
}
}

return buildReport(results)
return results, nil
}
3 changes: 2 additions & 1 deletion commands/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ var InitCmd = cli.Command{
Action: func(c *cli.Context) error {
flagRoot := c.GlobalString("IPTB_ROOT")
flagTestbed := c.GlobalString("testbed")
flagEncoding := c.GlobalString("encoding")

tb := testbed.NewTestbed(path.Join(flagRoot, "testbeds", flagTestbed))
nodes, err := tb.Nodes()
Expand Down Expand Up @@ -59,6 +60,6 @@ var InitCmd = cli.Command{
return err
}

return buildReport(results)
return buildReport(results, flagEncoding)
},
}
3 changes: 2 additions & 1 deletion commands/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var LogsCmd = cli.Command{
Action: func(c *cli.Context) error {
flagRoot := c.GlobalString("IPTB_ROOT")
flagTestbed := c.GlobalString("testbed")
flagEncoding := c.GlobalString("encoding")
flagErr := c.BoolT("err")
flagOut := c.BoolT("out")

Expand Down Expand Up @@ -84,7 +85,7 @@ var LogsCmd = cli.Command{
return err
}

return buildReport(results)
return buildReport(results, flagEncoding)
},
}

Expand Down
3 changes: 2 additions & 1 deletion commands/restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var RestartCmd = cli.Command{
Action: func(c *cli.Context) error {
flagRoot := c.GlobalString("IPTB_ROOT")
flagTestbed := c.GlobalString("testbed")
flagEncoding := c.GlobalString("encoding")
flagWait := c.Bool("wait")

tb := testbed.NewTestbed(path.Join(flagRoot, "testbeds", flagTestbed))
Expand Down Expand Up @@ -68,6 +69,6 @@ var RestartCmd = cli.Command{
return err
}

return buildReport(results)
return buildReport(results, flagEncoding)
},
}
4 changes: 2 additions & 2 deletions commands/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ var RunCmd = cli.Command{
if present := isTerminatorPresent(c); present {
return c.Set("terminator", "true")
}

return nil
},
Action: func(c *cli.Context) error {
flagRoot := c.GlobalString("IPTB_ROOT")
flagTestbed := c.GlobalString("testbed")
flagEncoding := c.GlobalString("encoding")

tb := testbed.NewTestbed(path.Join(flagRoot, "testbeds", flagTestbed))
nodes, err := tb.Nodes()
Expand Down Expand Up @@ -59,6 +59,6 @@ var RunCmd = cli.Command{
return err
}

return buildReport(results)
return buildReport(results, flagEncoding)
},
}
3 changes: 2 additions & 1 deletion commands/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var StartCmd = cli.Command{
Action: func(c *cli.Context) error {
flagRoot := c.GlobalString("IPTB_ROOT")
flagTestbed := c.GlobalString("testbed")
flagEncoding := c.GlobalString("encoding")
flagWait := c.Bool("wait")

tb := testbed.NewTestbed(path.Join(flagRoot, "testbeds", flagTestbed))
Expand Down Expand Up @@ -64,6 +65,6 @@ var StartCmd = cli.Command{
return err
}

return buildReport(results)
return buildReport(results, flagEncoding)
},
}
3 changes: 2 additions & 1 deletion commands/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var StopCmd = cli.Command{
Action: func(c *cli.Context) error {
flagRoot := c.GlobalString("IPTB_ROOT")
flagTestbed := c.GlobalString("testbed")
flagEncoding := c.GlobalString("encoding")

tb := testbed.NewTestbed(path.Join(flagRoot, "testbeds", flagTestbed))
nodes, err := tb.Nodes()
Expand Down Expand Up @@ -46,6 +47,6 @@ var StopCmd = cli.Command{
return err
}

return buildReport(results)
return buildReport(results, flagEncoding)
},
}
81 changes: 62 additions & 19 deletions commands/utils.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package commands

import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"strconv"
"strings"
"sync"
"time"

"github.com/pkg/errors"
cli "github.com/urfave/cli"
Expand Down Expand Up @@ -121,9 +124,19 @@ func expandDashRange(s string) ([]int, error) {
}

type Result struct {
Node int
Output testbedi.Output
Error error
Node int
Output testbedi.Output
Error error
Elapsed time.Duration
}

type output struct {
Node int
ExitCode int
Error error
PluginStdout string
PluginStderr string
Elapsed float64
}

type outputFunc func(testbedi.Core) (testbedi.Output, error)
Expand All @@ -141,15 +154,17 @@ func mapWithOutput(list []int, nodes []testbedi.Core, fn outputFunc) ([]Result,
wg.Add(1)
go func(i, n int, node testbedi.Core) {
defer wg.Done()
start := time.Now()
out, err := fn(node)

elapsed := time.Since(start)
lk.Lock()
defer lk.Unlock()

results[i] = Result{
Node: n,
Output: out,
Error: errors.Wrapf(err, "node[%d]", n),
Node: n,
Output: out,
Error: errors.Wrapf(err, "node[%d]", n),
Elapsed: elapsed,
}
}(i, n, nodes[n])
}
Expand All @@ -175,7 +190,7 @@ func validRange(list []int, total int) error {
return nil
}

func buildReport(results []Result) error {
func buildReport(results []Result, encoding string) error {
var errs []error

for _, rs := range results {
Expand All @@ -184,21 +199,49 @@ func buildReport(results []Result) error {
}

if rs.Output != nil {
fmt.Printf("node[%d] exit %d\n", rs.Node, rs.Output.ExitCode())
if rs.Output.Error() != nil {
fmt.Printf("%s", rs.Output.Error())
if encoding == "text" {
fmt.Printf("node[%d] exit %d elapsed %s\n", rs.Node, rs.Output.ExitCode(), rs.Elapsed)
if rs.Output.Error() != nil {
fmt.Printf("%s", rs.Output.Error())
}
fmt.Println()
io.Copy(os.Stdout, rs.Output.Stdout())
io.Copy(os.Stdout, rs.Output.Stderr())
} else {
// Transform plugin stdout to string
pluginOutB, err := ioutil.ReadAll(rs.Output.Stdout())
if err != nil {
errs = append(errs, err)
}
pluginOut := string(pluginOutB)
// Transform plugin stderr to string
pluginErrB, err := ioutil.ReadAll(rs.Output.Stderr())
if err != nil {
errs = append(errs, err)
}
pluginErr := string(pluginErrB)
// JSONify the plugin output
rsJSON, err := json.Marshal(output{
Node: rs.Node,
ExitCode: rs.Output.ExitCode(),
Error: rs.Output.Error(),
PluginStdout: pluginOut,
PluginStderr: pluginErr,
Elapsed: rs.Elapsed.Seconds(),
})

if err != nil {
errs = append(errs, err)
}
fmt.Printf("%s\n", rsJSON)
}

fmt.Println()

io.Copy(os.Stdout, rs.Output.Stdout())
io.Copy(os.Stdout, rs.Output.Stderr())

fmt.Println()
}

}

// Add an empty line between the commands if the encoding is not human readable
if encoding != "text" {
fmt.Println()
}
if len(errs) != 0 {
return cli.NewMultiError(errs...)
}
Expand Down
Loading