testutil: initial pass at moving test server harness into testutil

This commit is contained in:
Ryan Uber 2015-03-02 18:18:38 -08:00
parent c6d45430f1
commit 37f6301856
12 changed files with 228 additions and 203 deletions

View File

@ -17,7 +17,7 @@ func TestACL_CreateDestroy(t *testing.T) {
t.SkipNow() t.SkipNow()
} }
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
c.config.Token = CONSUL_ROOT c.config.Token = CONSUL_ROOT
acl := c.ACL() acl := c.ACL()
@ -65,7 +65,7 @@ func TestACL_CloneDestroy(t *testing.T) {
t.SkipNow() t.SkipNow()
} }
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
c.config.Token = CONSUL_ROOT c.config.Token = CONSUL_ROOT
acl := c.ACL() acl := c.ACL()
@ -98,7 +98,7 @@ func TestACL_Info(t *testing.T) {
t.SkipNow() t.SkipNow()
} }
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
c.config.Token = CONSUL_ROOT c.config.Token = CONSUL_ROOT
acl := c.ACL() acl := c.ACL()
@ -125,7 +125,7 @@ func TestACL_List(t *testing.T) {
t.SkipNow() t.SkipNow()
} }
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
c.config.Token = CONSUL_ROOT c.config.Token = CONSUL_ROOT
acl := c.ACL() acl := c.ACL()

View File

@ -7,7 +7,7 @@ import (
func TestAgent_Self(t *testing.T) { func TestAgent_Self(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -24,7 +24,7 @@ func TestAgent_Self(t *testing.T) {
func TestAgent_Members(t *testing.T) { func TestAgent_Members(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -40,7 +40,7 @@ func TestAgent_Members(t *testing.T) {
func TestAgent_Services(t *testing.T) { func TestAgent_Services(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -79,7 +79,7 @@ func TestAgent_Services(t *testing.T) {
func TestAgent_ServiceAddress(t *testing.T) { func TestAgent_ServiceAddress(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -125,7 +125,7 @@ func TestAgent_ServiceAddress(t *testing.T) {
func TestAgent_Services_MultipleChecks(t *testing.T) { func TestAgent_Services_MultipleChecks(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -168,7 +168,7 @@ func TestAgent_Services_MultipleChecks(t *testing.T) {
func TestAgent_SetTTLStatus(t *testing.T) { func TestAgent_SetTTLStatus(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -208,7 +208,7 @@ func TestAgent_SetTTLStatus(t *testing.T) {
func TestAgent_Checks(t *testing.T) { func TestAgent_Checks(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -235,7 +235,7 @@ func TestAgent_Checks(t *testing.T) {
func TestAgent_Checks_serviceBound(t *testing.T) { func TestAgent_Checks_serviceBound(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -273,7 +273,7 @@ func TestAgent_Checks_serviceBound(t *testing.T) {
func TestAgent_Join(t *testing.T) { func TestAgent_Join(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -292,7 +292,7 @@ func TestAgent_Join(t *testing.T) {
func TestAgent_ForceLeave(t *testing.T) { func TestAgent_ForceLeave(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -305,7 +305,7 @@ func TestAgent_ForceLeave(t *testing.T) {
func TestServiceMaintenance(t *testing.T) { func TestServiceMaintenance(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
@ -359,7 +359,7 @@ func TestServiceMaintenance(t *testing.T) {
func TestNodeMaintenance(t *testing.T) { func TestNodeMaintenance(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()

View File

@ -2,12 +2,10 @@ package api
import ( import (
crand "crypto/rand" crand "crypto/rand"
"encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"testing" "testing"
@ -16,131 +14,24 @@ import (
"github.com/hashicorp/consul/testutil" "github.com/hashicorp/consul/testutil"
) )
type testServer struct {
pid int
dataDir string
configFile string
}
type testPortConfig struct {
DNS int `json:"dns,omitempty"`
HTTP int `json:"http,omitempty"`
RPC int `json:"rpc,omitempty"`
SerfLan int `json:"serf_lan,omitempty"`
SerfWan int `json:"serf_wan,omitempty"`
Server int `json:"server,omitempty"`
}
type testAddressConfig struct {
HTTP string `json:"http,omitempty"`
}
type testServerConfig struct {
Bootstrap bool `json:"bootstrap,omitempty"`
Server bool `json:"server,omitempty"`
DataDir string `json:"data_dir,omitempty"`
LogLevel string `json:"log_level,omitempty"`
Addresses *testAddressConfig `json:"addresses,omitempty"`
Ports testPortConfig `json:"ports,omitempty"`
}
// Callback functions for modifying config
type configCallback func(c *Config) type configCallback func(c *Config)
type serverConfigCallback func(c *testServerConfig)
func defaultConfig() *testServerConfig { func makeClient(t *testing.T) (*Client, *testutil.TestServer) {
return &testServerConfig{
Bootstrap: true,
Server: true,
LogLevel: "debug",
Ports: testPortConfig{
DNS: 19000,
HTTP: 18800,
RPC: 18600,
SerfLan: 18200,
SerfWan: 18400,
Server: 18000,
},
}
}
func (s *testServer) stop() {
defer os.RemoveAll(s.dataDir)
defer os.RemoveAll(s.configFile)
cmd := exec.Command("kill", "-9", fmt.Sprintf("%d", s.pid))
if err := cmd.Run(); err != nil {
panic(err)
}
}
func newTestServer(t *testing.T) *testServer {
return newTestServerWithConfig(t, func(c *testServerConfig) {})
}
func newTestServerWithConfig(t *testing.T, cb serverConfigCallback) *testServer {
if path, err := exec.LookPath("consul"); err != nil || path == "" {
t.Log("consul not found on $PATH, skipping")
t.SkipNow()
}
pidFile, err := ioutil.TempFile("", "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
pidFile.Close()
os.Remove(pidFile.Name())
dataDir, err := ioutil.TempDir("", "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
configFile, err := ioutil.TempFile("", "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
consulConfig := defaultConfig()
consulConfig.DataDir = dataDir
cb(consulConfig)
configContent, err := json.Marshal(consulConfig)
if err != nil {
t.Fatalf("err: %s", err)
}
if _, err := configFile.Write(configContent); err != nil {
t.Fatalf("err: %s", err)
}
configFile.Close()
// Start the server
cmd := exec.Command("consul", "agent", "-config-file", configFile.Name())
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
t.Fatalf("err: %s", err)
}
return &testServer{
pid: cmd.Process.Pid,
dataDir: dataDir,
configFile: configFile.Name(),
}
}
func makeClient(t *testing.T) (*Client, *testServer) {
return makeClientWithConfig(t, func(c *Config) { return makeClientWithConfig(t, func(c *Config) {
c.Address = "127.0.0.1:18800" c.Address = "127.0.0.1:18800"
}, func(c *testServerConfig) {}) }, nil)
} }
func makeClientWithConfig(t *testing.T, cb1 configCallback, cb2 serverConfigCallback) (*Client, *testServer) { func makeClientWithConfig(
t *testing.T,
cb1 configCallback,
cb2 testutil.ServerConfigCallback) (*Client, *testutil.TestServer) {
// Make client config // Make client config
conf := DefaultConfig() conf := DefaultConfig()
cb1(conf) if cb1 != nil {
cb1(conf)
}
// Create client // Create client
client, err := NewClient(conf) client, err := NewClient(conf)
@ -149,29 +40,7 @@ func makeClientWithConfig(t *testing.T, cb1 configCallback, cb2 serverConfigCall
} }
// Create server // Create server
server := newTestServerWithConfig(t, cb2) server := testutil.NewTestServerConfig(t, cb2)
// Allow the server some time to start, and verify we have a leader.
testutil.WaitForResult(func() (bool, error) {
req := client.newRequest("GET", "/v1/catalog/nodes")
_, resp, err := client.doRequest(req)
if err != nil {
return false, err
}
resp.Body.Close()
// Ensure we have a leader and a node registeration
if leader := resp.Header.Get("X-Consul-KnownLeader"); leader != "true" {
return false, fmt.Errorf("Consul leader status: %#v", leader)
}
if resp.Header.Get("X-Consul-Index") == "0" {
return false, fmt.Errorf("Consul index is 0")
}
return true, nil
}, func(err error) {
t.Fatalf("err: %s", err)
})
return client, server return client, server
} }
@ -237,7 +106,7 @@ func TestDefaultConfig_env(t *testing.T) {
func TestSetQueryOptions(t *testing.T) { func TestSetQueryOptions(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
r := c.newRequest("GET", "/v1/kv/foo") r := c.newRequest("GET", "/v1/kv/foo")
q := &QueryOptions{ q := &QueryOptions{
@ -272,7 +141,7 @@ func TestSetQueryOptions(t *testing.T) {
func TestSetWriteOptions(t *testing.T) { func TestSetWriteOptions(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
r := c.newRequest("GET", "/v1/kv/foo") r := c.newRequest("GET", "/v1/kv/foo")
q := &WriteOptions{ q := &WriteOptions{
@ -291,7 +160,7 @@ func TestSetWriteOptions(t *testing.T) {
func TestRequestToHTTP(t *testing.T) { func TestRequestToHTTP(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
r := c.newRequest("DELETE", "/v1/kv/foo") r := c.newRequest("DELETE", "/v1/kv/foo")
q := &QueryOptions{ q := &QueryOptions{
@ -349,12 +218,12 @@ func TestAPI_UnixSocket(t *testing.T) {
c, s := makeClientWithConfig(t, func(c *Config) { c, s := makeClientWithConfig(t, func(c *Config) {
c.Address = "unix://" + socket c.Address = "unix://" + socket
}, func(c *testServerConfig) { }, func(c *testutil.TestServerConfig) {
c.Addresses = &testAddressConfig{ c.Addresses = &testutil.TestAddressConfig{
HTTP: "unix://" + socket, HTTP: "unix://" + socket,
} }
}) })
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()

View File

@ -9,7 +9,7 @@ import (
func TestCatalog_Datacenters(t *testing.T) { func TestCatalog_Datacenters(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
catalog := c.Catalog() catalog := c.Catalog()
@ -31,7 +31,7 @@ func TestCatalog_Datacenters(t *testing.T) {
func TestCatalog_Nodes(t *testing.T) { func TestCatalog_Nodes(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
catalog := c.Catalog() catalog := c.Catalog()
@ -57,7 +57,7 @@ func TestCatalog_Nodes(t *testing.T) {
func TestCatalog_Services(t *testing.T) { func TestCatalog_Services(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
catalog := c.Catalog() catalog := c.Catalog()
@ -83,7 +83,7 @@ func TestCatalog_Services(t *testing.T) {
func TestCatalog_Service(t *testing.T) { func TestCatalog_Service(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
catalog := c.Catalog() catalog := c.Catalog()
@ -109,7 +109,7 @@ func TestCatalog_Service(t *testing.T) {
func TestCatalog_Node(t *testing.T) { func TestCatalog_Node(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
catalog := c.Catalog() catalog := c.Catalog()
name, _ := c.Agent().NodeName() name, _ := c.Agent().NodeName()
@ -135,7 +135,7 @@ func TestCatalog_Node(t *testing.T) {
func TestCatalog_Registration(t *testing.T) { func TestCatalog_Registration(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
catalog := c.Catalog() catalog := c.Catalog()

View File

@ -6,7 +6,7 @@ import (
func TestEvent_FireList(t *testing.T) { func TestEvent_FireList(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
event := c.Event() event := c.Event()

View File

@ -9,7 +9,7 @@ import (
func TestHealth_Node(t *testing.T) { func TestHealth_Node(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
health := c.Health() health := c.Health()
@ -39,7 +39,7 @@ func TestHealth_Node(t *testing.T) {
func TestHealth_Checks(t *testing.T) { func TestHealth_Checks(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
agent := c.Agent() agent := c.Agent()
health := c.Health() health := c.Health()
@ -75,7 +75,7 @@ func TestHealth_Checks(t *testing.T) {
func TestHealth_Service(t *testing.T) { func TestHealth_Service(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
health := c.Health() health := c.Health()
@ -99,7 +99,7 @@ func TestHealth_Service(t *testing.T) {
func TestHealth_State(t *testing.T) { func TestHealth_State(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
health := c.Health() health := c.Health()

View File

@ -9,7 +9,7 @@ import (
func TestClientPutGetDelete(t *testing.T) { func TestClientPutGetDelete(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
kv := c.KV() kv := c.KV()
@ -65,7 +65,7 @@ func TestClientPutGetDelete(t *testing.T) {
func TestClient_List_DeleteRecurse(t *testing.T) { func TestClient_List_DeleteRecurse(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
kv := c.KV() kv := c.KV()
@ -119,7 +119,7 @@ func TestClient_List_DeleteRecurse(t *testing.T) {
func TestClient_DeleteCAS(t *testing.T) { func TestClient_DeleteCAS(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
kv := c.KV() kv := c.KV()
@ -164,7 +164,7 @@ func TestClient_DeleteCAS(t *testing.T) {
func TestClient_CAS(t *testing.T) { func TestClient_CAS(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
kv := c.KV() kv := c.KV()
@ -211,7 +211,7 @@ func TestClient_CAS(t *testing.T) {
func TestClient_WatchGet(t *testing.T) { func TestClient_WatchGet(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
kv := c.KV() kv := c.KV()
@ -262,7 +262,7 @@ func TestClient_WatchGet(t *testing.T) {
func TestClient_WatchList(t *testing.T) { func TestClient_WatchList(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
kv := c.KV() kv := c.KV()
@ -315,7 +315,7 @@ func TestClient_WatchList(t *testing.T) {
func TestClient_Keys_DeleteRecurse(t *testing.T) { func TestClient_Keys_DeleteRecurse(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
kv := c.KV() kv := c.KV()
@ -364,7 +364,7 @@ func TestClient_Keys_DeleteRecurse(t *testing.T) {
func TestClient_AcquireRelease(t *testing.T) { func TestClient_AcquireRelease(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
session := c.Session() session := c.Session()
kv := c.KV() kv := c.KV()

View File

@ -9,7 +9,7 @@ import (
func TestLock_LockUnlock(t *testing.T) { func TestLock_LockUnlock(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
lock, err := c.LockKey("test/lock") lock, err := c.LockKey("test/lock")
if err != nil { if err != nil {
@ -66,7 +66,7 @@ func TestLock_LockUnlock(t *testing.T) {
func TestLock_ForceInvalidate(t *testing.T) { func TestLock_ForceInvalidate(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
lock, err := c.LockKey("test/lock") lock, err := c.LockKey("test/lock")
if err != nil { if err != nil {
@ -100,7 +100,7 @@ func TestLock_ForceInvalidate(t *testing.T) {
func TestLock_DeleteKey(t *testing.T) { func TestLock_DeleteKey(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
lock, err := c.LockKey("test/lock") lock, err := c.LockKey("test/lock")
if err != nil { if err != nil {
@ -133,7 +133,7 @@ func TestLock_DeleteKey(t *testing.T) {
func TestLock_Contend(t *testing.T) { func TestLock_Contend(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
acquired := make([]bool, 3) acquired := make([]bool, 3)
@ -185,7 +185,7 @@ func TestLock_Contend(t *testing.T) {
func TestLock_Destroy(t *testing.T) { func TestLock_Destroy(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
lock, err := c.LockKey("test/lock") lock, err := c.LockKey("test/lock")
if err != nil { if err != nil {
@ -253,7 +253,7 @@ func TestLock_Destroy(t *testing.T) {
func TestLock_Conflict(t *testing.T) { func TestLock_Conflict(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
sema, err := c.SemaphorePrefix("test/lock/", 2) sema, err := c.SemaphorePrefix("test/lock/", 2)
if err != nil { if err != nil {

View File

@ -9,7 +9,7 @@ import (
func TestSemaphore_AcquireRelease(t *testing.T) { func TestSemaphore_AcquireRelease(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
sema, err := c.SemaphorePrefix("test/semaphore", 2) sema, err := c.SemaphorePrefix("test/semaphore", 2)
if err != nil { if err != nil {
@ -66,7 +66,7 @@ func TestSemaphore_AcquireRelease(t *testing.T) {
func TestSemaphore_ForceInvalidate(t *testing.T) { func TestSemaphore_ForceInvalidate(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
sema, err := c.SemaphorePrefix("test/semaphore", 2) sema, err := c.SemaphorePrefix("test/semaphore", 2)
if err != nil { if err != nil {
@ -100,7 +100,7 @@ func TestSemaphore_ForceInvalidate(t *testing.T) {
func TestSemaphore_DeleteKey(t *testing.T) { func TestSemaphore_DeleteKey(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
sema, err := c.SemaphorePrefix("test/semaphore", 2) sema, err := c.SemaphorePrefix("test/semaphore", 2)
if err != nil { if err != nil {
@ -133,7 +133,7 @@ func TestSemaphore_DeleteKey(t *testing.T) {
func TestSemaphore_Contend(t *testing.T) { func TestSemaphore_Contend(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
acquired := make([]bool, 4) acquired := make([]bool, 4)
@ -185,7 +185,7 @@ func TestSemaphore_Contend(t *testing.T) {
func TestSemaphore_BadLimit(t *testing.T) { func TestSemaphore_BadLimit(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
sema, err := c.SemaphorePrefix("test/semaphore", 0) sema, err := c.SemaphorePrefix("test/semaphore", 0)
if err == nil { if err == nil {
@ -215,7 +215,7 @@ func TestSemaphore_BadLimit(t *testing.T) {
func TestSemaphore_Destroy(t *testing.T) { func TestSemaphore_Destroy(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
sema, err := c.SemaphorePrefix("test/semaphore", 2) sema, err := c.SemaphorePrefix("test/semaphore", 2)
if err != nil { if err != nil {
@ -270,7 +270,7 @@ func TestSemaphore_Destroy(t *testing.T) {
func TestSemaphore_Conflict(t *testing.T) { func TestSemaphore_Conflict(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
lock, err := c.LockKey("test/sema/.lock") lock, err := c.LockKey("test/sema/.lock")
if err != nil { if err != nil {

View File

@ -6,7 +6,7 @@ import (
func TestSession_CreateDestroy(t *testing.T) { func TestSession_CreateDestroy(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
session := c.Session() session := c.Session()
@ -35,7 +35,7 @@ func TestSession_CreateDestroy(t *testing.T) {
func TestSession_CreateRenewDestroy(t *testing.T) { func TestSession_CreateRenewDestroy(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
session := c.Session() session := c.Session()
@ -85,7 +85,7 @@ func TestSession_CreateRenewDestroy(t *testing.T) {
func TestSession_Info(t *testing.T) { func TestSession_Info(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
session := c.Session() session := c.Session()
@ -138,7 +138,7 @@ func TestSession_Info(t *testing.T) {
func TestSession_Node(t *testing.T) { func TestSession_Node(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
session := c.Session() session := c.Session()
@ -172,7 +172,7 @@ func TestSession_Node(t *testing.T) {
func TestSession_List(t *testing.T) { func TestSession_List(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
session := c.Session() session := c.Session()

View File

@ -6,7 +6,7 @@ import (
func TestStatusLeader(t *testing.T) { func TestStatusLeader(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
status := c.Status() status := c.Status()
@ -21,7 +21,7 @@ func TestStatusLeader(t *testing.T) {
func TestStatusPeers(t *testing.T) { func TestStatusPeers(t *testing.T) {
c, s := makeClient(t) c, s := makeClient(t)
defer s.stop() defer s.Stop()
status := c.Status() status := c.Status()

156
testutil/server.go Normal file
View File

@ -0,0 +1,156 @@
package testutil
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
"sync/atomic"
"testing"
)
var offset uint64
type TestPortConfig struct {
DNS int `json:"dns,omitempty"`
HTTP int `json:"http,omitempty"`
RPC int `json:"rpc,omitempty"`
SerfLan int `json:"serf_lan,omitempty"`
SerfWan int `json:"serf_wan,omitempty"`
Server int `json:"server,omitempty"`
}
type TestAddressConfig struct {
HTTP string `json:"http,omitempty"`
}
type TestServerConfig struct {
Bootstrap bool `json:"bootstrap,omitempty"`
Server bool `json:"server,omitempty"`
DataDir string `json:"data_dir,omitempty"`
LogLevel string `json:"log_level,omitempty"`
Addresses *TestAddressConfig `json:"addresses,omitempty"`
Ports *TestPortConfig `json:"ports,omitempty"`
}
type ServerConfigCallback func(c *TestServerConfig)
func defaultServerConfig() *TestServerConfig {
idx := int(atomic.AddUint64(&offset, 1))
return &TestServerConfig{
Bootstrap: true,
Server: true,
LogLevel: "debug",
Ports: &TestPortConfig{
DNS: 19000 + idx,
HTTP: 18800 + idx,
RPC: 18600 + idx,
SerfLan: 18200 + idx,
SerfWan: 18400 + idx,
Server: 18000 + idx,
},
}
}
type TestServer struct {
pid int
dataDir string
config *TestServerConfig
}
func NewTestServer(t *testing.T) *TestServer {
return NewTestServerConfig(t, nil)
}
func NewTestServerConfig(t *testing.T, cb ServerConfigCallback) *TestServer {
if path, err := exec.LookPath("consul"); err != nil || path == "" {
t.Log("consul not found on $PATH, skipping")
t.SkipNow()
}
dataDir, err := ioutil.TempDir("", "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
configFile, err := ioutil.TempFile("", "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.Remove(configFile.Name())
consulConfig := defaultServerConfig()
consulConfig.DataDir = dataDir
if cb != nil {
cb(consulConfig)
}
configContent, err := json.Marshal(consulConfig)
if err != nil {
t.Fatalf("err: %s", err)
}
if _, err := configFile.Write(configContent); err != nil {
t.Fatalf("err: %s", err)
}
configFile.Close()
// Start the server
cmd := exec.Command("consul", "agent", "-config-file", configFile.Name())
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
t.Fatalf("err: %s", err)
}
server := &TestServer{
config: consulConfig,
pid: cmd.Process.Pid,
dataDir: dataDir,
}
if err := server.waitForLeader(); err != nil {
t.Fatalf("err: %s", err)
}
return server
}
func (s *TestServer) Stop() {
defer os.RemoveAll(s.dataDir)
cmd := exec.Command("kill", "-9", fmt.Sprintf("%d", s.pid))
if err := cmd.Run(); err != nil {
panic(err)
}
}
func (s *TestServer) waitForLeader() error {
url := fmt.Sprintf("http://127.0.0.1:%d/v1/catalog/nodes", s.config.Ports.HTTP)
WaitForResult(func() (bool, error) {
resp, err := http.Get(url)
if err != nil {
return false, err
}
resp.Body.Close()
// Ensure we have a leader and a node registeration
if leader := resp.Header.Get("X-Consul-KnownLeader"); leader != "true" {
fmt.Println(leader)
return false, fmt.Errorf("Consul leader status: %#v", leader)
}
if resp.Header.Get("X-Consul-Index") == "0" {
return false, fmt.Errorf("Consul index is 0")
}
return true, nil
}, func(err error) {
panic(err)
})
return nil
}