diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index abd6818d3..6c4e996be 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -244,6 +244,7 @@ func daemonFunc(req cmds.Request, res cmds.Response) { corehttp.CommandsOption(*req.Context()), corehttp.WebUIOption, gateway.ServeOption(), + corehttp.VersionOption(), } if rootRedirect != nil { opts = append(opts, rootRedirect) diff --git a/test/Makefile b/test/Makefile index 52f18d210..868eac731 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,9 +1,10 @@ -BINS = bin/random bin/multihash bin/ipfs +BINS = bin/random bin/multihash bin/ipfs bin/pollEndpoint IPFS_ROOT = ../ IPFS_CMD = ../cmd/ipfs RANDOM_SRC = ../Godeps/_workspace/src/github.com/jbenet/go-random MULTIHASH_SRC = ../Godeps/_workspace/src/github.com/jbenet/go-multihash +POLLENDPOINT_SRC= ../thirdparty/pollEndpoint all: deps @@ -23,6 +24,9 @@ bin/multihash: $(MULTIHASH_SRC)/**/*.go bin/ipfs: $(IPFS_ROOT)/**/*.go go build -o bin/ipfs $(IPFS_CMD) +bin/pollEndpoint: $(POLLENDPOINT_SRC)/*.go + go build -o bin/pollEndpoint $(POLLENDPOINT_SRC) + test: test_expensive test_expensive: diff --git a/test/sharness/Makefile b/test/sharness/Makefile index 392826632..144262f98 100644 --- a/test/sharness/Makefile +++ b/test/sharness/Makefile @@ -7,7 +7,7 @@ # NOTE: run with TEST_VERBOSE=1 for verbose sharness tests. T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)) -BINS = bin/random bin/multihash bin/ipfs +BINS = bin/random bin/multihash bin/ipfs bin/pollEndpoint SHARNESS = lib/sharness/sharness.sh IPFS_ROOT = ../.. diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 25724e25b..d2896c60c 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -175,15 +175,14 @@ test_launch_ipfs_daemon() { ADDR_API="/ip4/127.0.0.1/tcp/5001" test_expect_success "'ipfs daemon' is ready" ' IPFS_PID=$! && - test_wait_output_n_lines_60_sec actual_daemon 2 && - test_run_repeat_60_sec "grep \"API server listening on $ADDR_API\" actual_daemon" || - test_fsh cat actual_daemon || test_fsh cat daemon_err + pollEndpoint -ep=/version -host=$ADDR_API -v -tout=1s -tries=60 2>poll_apierr > poll_apiout || + test_fsh cat actual_daemon || test_fsh cat daemon_err || test_fsh cat poll_apierr || test_fsh cat poll_apiout ' if test "$ADDR_GWAY" != ""; then test_expect_success "'ipfs daemon' output includes Gateway address" ' - test_run_repeat_60_sec "grep \"Gateway server listening on $ADDR_GWAY\" actual_daemon" || - test_fsh cat daemon_err + pollEndpoint -ep=/version -host=$ADDR_GWAY -v -tout=1s -tries=60 2>poll_gwerr > poll_gwout || + test_fsh cat daemon_err || test_fsh cat poll_gwerr || test_fsh cat poll_gwout ' fi } diff --git a/thirdparty/pollEndpoint/main.go b/thirdparty/pollEndpoint/main.go new file mode 100644 index 000000000..de9e56523 --- /dev/null +++ b/thirdparty/pollEndpoint/main.go @@ -0,0 +1,93 @@ +// pollEndpoint is a helper utility that waits for a http endpoint to be reachable and return with http.StatusOK +package main + +import ( + "flag" + "fmt" + "net/http" + "net/url" + "os" + "time" + + log "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus" + ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" + manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net" +) + +var ( + host = flag.String("host", "/ip4/127.0.0.1/tcp/5001", "the multiaddr host to dial on") + endpoint = flag.String("ep", "/version", "which http endpoint path to hit") + tries = flag.Int("tries", 10, "how many tries to make before failing") + timeout = flag.Duration("tout", time.Second, "how long to wait between attempts") + verbose = flag.Bool("v", false, "verbose logging") +) + +func main() { + flag.Parse() + + // extract address from host flag + addr, err := ma.NewMultiaddr(*host) + if err != nil { + log.WithField("err", err).Fatal("NewMultiaddr() failed") + } + p := addr.Protocols() + if len(p) < 2 { + log.WithField("addr", addr).Fatal("need two protocols in host flag (/ip/tcp)") + } + _, host, err := manet.DialArgs(addr) + if err != nil { + log.WithField("err", err).Fatal("manet.DialArgs() failed") + } + + if *verbose { // lower log level + log.SetLevel(log.DebugLevel) + } + + // construct url to dial + var u url.URL + u.Scheme = "http" + u.Host = host + u.Path = *endpoint + + // show what we got + start := time.Now() + log.WithFields(log.Fields{ + "when": start, + "tries": *tries, + "timeout": *timeout, + "url": u.String(), + }).Debug("starting") + + for *tries > 0 { + f := log.Fields{"tries": *tries} + + err := checkOK(http.Get(u.String())) + if err == nil { + f["took"] = time.Since(start) + log.WithFields(f).Println("status ok - endpoint reachable") + os.Exit(0) + } + f["error"] = err + log.WithFields(f).Debug("get failed") + time.Sleep(*timeout) + *tries-- + } + + log.Println("failed.") + os.Exit(1) +} + +func checkOK(resp *http.Response, err error) error { + if err == nil { // request worked + resp.Body.Close() + if resp.StatusCode == http.StatusOK { + return nil + } + return fmt.Errorf("Response not OK. %d %s", resp.StatusCode, resp.Status) + } else if urlErr, ok := err.(*url.Error); ok { // expected error from http.Get() + if urlErr.Op != "Get" || urlErr.URL != *endpoint { + return fmt.Errorf("wrong url or endpoint error from http.Get() %#v", urlErr) + } + } + return err +}