mirror of https://github.com/hashicorp/consul
testutil: allow skipping leader wait, update example
parent
db134f6190
commit
04d73628d1
|
@ -19,42 +19,46 @@ Following is some example usage:
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/consul/testutil"
|
||||
"testing"
|
||||
"github.com/hashicorp/consul/testutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(t *testing.T) {
|
||||
// Create a server
|
||||
srv1 := testutil.NewTestServer(t)
|
||||
defer srv1.Stop()
|
||||
// Create a server
|
||||
srv1 := testutil.NewTestServer(t)
|
||||
defer srv1.Stop()
|
||||
|
||||
// Create a secondary server
|
||||
srv2 := testutil.NewTestServer(t)
|
||||
defer srv2.Stop()
|
||||
// Create a secondary server, passing in configuration
|
||||
// to avoid bootstrapping or waiting for a leader.
|
||||
srv2 := testutil.NewTestServerConfig(t, func(c *testutil.TestServerConfig) {
|
||||
c.Bootstrap = false
|
||||
c.NoLeaderWait = true
|
||||
})
|
||||
defer srv2.Stop()
|
||||
|
||||
// Join the servers together
|
||||
srv1.JoinLAN(srv2.LANAddr)
|
||||
// Join the servers together
|
||||
srv1.JoinLAN(srv2.LANAddr)
|
||||
|
||||
// Create a test key/value pair
|
||||
srv1.SetKV("foo", []byte("bar"))
|
||||
// Create a test key/value pair
|
||||
srv1.SetKV("foo", []byte("bar"))
|
||||
|
||||
// Create lots of test key/value pairs
|
||||
srv1.PopulateKV(map[string][]byte{
|
||||
"bar": []byte("123"),
|
||||
"baz": []byte("456"),
|
||||
})
|
||||
// Create lots of test key/value pairs
|
||||
srv1.PopulateKV(map[string][]byte{
|
||||
"bar": []byte("123"),
|
||||
"baz": []byte("456"),
|
||||
})
|
||||
|
||||
// Create a service
|
||||
srv1.AddService("redis", "passing", []string{"master"})
|
||||
// Create a service
|
||||
srv1.AddService("redis", "passing", []string{"master"})
|
||||
|
||||
// Create a service check
|
||||
srv1.AddCheck("service:redis", "redis", "passing")
|
||||
// Create a service check
|
||||
srv1.AddCheck("service:redis", "redis", "passing")
|
||||
|
||||
// Create a node check
|
||||
srv1.AddCheck("mem", "", "critical")
|
||||
// Create a node check
|
||||
srv1.AddCheck("mem", "", "critical")
|
||||
|
||||
// The HTTPAddr field contains the address of the Consul
|
||||
// API on the new test server instance.
|
||||
println(srv1.HTTPAddr)
|
||||
// The HTTPAddr field contains the address of the Consul
|
||||
// API on the new test server instance.
|
||||
println(srv1.HTTPAddr)
|
||||
}
|
||||
```
|
||||
|
|
|
@ -59,6 +59,11 @@ type TestServerConfig struct {
|
|||
Bind string `json:"bind_addr,omitempty"`
|
||||
Addresses *TestAddressConfig `json:"addresses,omitempty"`
|
||||
Ports *TestPortConfig `json:"ports,omitempty"`
|
||||
|
||||
// NoLeaderWait is a special config option used to instruct
|
||||
// the test harness not to wait for a leader. Useful for
|
||||
// bootstrapping a multi-node cluster for testing.
|
||||
NoLeaderWait bool `json:"-"`
|
||||
}
|
||||
|
||||
// ServerConfigCallback is a function interface which can be
|
||||
|
@ -142,12 +147,11 @@ func NewTestServerConfig(t *testing.T, cb ServerConfigCallback) *TestServer {
|
|||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
configFile, err := ioutil.TempFile("", "consul")
|
||||
configFile, err := ioutil.TempFile(dataDir, "config")
|
||||
if err != nil {
|
||||
defer os.RemoveAll(dataDir)
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Remove(configFile.Name())
|
||||
|
||||
consulConfig := defaultServerConfig()
|
||||
consulConfig.DataDir = dataDir
|
||||
|
@ -203,7 +207,11 @@ func NewTestServerConfig(t *testing.T, cb ServerConfigCallback) *TestServer {
|
|||
}
|
||||
|
||||
// Wait for the server to be ready
|
||||
server.waitForLeader()
|
||||
if consulConfig.NoLeaderWait {
|
||||
server.waitForAPI()
|
||||
} else {
|
||||
server.waitForLeader()
|
||||
}
|
||||
|
||||
return server
|
||||
}
|
||||
|
@ -219,6 +227,26 @@ func (s *TestServer) Stop() {
|
|||
}
|
||||
}
|
||||
|
||||
// waitForAPI waits for only the agent HTTP endpoint to start
|
||||
// responding. This is an indication that the agent has started,
|
||||
// but will likely return before a leader is elected.
|
||||
func (s *TestServer) waitForAPI() {
|
||||
WaitForResult(func() (bool, error) {
|
||||
resp, err := s.HttpClient.Get(s.url("/v1/agent/self"))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if err := s.requireOK(resp); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}, func(err error) {
|
||||
defer s.Stop()
|
||||
s.t.Fatalf("err: %s", err)
|
||||
})
|
||||
}
|
||||
|
||||
// waitForLeader waits for the Consul server's HTTP API to become
|
||||
// available, and then waits for a known leader and an index of
|
||||
// 1 or more to be observed to confirm leader election is done.
|
||||
|
|
Loading…
Reference in New Issue