@cryptotaxi247 / kubo / commits / 56a32a306

using pollEndpoint to block in tests for 'daemon ready' (updates #844)

Henry committed Mar 4, 2015 at 14:50 UTC 56a32a306c4048221f98c9baef1b0ac3e3f53d9f
4 files changed +114 -4
cmd/ipfs/daemon.go
+1
@@ -244,6 +244,7 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
244 corehttp.CommandsOption(*req.Context()),
245 corehttp.WebUIOption,
246 gateway.ServeOption(),
247 + corehttp.VersionOption(),
248 }
249 if rootRedirect != nil {
250 opts = append(opts, rootRedirect)
cmd/pollEndpoint/main.go new
+106
@@ -0,0 +1,106 @@
1 +// pollEndpoint is a helper utility that waits for a http endpoint to be reachable and return with http.StatusOK
2 +package main
3 +
4 +import (
5 + "flag"
6 + "net"
7 + "net/http"
8 + "net/url"
9 + "os"
10 + "syscall"
11 + "time"
12 +
13 + log "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
14 + ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
15 + manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
16 +)
17 +
18 +var (
19 + host = flag.String("host", "/ip4/127.0.0.1/tcp/5001", "the multiaddr host to dial on")
20 + endpoint = flag.String("ep", "/version", "which http endpoint path to hit")
21 + tries = flag.Int("tries", 10, "how many tries to make before failing")
22 + timeout = flag.Duration("tout", time.Second, "how long to wait between attempts")
23 + verbose = flag.Bool("v", false, "verbose logging")
24 +)
25 +
26 +func main() {
27 + flag.Parse()
28 +
29 + // extract address from host flag
30 + addr, err := ma.NewMultiaddr(*host)
31 + if err != nil {
32 + log.WithField("err", err).Fatal("NewMultiaddr() failed")
33 + }
34 + p := addr.Protocols()
35 + if len(p) < 2 {
36 + log.WithField("addr", addr).Fatal("need to protocolls in host flag.")
37 + }
38 + _, host, err := manet.DialArgs(addr)
39 + if err != nil {
40 + log.WithField("err", err).Fatal("manet.DialArgs() failed")
41 + }
42 +
43 + if *verbose { // lower log level
44 + log.SetLevel(log.DebugLevel)
45 + }
46 +
47 + // construct url to dial
48 + var u url.URL
49 + u.Scheme = "http"
50 + u.Host = host
51 + u.Path = *endpoint
52 +
53 + // show what we got
54 + start := time.Now()
55 + log.WithFields(log.Fields{
56 + "when": start,
57 + "tries": *tries,
58 + "timeout": *timeout,
59 + "url": u.String(),
60 + }).Debug("starting")
61 +
62 + for *tries > 0 {
63 +
64 + f := log.Fields{"tries": *tries}
65 +
66 + resp, err := http.Get(u.String())
67 +
68 + if err == nil {
69 + resp.Body.Close()
70 +
71 + if resp.StatusCode == http.StatusOK {
72 + f["took"] = time.Since(start)
73 + log.WithFields(f).Println("status ok - endpoint reachable")
74 + os.Exit(0)
75 + }
76 +
77 + f["status"] = resp.Status
78 + log.WithFields(f).Warn("response not okay")
79 +
80 + } else if urlErr, ok := err.(*url.Error); ok { // expected error from http.Get()
81 + f["urlErr"] = urlErr
82 +
83 + if urlErr.Op != "Get" || urlErr.URL != *endpoint {
84 + f["op"] = urlErr.Op
85 + f["url"] = urlErr.URL
86 + log.WithFields(f).Error("way to funky buisness..!")
87 + }
88 +
89 + if opErr, ok := urlErr.Err.(*net.OpError); ok {
90 + f["opErr"] = opErr
91 + f["connRefused"] = opErr.Err == syscall.ECONNREFUSED
92 + f["temporary"] = opErr.Temporary()
93 + log.WithFields(f).Println("net.OpError")
94 + }
95 + } else { // unexpected error from http.Get()
96 + f["err"] = err
97 + log.WithFields(f).Error("unknown error")
98 + }
99 +
100 + time.Sleep(*timeout)
101 + *tries--
102 + }
103 +
104 + log.Println("failed.")
105 + os.Exit(1)
106 +}
test/Makefile
+5 -1
@@ -1,9 +1,10 @@
1
2 -BINS = bin/random bin/multihash bin/ipfs
2 +BINS = bin/random bin/multihash bin/ipfs bin/pollEndpoint
3 IPFS_ROOT = ../
4 IPFS_CMD = ../cmd/ipfs
5 RANDOM_SRC = ../Godeps/_workspace/src/github.com/jbenet/go-random
6 MULTIHASH_SRC = ../Godeps/_workspace/src/github.com/jbenet/go-multihash
7 +POLLENDPOINT_SRC= ../cmd/pollEndpoint
8
9 all: deps
10
@@ -23,6 +24,9 @@ bin/multihash: $(MULTIHASH_SRC)/**/*.go
24 bin/ipfs: $(IPFS_ROOT)/**/*.go
25 go build -o bin/ipfs $(IPFS_CMD)
26
27 +bin/pollEndpoint: $(POLLENDPOINT_SRC)/*.go
28 + go build -o bin/pollEndpoint $(POLLENDPOINT_SRC)
29 +
30 test: test_expensive
31
32 test_expensive:
test/sharness/lib/test-lib.sh
+2 -3
@@ -175,14 +175,13 @@ test_launch_ipfs_daemon() {
175 ADDR_API="/ip4/127.0.0.1/tcp/5001"
176 test_expect_success "'ipfs daemon' is ready" '
177 IPFS_PID=$! &&
178 - test_wait_output_n_lines_60_sec actual_daemon 2 &&
179 - test_run_repeat_60_sec "grep \"API server listening on $ADDR_API\" actual_daemon" ||
178 + pollEndpoint -ep=/version -host=$ADDR_API -v -tout=1s -tries=60 2>poll_err > poll_apiout ||
179 test_fsh cat actual_daemon || test_fsh cat daemon_err
180 '
181
182 if test "$ADDR_GWAY" != ""; then
183 test_expect_success "'ipfs daemon' output includes Gateway address" '
185 - test_run_repeat_60_sec "grep \"Gateway server listening on $ADDR_GWAY\" actual_daemon" ||
184 + pollEndpoint -ep=/version -host=$ADDR_GWAY -v -tout=1s -tries=60 2>poll_err > poll_gwout ||
185 test_fsh cat daemon_err
186 '
187 fi