consul/api/health_test.go
Frank Schroeder 21a82a0a16
test: Refactor WaitForResult tests with retry
Refactor tests that use testutil.WaitForResult to use retry.

Since this requires refactoring the test functions in general this patch
also shows the use of the github.com/pascaldekloe/goe/verify library
which provides a good mechanism for comparing nested data structures.
Instead of just converting the tests from testutil.WaitForResult to
retry the tests that performing a nested comparison of data structures
are converted to the verify library at the same time.
2017-05-05 17:07:02 +02:00

355 lines
6.7 KiB
Go

package api
import (
"fmt"
"testing"
"github.com/hashicorp/consul/testutil"
"github.com/hashicorp/consul/testutil/retry"
"github.com/pascaldekloe/goe/verify"
)
func TestHealth_Node(t *testing.T) {
t.Parallel()
c, s := makeClient(t)
defer s.Stop()
agent := c.Agent()
health := c.Health()
info, err := agent.Self()
if err != nil {
t.Fatalf("err: %v", err)
}
name := info["Config"]["NodeName"].(string)
retry.Run("", t, func(r *retry.R) {
checks, meta, err := health.Node(name, nil)
if err != nil {
r.Fatal(err)
}
if meta.LastIndex == 0 {
r.Fatalf("bad: %v", meta)
}
if len(checks) == 0 {
r.Fatalf("bad: %v", checks)
}
})
}
func TestHealthChecks_AggregatedStatus(t *testing.T) {
t.Parallel()
cases := []struct {
name string
checks HealthChecks
exp string
}{
{
"empty",
nil,
HealthPassing,
},
{
"passing",
HealthChecks{
&HealthCheck{
Status: HealthPassing,
},
},
HealthPassing,
},
{
"warning",
HealthChecks{
&HealthCheck{
Status: HealthWarning,
},
},
HealthWarning,
},
{
"critical",
HealthChecks{
&HealthCheck{
Status: HealthCritical,
},
},
HealthCritical,
},
{
"node_maintenance",
HealthChecks{
&HealthCheck{
CheckID: NodeMaint,
},
},
HealthMaint,
},
{
"service_maintenance",
HealthChecks{
&HealthCheck{
CheckID: ServiceMaintPrefix + "service",
},
},
HealthMaint,
},
{
"unknown",
HealthChecks{
&HealthCheck{
Status: "nope-nope-noper",
},
},
"",
},
{
"maintenance_over_critical",
HealthChecks{
&HealthCheck{
CheckID: NodeMaint,
},
&HealthCheck{
Status: HealthCritical,
},
},
HealthMaint,
},
{
"critical_over_warning",
HealthChecks{
&HealthCheck{
Status: HealthCritical,
},
&HealthCheck{
Status: HealthWarning,
},
},
HealthCritical,
},
{
"warning_over_passing",
HealthChecks{
&HealthCheck{
Status: HealthWarning,
},
&HealthCheck{
Status: HealthPassing,
},
},
HealthWarning,
},
{
"lots",
HealthChecks{
&HealthCheck{
Status: HealthPassing,
},
&HealthCheck{
Status: HealthPassing,
},
&HealthCheck{
Status: HealthPassing,
},
&HealthCheck{
Status: HealthWarning,
},
},
HealthWarning,
},
}
for i, tc := range cases {
t.Run(fmt.Sprintf("%d_%s", i, tc.name), func(t *testing.T) {
act := tc.checks.AggregatedStatus()
if tc.exp != act {
t.Errorf("\nexp: %#v\nact: %#v", tc.exp, act)
}
})
}
}
func TestHealth_Checks(t *testing.T) {
t.Parallel()
c, s := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
conf.NodeName = "node123"
})
defer s.Stop()
agent := c.Agent()
health := c.Health()
// Make a service with a check
reg := &AgentServiceRegistration{
Name: "foo",
Tags: []string{"bar"},
Check: &AgentServiceCheck{
TTL: "15s",
},
}
if err := agent.ServiceRegister(reg); err != nil {
t.Fatalf("err: %v", err)
}
defer agent.ServiceDeregister("foo")
retry.Run("", t, func(r *retry.R) {
checks := HealthChecks{
&HealthCheck{
Node: "node123",
CheckID: "service:foo",
Name: "Service 'foo' check",
Status: "critical",
ServiceID: "foo",
ServiceName: "foo",
ServiceTags: []string{"bar"},
},
}
out, meta, err := health.Checks("foo", nil)
if err != nil {
r.Fatal(err)
}
if meta.LastIndex == 0 {
r.Fatalf("bad: %v", meta)
}
if got, want := out, checks; !verify.Values(t, "checks", got, want) {
r.Fatal("health.Checks failed")
}
})
}
func TestHealth_Checks_NodeMetaFilter(t *testing.T) {
t.Parallel()
meta := map[string]string{"somekey": "somevalue"}
c, s := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
conf.NodeMeta = meta
})
defer s.Stop()
agent := c.Agent()
health := c.Health()
// Make a service with a check
reg := &AgentServiceRegistration{
Name: "foo",
Check: &AgentServiceCheck{
TTL: "15s",
},
}
if err := agent.ServiceRegister(reg); err != nil {
t.Fatalf("err: %v", err)
}
defer agent.ServiceDeregister("foo")
retry.Run("", t, func(r *retry.R) {
checks, meta, err := health.Checks("foo", &QueryOptions{NodeMeta: meta})
if err != nil {
r.Fatal(err)
}
if meta.LastIndex == 0 {
r.Fatalf("bad: %v", meta)
}
if len(checks) == 0 {
r.Fatalf("Bad: %v", checks)
}
})
}
func TestHealth_Service(t *testing.T) {
c, s := makeClient(t)
defer s.Stop()
health := c.Health()
retry.Run("", t, func(r *retry.R) {
// consul service should always exist...
checks, meta, err := health.Service("consul", "", true, nil)
if err != nil {
r.Fatal(err)
}
if meta.LastIndex == 0 {
r.Fatalf("bad: %v", meta)
}
if len(checks) == 0 {
r.Fatalf("Bad: %v", checks)
}
if _, ok := checks[0].Node.TaggedAddresses["wan"]; !ok {
r.Fatalf("Bad: %v", checks[0].Node)
}
if checks[0].Node.Datacenter != "dc1" {
r.Fatalf("Bad datacenter: %v", checks[0].Node)
}
})
}
func TestHealth_Service_NodeMetaFilter(t *testing.T) {
meta := map[string]string{"somekey": "somevalue"}
c, s := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
conf.NodeMeta = meta
})
defer s.Stop()
health := c.Health()
retry.Run("", t, func(r *retry.R) {
// consul service should always exist...
checks, meta, err := health.Service("consul", "", true, &QueryOptions{NodeMeta: meta})
if err != nil {
r.Fatal(err)
}
if meta.LastIndex == 0 {
r.Fatalf("bad: %v", meta)
}
if len(checks) == 0 {
r.Fatalf("Bad: %v", checks)
}
if _, ok := checks[0].Node.TaggedAddresses["wan"]; !ok {
r.Fatalf("Bad: %v", checks[0].Node)
}
if checks[0].Node.Datacenter != "dc1" {
r.Fatalf("Bad datacenter: %v", checks[0].Node)
}
})
}
func TestHealth_State(t *testing.T) {
t.Parallel()
c, s := makeClient(t)
defer s.Stop()
health := c.Health()
retry.Run("", t, func(r *retry.R) {
checks, meta, err := health.State("any", nil)
if err != nil {
r.Fatal(err)
}
if meta.LastIndex == 0 {
r.Fatalf("bad: %v", meta)
}
if len(checks) == 0 {
r.Fatalf("Bad: %v", checks)
}
})
}
func TestHealth_State_NodeMetaFilter(t *testing.T) {
t.Parallel()
meta := map[string]string{"somekey": "somevalue"}
c, s := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
conf.NodeMeta = meta
})
defer s.Stop()
health := c.Health()
retry.Run("", t, func(r *retry.R) {
checks, meta, err := health.State("any", &QueryOptions{NodeMeta: meta})
if err != nil {
r.Fatal(err)
}
if meta.LastIndex == 0 {
r.Fatalf("bad: %v", meta)
}
if len(checks) == 0 {
r.Fatalf("Bad: %v", checks)
}
})
}