From 8455077e5d466af8856054721b1974fd8cd1c3e8 Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Tue, 6 Jan 2015 15:26:50 -0800 Subject: [PATCH] api: add harnessing for tests This is necessary as consul-api's tests require a real consul instance to be running. We can't directly import an agent to fire up an instance, due to the way this would create an import cycle. These tests instead will start a consul instance using the binary in $PATH (if it exists). --- api/acl_test.go | 16 +++++-- api/agent_test.go | 28 ++++++++--- api/api_test.go | 111 +++++++++++++++++++++++++++++++++++++++++--- api/catalog_test.go | 48 +++++++++---------- api/event_test.go | 4 +- api/health_test.go | 16 +++++-- api/kv_test.go | 30 ++++++++---- api/session_test.go | 20 ++++++-- api/status_test.go | 8 +++- 9 files changed, 218 insertions(+), 63 deletions(-) diff --git a/api/acl_test.go b/api/acl_test.go index e6a6ed64ce..166b892dbe 100644 --- a/api/acl_test.go +++ b/api/acl_test.go @@ -16,7 +16,9 @@ func TestACL_CreateDestroy(t *testing.T) { if CONSUL_ROOT == "" { t.SkipNow() } - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + c.config.Token = CONSUL_ROOT acl := c.ACL() @@ -62,7 +64,9 @@ func TestACL_CloneDestroy(t *testing.T) { if CONSUL_ROOT == "" { t.SkipNow() } - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + c.config.Token = CONSUL_ROOT acl := c.ACL() @@ -93,7 +97,9 @@ func TestACL_Info(t *testing.T) { if CONSUL_ROOT == "" { t.SkipNow() } - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + c.config.Token = CONSUL_ROOT acl := c.ACL() @@ -118,7 +124,9 @@ func TestACL_List(t *testing.T) { if CONSUL_ROOT == "" { t.SkipNow() } - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + c.config.Token = CONSUL_ROOT acl := c.ACL() diff --git a/api/agent_test.go b/api/agent_test.go index 77081679d9..06f8ca12e1 100644 --- a/api/agent_test.go +++ b/api/agent_test.go @@ -5,7 +5,9 @@ import ( ) func TestAgent_Self(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + agent := c.Agent() info, err := agent.Self() @@ -20,7 +22,9 @@ func TestAgent_Self(t *testing.T) { } func TestAgent_Members(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + agent := c.Agent() members, err := agent.Members(false) @@ -34,7 +38,9 @@ func TestAgent_Members(t *testing.T) { } func TestAgent_Services(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + agent := c.Agent() reg := &AgentServiceRegistration{ @@ -71,7 +77,9 @@ func TestAgent_Services(t *testing.T) { } func TestAgent_SetTTLStatus(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + agent := c.Agent() reg := &AgentServiceRegistration{ @@ -109,7 +117,9 @@ func TestAgent_SetTTLStatus(t *testing.T) { } func TestAgent_Checks(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + agent := c.Agent() reg := &AgentCheckRegistration{ @@ -134,7 +144,9 @@ func TestAgent_Checks(t *testing.T) { } func TestAgent_Join(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + agent := c.Agent() info, err := agent.Self() @@ -151,7 +163,9 @@ func TestAgent_Join(t *testing.T) { } func TestAgent_ForceLeave(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + agent := c.Agent() // Eject somebody diff --git a/api/api_test.go b/api/api_test.go index 19202dbf34..7d961bedaa 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -3,18 +3,111 @@ package api import ( crand "crypto/rand" "fmt" + "io/ioutil" "net/http" + "os" + "os/exec" "testing" "time" ) -func makeClient(t *testing.T) *Client { +var consulConfig = `{ + "ports": { + "http": 18800 + }, + "data_dir": "%s", + "bootstrap": true, + "server": true +}` + +type testServer struct { + pid int + dataDir string + configFile string +} + +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 { + 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) + } + configContent := fmt.Sprintf(consulConfig, dataDir) + if _, err := configFile.WriteString(configContent); err != nil { + t.Fatalf("err: %s", err) + } + configFile.Close() + + // Start the server + cmd := exec.Command("consul", "agent", "-config-file", configFile.Name()) + if err := cmd.Start(); err != nil { + t.Fatalf("err: %s", err) + } + + // Allow the server some time to start, and verify we have a leader. + client := new(http.Client) + for i := 0; ; i++ { + if i >= 20 { + t.Fatal("Server failed to start") + } + time.Sleep(100 * time.Millisecond) + + resp, err := client.Get("http://127.0.0.1:18800/v1/status/leader") + if err != nil { + continue + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil || len(body) == 2 { + continue + } + + break + } + + return &testServer{ + pid: cmd.Process.Pid, + dataDir: dataDir, + configFile: configFile.Name(), + } +} + +func makeClient(t *testing.T) (*Client, *testServer) { + server := newTestServer(t) conf := DefaultConfig() + conf.Address = "127.0.0.1:18800" client, err := NewClient(conf) if err != nil { t.Fatalf("err: %v", err) } - return client + return client, server } func testKey() string { @@ -32,7 +125,9 @@ func testKey() string { } func TestSetQueryOptions(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + r := c.newRequest("GET", "/v1/kv/foo") q := &QueryOptions{ Datacenter: "foo", @@ -65,7 +160,9 @@ func TestSetQueryOptions(t *testing.T) { } func TestSetWriteOptions(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + r := c.newRequest("GET", "/v1/kv/foo") q := &WriteOptions{ Datacenter: "foo", @@ -82,7 +179,9 @@ func TestSetWriteOptions(t *testing.T) { } func TestRequestToHTTP(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + r := c.newRequest("DELETE", "/v1/kv/foo") q := &QueryOptions{ Datacenter: "foo", @@ -96,7 +195,7 @@ func TestRequestToHTTP(t *testing.T) { if req.Method != "DELETE" { t.Fatalf("bad: %v", req) } - if req.URL.String() != "http://127.0.0.1:8500/v1/kv/foo?dc=foo" { + if req.URL.String() != "http://127.0.0.1:18800/v1/kv/foo?dc=foo" { t.Fatalf("bad: %v", req) } } diff --git a/api/catalog_test.go b/api/catalog_test.go index 0b93d78e9b..42b96bf523 100644 --- a/api/catalog_test.go +++ b/api/catalog_test.go @@ -5,7 +5,9 @@ import ( ) func TestCatalog_Datacenters(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + catalog := c.Catalog() datacenters, err := catalog.Datacenters() @@ -19,7 +21,9 @@ func TestCatalog_Datacenters(t *testing.T) { } func TestCatalog_Nodes(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + catalog := c.Catalog() nodes, meta, err := catalog.Nodes(nil) @@ -37,7 +41,9 @@ func TestCatalog_Nodes(t *testing.T) { } func TestCatalog_Services(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + catalog := c.Catalog() services, meta, err := catalog.Services(nil) @@ -55,7 +61,9 @@ func TestCatalog_Services(t *testing.T) { } func TestCatalog_Service(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + catalog := c.Catalog() services, meta, err := catalog.Service("consul", "", nil) @@ -73,7 +81,9 @@ func TestCatalog_Service(t *testing.T) { } func TestCatalog_Node(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + catalog := c.Catalog() name, _ := c.Agent().NodeName() @@ -91,7 +101,9 @@ func TestCatalog_Node(t *testing.T) { } func TestCatalog_Registration(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + catalog := c.Catalog() service := &AgentService{ @@ -143,11 +155,6 @@ func TestCatalog_Registration(t *testing.T) { if health[0].CheckID != "service:redis1" { t.Fatalf("missing checkid service:redis1") } -} - -func TestCatalog_Deregistration(t *testing.T) { - c := makeClient(t) - catalog := c.Catalog() dereg := &CatalogDeregistration{ Datacenter: "dc1", @@ -156,14 +163,11 @@ func TestCatalog_Deregistration(t *testing.T) { ServiceID: "redis1", } - _, err := catalog.Deregister(dereg, nil) - - if err != nil { + if _, err := catalog.Deregister(dereg, nil); err != nil { t.Fatalf("err: %v", err) } - node, _, err := catalog.Node("foobar", nil) - + node, _, err = catalog.Node("foobar", nil) if err != nil { t.Fatalf("err: %v", err) } @@ -179,14 +183,11 @@ func TestCatalog_Deregistration(t *testing.T) { CheckID: "service:redis1", } - _, err = catalog.Deregister(dereg, nil) - - if err != nil { + if _, err := catalog.Deregister(dereg, nil); err != nil { t.Fatalf("err: %v", err) } - health, _, err := c.Health().Node("foobar", nil) - + health, _, err = c.Health().Node("foobar", nil) if err != nil { t.Fatalf("err: %v", err) } @@ -201,14 +202,11 @@ func TestCatalog_Deregistration(t *testing.T) { Address: "192.168.10.10", } - _, err = catalog.Deregister(dereg, nil) - - if err != nil { + if _, err = catalog.Deregister(dereg, nil); err != nil { t.Fatalf("err: %v", err) } node, _, err = catalog.Node("foobar", nil) - if err != nil { t.Fatalf("err: %v", err) } diff --git a/api/event_test.go b/api/event_test.go index 0ff04e4947..974c40e42d 100644 --- a/api/event_test.go +++ b/api/event_test.go @@ -5,7 +5,9 @@ import ( ) func TestEvent_FireList(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + event := c.Event() params := &UserEvent{Name: "foo"} diff --git a/api/health_test.go b/api/health_test.go index 2daf1e9e44..03c66a3d90 100644 --- a/api/health_test.go +++ b/api/health_test.go @@ -6,7 +6,9 @@ import ( ) func TestHealth_Node(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + agent := c.Agent() health := c.Health() @@ -30,7 +32,9 @@ func TestHealth_Node(t *testing.T) { } func TestHealth_Checks(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + agent := c.Agent() health := c.Health() @@ -63,7 +67,9 @@ func TestHealth_Checks(t *testing.T) { } func TestHealth_Service(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + health := c.Health() // consul service should always exist... @@ -81,7 +87,9 @@ func TestHealth_Service(t *testing.T) { } func TestHealth_State(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + health := c.Health() checks, meta, err := health.State("any", nil) diff --git a/api/kv_test.go b/api/kv_test.go index 5dac389e20..1ed751320a 100644 --- a/api/kv_test.go +++ b/api/kv_test.go @@ -8,7 +8,9 @@ import ( ) func TestClientPutGetDelete(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + kv := c.KV() // Get a get without a key @@ -62,7 +64,9 @@ func TestClientPutGetDelete(t *testing.T) { } func TestClient_List_DeleteRecurse(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + kv := c.KV() // Generate some test keys @@ -114,7 +118,9 @@ func TestClient_List_DeleteRecurse(t *testing.T) { } func TestClient_CAS(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + kv := c.KV() // Put the key @@ -159,7 +165,9 @@ func TestClient_CAS(t *testing.T) { } func TestClient_WatchGet(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + kv := c.KV() // Get a get without a key @@ -178,7 +186,6 @@ func TestClient_WatchGet(t *testing.T) { // Put the key value := []byte("test") go func() { - c := makeClient(t) kv := c.KV() time.Sleep(100 * time.Millisecond) @@ -209,7 +216,9 @@ func TestClient_WatchGet(t *testing.T) { } func TestClient_WatchList(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + kv := c.KV() // Get a get without a key @@ -229,7 +238,6 @@ func TestClient_WatchList(t *testing.T) { // Put the key value := []byte("test") go func() { - c := makeClient(t) kv := c.KV() time.Sleep(100 * time.Millisecond) @@ -261,7 +269,9 @@ func TestClient_WatchList(t *testing.T) { } func TestClient_Keys_DeleteRecurse(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + kv := c.KV() // Generate some test keys @@ -308,7 +318,9 @@ func TestClient_Keys_DeleteRecurse(t *testing.T) { } func TestClient_AcquireRelease(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + session := c.Session() kv := c.KV() diff --git a/api/session_test.go b/api/session_test.go index 65060c933c..3579e48b1b 100644 --- a/api/session_test.go +++ b/api/session_test.go @@ -5,7 +5,9 @@ import ( ) func TestSession_CreateDestroy(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + session := c.Session() id, meta, err := session.Create(nil, nil) @@ -32,7 +34,9 @@ func TestSession_CreateDestroy(t *testing.T) { } func TestSession_CreateRenewDestroy(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + session := c.Session() se := &SessionEntry{ @@ -80,7 +84,9 @@ func TestSession_CreateRenewDestroy(t *testing.T) { } func TestSession_Info(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + session := c.Session() id, _, err := session.Create(nil, nil) @@ -131,7 +137,9 @@ func TestSession_Info(t *testing.T) { } func TestSession_Node(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + session := c.Session() id, _, err := session.Create(nil, nil) @@ -163,7 +171,9 @@ func TestSession_Node(t *testing.T) { } func TestSession_List(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + session := c.Session() id, _, err := session.Create(nil, nil) diff --git a/api/status_test.go b/api/status_test.go index 2488a47925..096b13da09 100644 --- a/api/status_test.go +++ b/api/status_test.go @@ -5,7 +5,9 @@ import ( ) func TestStatusLeader(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + status := c.Status() leader, err := status.Leader() @@ -18,7 +20,9 @@ func TestStatusLeader(t *testing.T) { } func TestStatusPeers(t *testing.T) { - c := makeClient(t) + c, s := makeClient(t) + defer s.stop() + status := c.Status() peers, err := status.Peers()