diff --git a/vendor/github.com/hashicorp/consul/test/porter/client.go b/vendor/github.com/hashicorp/consul/test/porter/client.go index 34d3579e9..1c746e9be 100644 --- a/vendor/github.com/hashicorp/consul/test/porter/client.go +++ b/vendor/github.com/hashicorp/consul/test/porter/client.go @@ -6,9 +6,31 @@ import ( "io/ioutil" "net/http" "os" + "strings" ) -var DefaultAddr = "127.0.0.1:7965" +var ( + // DefaultAddr is the the default bind address of a Porter server. This acts + // as the fallback address if the Porter server is not specified. + DefaultAddr = "127.0.0.1:7965" +) + +const ( + // porterErrPrefix is the string returned when displaying a porter error + porterErrPrefix = `Are you running porter? +Install with 'go install github.com/hashicorp/consul/test/porter/cmd/porter' +Then run 'porter go test ...'` +) + +// PorterExistErr is used to wrap an error that is likely from Porter not being +// run. +type PorterExistErr struct { + Wrapped error +} + +func (p *PorterExistErr) Error() string { + return fmt.Sprintf("%s:\n%s", porterErrPrefix, p.Wrapped) +} func RandomPorts(n int) ([]int, error) { addr := os.Getenv("PORTER_ADDR") @@ -23,6 +45,9 @@ func RandomPorts(n int) ([]int, error) { } resp, err := http.Get(fmt.Sprintf("http://%s/%d", addr, n)) if err != nil { + if strings.Contains(err.Error(), "connection refused") { + return nil, &PorterExistErr{Wrapped: err} + } return nil, err } defer resp.Body.Close() diff --git a/vendor/github.com/hashicorp/consul/testutil/server.go b/vendor/github.com/hashicorp/consul/testutil/server.go index 22880a869..93b734a67 100644 --- a/vendor/github.com/hashicorp/consul/testutil/server.go +++ b/vendor/github.com/hashicorp/consul/testutil/server.go @@ -27,6 +27,7 @@ import ( "testing" "time" + "github.com/hashicorp/consul/test/porter" "github.com/hashicorp/consul/testutil/retry" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-uuid" @@ -47,9 +48,6 @@ type TestPortConfig struct { SerfLan int `json:"serf_lan,omitempty"` SerfWan int `json:"serf_wan,omitempty"` Server int `json:"server,omitempty"` - - // Deprecated - RPC int `json:"rpc,omitempty"` } // TestAddressConfig contains the bind addresses for various @@ -113,8 +111,19 @@ func defaultServerConfig() *TestServerConfig { panic(err) } + ports, err := porter.RandomPorts(6) + if err != nil { + if _, ok := err.(*porter.PorterExistErr); ok { + // Fall back in the case that the testutil server is being used + // without porter. This should NEVER be used for Consul's own + // unit tests. See comments for getRandomPorts() for more details. + ports = getRandomPorts(6) + } else { + panic(err) + } + } return &TestServerConfig{ - NodeName: fmt.Sprintf("node%d", randomPort()), + NodeName: "node-" + nodeID, NodeID: nodeID, DisableCheckpoint: true, Performance: &TestPerformanceConfig{ @@ -126,28 +135,17 @@ func defaultServerConfig() *TestServerConfig { Bind: "127.0.0.1", Addresses: &TestAddressConfig{}, Ports: &TestPortConfig{ - DNS: randomPort(), - HTTP: randomPort(), - HTTPS: randomPort(), - SerfLan: randomPort(), - SerfWan: randomPort(), - Server: randomPort(), - //RPC: randomPort(), + DNS: ports[0], + HTTP: ports[1], + HTTPS: ports[2], + SerfLan: ports[3], + SerfWan: ports[4], + Server: ports[5], }, ReadyTimeout: 10 * time.Second, } } -// randomPort asks the kernel for a random port to use. -func randomPort() int { - l, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - panic(err) - } - defer l.Close() - return l.Addr().(*net.TCPAddr).Port -} - // TestService is used to serialize a service definition. type TestService struct { ID string `json:",omitempty"` @@ -200,15 +198,7 @@ func NewTestServerConfig(cb ServerConfigCallback) (*TestServer, error) { // configuring or starting the server, the server will NOT be running when the // function returns (thus you do not need to stop it). func NewTestServerConfigT(t *testing.T, cb ServerConfigCallback) (*TestServer, error) { - var server *TestServer - retry.Run(t, func(r *retry.R) { - var err error - server, err = newTestServerConfigT(t, cb) - if err != nil { - r.Fatalf("failed starting test server: %v", err) - } - }) - return server, nil + return newTestServerConfigT(t, cb) } // newTestServerConfigT is the internal helper for NewTestServerConfigT. @@ -400,3 +390,22 @@ func (s *TestServer) waitForLeader() error { } return nil } + +// getRandomPorts returns a set of random port or panics on error. This +// is here to support external uses of testutil which may not have porter, +// but this has been shown not to work well with parallel tests (such as +// Consul's unit tests). This fallback should NEVER be used for Consul's +// own tests. +func getRandomPorts(n int) []int { + ports := make([]int, n) + for i := 0; i < n; i++ { + l, err := net.Listen("tcp", ":0") + if err != nil { + panic(err) + } + l.Close() + ports[i] = l.Addr().(*net.TCPAddr).Port + } + + return ports +} diff --git a/vendor/github.com/hashicorp/consul/testutil/server_methods.go b/vendor/github.com/hashicorp/consul/testutil/server_methods.go index 8f4b067ad..dec512054 100644 --- a/vendor/github.com/hashicorp/consul/testutil/server_methods.go +++ b/vendor/github.com/hashicorp/consul/testutil/server_methods.go @@ -25,13 +25,13 @@ const ( // JoinLAN is used to join local datacenters together. func (s *TestServer) JoinLAN(t *testing.T, addr string) { - resp := s.get(t, "/v1/agent/join/"+addr) + resp := s.put(t, "/v1/agent/join/"+addr, nil) defer resp.Body.Close() } // JoinWAN is used to join remote datacenters together. func (s *TestServer) JoinWAN(t *testing.T, addr string) { - resp := s.get(t, "/v1/agent/join/"+addr+"?wan=1") + resp := s.put(t, "/v1/agent/join/"+addr+"?wan=1", nil) resp.Body.Close() } diff --git a/vendor/vendor.json b/vendor/vendor.json index 38b36a819..08c91cae1 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -761,22 +761,22 @@ "revisionTime": "2017-10-16T16:22:40Z" }, { - "checksumSHA1": "lLvSnIuLwqn3ZbX1H4dVtzKuRdU=", + "checksumSHA1": "5XjgqE4UIfwXvkq5VssGNc7uPhQ=", "path": "github.com/hashicorp/consul/test/porter", - "revision": "51ea240df8476e02215d53fbfad5838bf0d44d21", - "revisionTime": "2017-10-16T16:22:40Z" + "revision": "ad9425ca6353b8afcfebd19130a8cf768f7eac30", + "revisionTime": "2017-10-21T00:05:25Z" }, { - "checksumSHA1": "AZh3opzONxPrOi+4Io2+OomdKgM=", + "checksumSHA1": "+go9ycmyfF4b0W174gc7ej5mnE8=", "path": "github.com/hashicorp/consul/testutil", - "revision": "745fd38728f28061c9f5bfe323d68ee25f2cd07b", - "revisionTime": "2017-10-16T23:19:35Z" + "revision": "350932161d6745836c1b2f39849bddb0f9fb52fd", + "revisionTime": "2017-10-20T23:49:17Z" }, { "checksumSHA1": "J8TTDc84MvAyXE/FrfgS+xc/b6s=", "path": "github.com/hashicorp/consul/testutil/retry", - "revision": "745fd38728f28061c9f5bfe323d68ee25f2cd07b", - "revisionTime": "2017-10-16T23:19:35Z" + "revision": "350932161d6745836c1b2f39849bddb0f9fb52fd", + "revisionTime": "2017-10-20T23:49:17Z" }, { "path": "github.com/hashicorp/errwrap",