Testutil falls back to random ports w/o porter (#3604)

* Testutil falls back to random ports w/o porter

This PR allows the testutil server to be used without porter.

* Adds sterner-sounding fallback comments.
This commit is contained in:
Alex Dadgar 2017-10-20 16:46:13 -07:00 committed by James Phillips
parent 211f886f11
commit c7a65b4587
2 changed files with 50 additions and 3 deletions

View File

@ -9,7 +9,28 @@ import (
"strings" "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) { func RandomPorts(n int) ([]int, error) {
addr := os.Getenv("PORTER_ADDR") addr := os.Getenv("PORTER_ADDR")
@ -25,7 +46,7 @@ func RandomPorts(n int) ([]int, error) {
resp, err := http.Get(fmt.Sprintf("http://%s/%d", addr, n)) resp, err := http.Get(fmt.Sprintf("http://%s/%d", addr, n))
if err != nil { if err != nil {
if strings.Contains(err.Error(), "connection refused") { if strings.Contains(err.Error(), "connection refused") {
return nil, fmt.Errorf("Are you running porter?\nInstall with 'go install github.com/hashicorp/consul/test/porter/cmd/porter'\nThen run 'porter go test ...'\n%s", err) return nil, &PorterExistErr{Wrapped: err}
} }
return nil, err return nil, err
} }

View File

@ -113,7 +113,14 @@ func defaultServerConfig() *TestServerConfig {
ports, err := porter.RandomPorts(6) ports, err := porter.RandomPorts(6)
if err != nil { if err != nil {
panic(err) 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{ return &TestServerConfig{
NodeName: "node-" + nodeID, NodeName: "node-" + nodeID,
@ -383,3 +390,22 @@ func (s *TestServer) waitForLeader() error {
} }
return nil 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
}