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"
)
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")
@ -25,7 +46,7 @@ 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, 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
}

View File

@ -113,7 +113,14 @@ func defaultServerConfig() *TestServerConfig {
ports, err := porter.RandomPorts(6)
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{
NodeName: "node-" + nodeID,
@ -383,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
}