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