consul/testrpc/wait.go
Frank Schroeder eddb1af603 Remove duplicate constants
This patch removes duplicate internal copies of constants in the structs
package which are also defined in the api package. The api.KVOp type
with all its values for the TXN endpoint and the api.HealthXXX constants
are now used throughout the codebase.

This resulted in some circular dependencies in the testutil package
which have been resolved by copying code and constants and moving the
WaitForLeader function into a separate testrpc package.
2017-04-20 09:54:49 -07:00

64 lines
1.3 KiB
Go

package testrpc
import (
"fmt"
"testing"
"time"
"github.com/hashicorp/consul/consul/structs"
"github.com/pkg/errors"
)
type testFn func() (bool, error)
const (
baseWait = 1 * time.Millisecond
maxWait = 100 * time.Millisecond
)
func WaitForResult(try testFn) error {
var err error
wait := baseWait
for retries := 100; retries > 0; retries-- {
var success bool
success, err = try()
if success {
time.Sleep(25 * time.Millisecond)
return nil
}
time.Sleep(wait)
wait *= 2
if wait > maxWait {
wait = maxWait
}
}
if err != nil {
return errors.Wrap(err, "timed out with error")
} else {
return fmt.Errorf("timed out")
}
}
type rpcFn func(string, interface{}, interface{}) error
func WaitForLeader(t *testing.T, rpc rpcFn, dc string) {
var out structs.IndexedNodes
if err := WaitForResult(func() (bool, error) {
// Ensure we have a leader and a node registration.
args := &structs.DCSpecificRequest{Datacenter: dc}
if err := rpc("Catalog.ListNodes", args, &out); err != nil {
return false, fmt.Errorf("Catalog.ListNodes failed: %v", err)
}
if !out.QueryMeta.KnownLeader {
return false, fmt.Errorf("No leader")
}
if out.Index == 0 {
return false, fmt.Errorf("Consul index is 0")
}
return true, nil
}); err != nil {
t.Fatalf("failed to find leader: %v", err)
}
}