Merge pull request #1979 from hashicorp/b-checkapi-update

Update Check API to use constants
This commit is contained in:
Sean Chittenden 2016-04-23 20:20:36 -07:00
commit 5a1f60f85a
9 changed files with 93 additions and 72 deletions

View File

@ -198,27 +198,42 @@ func (a *Agent) ServiceDeregister(serviceID string) error {
return nil return nil
} }
// PassTTL is used to set a TTL check to the passing state // PassTTL is used to set a TTL check to the passing state.
//
// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL().
// The client interface will be removed in 0.8 or changed to use
// UpdateTTL()'s endpoint and the server endpoints will be removed in 0.9.
func (a *Agent) PassTTL(checkID, note string) error { func (a *Agent) PassTTL(checkID, note string) error {
return a.updateTTL(checkID, note, "pass") return a.updateTTL(checkID, note, "pass")
} }
// WarnTTL is used to set a TTL check to the warning state // WarnTTL is used to set a TTL check to the warning state.
//
// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL().
// The client interface will be removed in 0.8 or changed to use
// UpdateTTL()'s endpoint and the server endpoints will be removed in 0.9.
func (a *Agent) WarnTTL(checkID, note string) error { func (a *Agent) WarnTTL(checkID, note string) error {
return a.updateTTL(checkID, note, "warn") return a.updateTTL(checkID, note, "warn")
} }
// FailTTL is used to set a TTL check to the failing state // FailTTL is used to set a TTL check to the failing state.
//
// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL().
// The client interface will be removed in 0.8 or changed to use
// UpdateTTL()'s endpoint and the server endpoints will be removed in 0.9.
func (a *Agent) FailTTL(checkID, note string) error { func (a *Agent) FailTTL(checkID, note string) error {
return a.updateTTL(checkID, note, "fail") return a.updateTTL(checkID, note, "fail")
} }
// updateTTL is used to update the TTL of a check. This is the internal // updateTTL is used to update the TTL of a check. This is the internal
// method that uses the old API that's present in Consul versions prior // method that uses the old API that's present in Consul versions prior to
// to 0.6.4. Since Consul didn't have an analogous "update" API before it // 0.6.4. Since Consul didn't have an analogous "update" API before it seemed
// seemed ok to break this (former) UpdateTTL in favor of the new UpdateTTL // ok to break this (former) UpdateTTL in favor of the new UpdateTTL below,
// below, but keep the old Pass/Warn/Fail methods using the old API under the // but keep the old Pass/Warn/Fail methods using the old API under the hood.
// hood. //
// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL().
// The client interface will be removed in 0.8 and the server endpoints will
// be removed in 0.9.
func (a *Agent) updateTTL(checkID, note, status string) error { func (a *Agent) updateTTL(checkID, note, status string) error {
switch status { switch status {
case "pass": case "pass":
@ -240,8 +255,9 @@ func (a *Agent) updateTTL(checkID, note, status string) error {
// checkUpdate is the payload for a PUT for a check update. // checkUpdate is the payload for a PUT for a check update.
type checkUpdate struct { type checkUpdate struct {
// Status us one of the structs.Health* states, "passing", "warning", or // Status is one of the api.Health* states: HealthPassing
// "critical". // ("passing"), HealthWarning ("warning"), or HealthCritical
// ("critical").
Status string Status string
// Output is the information to post to the UI for operators as the // Output is the information to post to the UI for operators as the

View File

@ -76,7 +76,7 @@ func TestAgent_Services(t *testing.T) {
} }
// Checks should default to critical // Checks should default to critical
if chk.Status != "critical" { if chk.Status != HealthCritical {
t.Fatalf("Bad: %#v", chk) t.Fatalf("Bad: %#v", chk)
} }
@ -97,7 +97,7 @@ func TestAgent_Services_CheckPassing(t *testing.T) {
Port: 8000, Port: 8000,
Check: &AgentServiceCheck{ Check: &AgentServiceCheck{
TTL: "15s", TTL: "15s",
Status: "passing", Status: HealthPassing,
}, },
} }
if err := agent.ServiceRegister(reg); err != nil { if err := agent.ServiceRegister(reg); err != nil {
@ -121,7 +121,7 @@ func TestAgent_Services_CheckPassing(t *testing.T) {
t.Fatalf("missing check: %v", checks) t.Fatalf("missing check: %v", checks)
} }
if chk.Status != "passing" { if chk.Status != HealthPassing {
t.Fatalf("Bad: %#v", chk) t.Fatalf("Bad: %#v", chk)
} }
if err := agent.ServiceDeregister("foo"); err != nil { if err := agent.ServiceDeregister("foo"); err != nil {
@ -320,47 +320,47 @@ func TestAgent_SetTTLStatus(t *testing.T) {
if err := agent.WarnTTL("service:foo", "foo"); err != nil { if err := agent.WarnTTL("service:foo", "foo"); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
verify("warning", "foo") verify(HealthWarning, "foo")
if err := agent.PassTTL("service:foo", "bar"); err != nil { if err := agent.PassTTL("service:foo", "bar"); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
verify("passing", "bar") verify(HealthPassing, "bar")
if err := agent.FailTTL("service:foo", "baz"); err != nil { if err := agent.FailTTL("service:foo", "baz"); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
verify("critical", "baz") verify(HealthCritical, "baz")
if err := agent.UpdateTTL("service:foo", "foo", "warn"); err != nil { if err := agent.UpdateTTL("service:foo", "foo", "warn"); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
verify("warning", "foo") verify(HealthWarning, "foo")
if err := agent.UpdateTTL("service:foo", "bar", "pass"); err != nil { if err := agent.UpdateTTL("service:foo", "bar", "pass"); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
verify("passing", "bar") verify(HealthPassing, "bar")
if err := agent.UpdateTTL("service:foo", "baz", "fail"); err != nil { if err := agent.UpdateTTL("service:foo", "baz", "fail"); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
verify("critical", "baz") verify(HealthCritical, "baz")
if err := agent.UpdateTTL("service:foo", "foo", "warning"); err != nil { if err := agent.UpdateTTL("service:foo", "foo", HealthWarning); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
verify("warning", "foo") verify(HealthWarning, "foo")
if err := agent.UpdateTTL("service:foo", "bar", "passing"); err != nil { if err := agent.UpdateTTL("service:foo", "bar", HealthPassing); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
verify("passing", "bar") verify(HealthPassing, "bar")
if err := agent.UpdateTTL("service:foo", "baz", "critical"); err != nil { if err := agent.UpdateTTL("service:foo", "baz", HealthCritical); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
verify("critical", "baz") verify(HealthCritical, "baz")
if err := agent.ServiceDeregister("foo"); err != nil { if err := agent.ServiceDeregister("foo"); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
@ -390,7 +390,7 @@ func TestAgent_Checks(t *testing.T) {
if !ok { if !ok {
t.Fatalf("missing check: %v", checks) t.Fatalf("missing check: %v", checks)
} }
if chk.Status != "critical" { if chk.Status != HealthCritical {
t.Fatalf("check not critical: %v", chk) t.Fatalf("check not critical: %v", chk)
} }
@ -409,7 +409,7 @@ func TestAgent_CheckStartPassing(t *testing.T) {
reg := &AgentCheckRegistration{ reg := &AgentCheckRegistration{
Name: "foo", Name: "foo",
AgentServiceCheck: AgentServiceCheck{ AgentServiceCheck: AgentServiceCheck{
Status: "passing", Status: HealthPassing,
}, },
} }
reg.TTL = "15s" reg.TTL = "15s"
@ -425,7 +425,7 @@ func TestAgent_CheckStartPassing(t *testing.T) {
if !ok { if !ok {
t.Fatalf("missing check: %v", checks) t.Fatalf("missing check: %v", checks)
} }
if chk.Status != "passing" { if chk.Status != HealthPassing {
t.Fatalf("check not passing: %v", chk) t.Fatalf("check not passing: %v", chk)
} }
@ -580,7 +580,7 @@ func TestServiceMaintenance(t *testing.T) {
for _, check := range checks { for _, check := range checks {
if strings.Contains(check.CheckID, "maintenance") { if strings.Contains(check.CheckID, "maintenance") {
found = true found = true
if check.Status != "critical" || check.Notes != "broken" { if check.Status != HealthCritical || check.Notes != "broken" {
t.Fatalf("bad: %#v", checks) t.Fatalf("bad: %#v", checks)
} }
} }
@ -627,7 +627,7 @@ func TestNodeMaintenance(t *testing.T) {
for _, check := range checks { for _, check := range checks {
if strings.Contains(check.CheckID, "maintenance") { if strings.Contains(check.CheckID, "maintenance") {
found = true found = true
if check.Status != "critical" || check.Notes != "broken" { if check.Status != HealthCritical || check.Notes != "broken" {
t.Fatalf("bad: %#v", checks) t.Fatalf("bad: %#v", checks)
} }
} }

View File

@ -157,7 +157,7 @@ func TestCatalog_Registration(t *testing.T) {
CheckID: "service:redis1", CheckID: "service:redis1",
Name: "Redis health check", Name: "Redis health check",
Notes: "Script based health check", Notes: "Script based health check",
Status: "passing", Status: HealthPassing,
ServiceID: "redis1", ServiceID: "redis1",
} }

View File

@ -526,9 +526,9 @@ func TestHTTPAgentUpdateCheck(t *testing.T) {
} }
cases := []checkUpdate{ cases := []checkUpdate{
checkUpdate{"passing", "hello-passing"}, checkUpdate{structs.HealthPassing, "hello-passing"},
checkUpdate{"critical", "hello-critical"}, checkUpdate{structs.HealthCritical, "hello-critical"},
checkUpdate{"warning", "hello-warning"}, checkUpdate{structs.HealthWarning, "hello-warning"},
} }
for _, c := range cases { for _, c := range cases {
@ -564,7 +564,7 @@ func TestHTTPAgentUpdateCheck(t *testing.T) {
} }
update := checkUpdate{ update := checkUpdate{
Status: "passing", Status: structs.HealthPassing,
Output: strings.Repeat("-= bad -=", 5*CheckBufSize), Output: strings.Repeat("-= bad -=", 5*CheckBufSize),
} }
req.Body = encodeReq(update) req.Body = encodeReq(update)
@ -623,7 +623,7 @@ func TestHTTPAgentUpdateCheck(t *testing.T) {
} }
update := checkUpdate{ update := checkUpdate{
Status: "passing", Status: structs.HealthPassing,
} }
req.Body = encodeReq(update) req.Body = encodeReq(update)

View File

@ -235,25 +235,25 @@ func TestCheckHTTPCritical(t *testing.T) {
server := mockHTTPServer(150) server := mockHTTPServer(150)
fmt.Println(server.URL) fmt.Println(server.URL)
expectHTTPStatus(t, server.URL, "critical") expectHTTPStatus(t, server.URL, structs.HealthCritical)
server.Close() server.Close()
// 2xx - 1 // 2xx - 1
server = mockHTTPServer(199) server = mockHTTPServer(199)
expectHTTPStatus(t, server.URL, "critical") expectHTTPStatus(t, server.URL, structs.HealthCritical)
server.Close() server.Close()
// 2xx + 1 // 2xx + 1
server = mockHTTPServer(300) server = mockHTTPServer(300)
expectHTTPStatus(t, server.URL, "critical") expectHTTPStatus(t, server.URL, structs.HealthCritical)
server.Close() server.Close()
server = mockHTTPServer(400) server = mockHTTPServer(400)
expectHTTPStatus(t, server.URL, "critical") expectHTTPStatus(t, server.URL, structs.HealthCritical)
server.Close() server.Close()
server = mockHTTPServer(500) server = mockHTTPServer(500)
expectHTTPStatus(t, server.URL, "critical") expectHTTPStatus(t, server.URL, structs.HealthCritical)
server.Close() server.Close()
} }
@ -261,25 +261,25 @@ func TestCheckHTTPPassing(t *testing.T) {
var server *httptest.Server var server *httptest.Server
server = mockHTTPServer(200) server = mockHTTPServer(200)
expectHTTPStatus(t, server.URL, "passing") expectHTTPStatus(t, server.URL, structs.HealthPassing)
server.Close() server.Close()
server = mockHTTPServer(201) server = mockHTTPServer(201)
expectHTTPStatus(t, server.URL, "passing") expectHTTPStatus(t, server.URL, structs.HealthPassing)
server.Close() server.Close()
server = mockHTTPServer(250) server = mockHTTPServer(250)
expectHTTPStatus(t, server.URL, "passing") expectHTTPStatus(t, server.URL, structs.HealthPassing)
server.Close() server.Close()
server = mockHTTPServer(299) server = mockHTTPServer(299)
expectHTTPStatus(t, server.URL, "passing") expectHTTPStatus(t, server.URL, structs.HealthPassing)
server.Close() server.Close()
} }
func TestCheckHTTPWarning(t *testing.T) { func TestCheckHTTPWarning(t *testing.T) {
server := mockHTTPServer(429) server := mockHTTPServer(429)
expectHTTPStatus(t, server.URL, "warning") expectHTTPStatus(t, server.URL, structs.HealthWarning)
server.Close() server.Close()
} }
@ -323,7 +323,7 @@ func TestCheckHTTPTimeout(t *testing.T) {
t.Fatalf("should have at least 2 updates %v", mock.updates) t.Fatalf("should have at least 2 updates %v", mock.updates)
} }
if mock.state["bar"] != "critical" { if mock.state["bar"] != structs.HealthCritical {
t.Fatalf("should be critical %v", mock.state) t.Fatalf("should be critical %v", mock.state)
} }
} }
@ -397,7 +397,7 @@ func TestCheckTCPCritical(t *testing.T) {
) )
tcpServer = mockTCPServer(`tcp`) tcpServer = mockTCPServer(`tcp`)
expectTCPStatus(t, `127.0.0.1:0`, "critical") expectTCPStatus(t, `127.0.0.1:0`, structs.HealthCritical)
tcpServer.Close() tcpServer.Close()
} }
@ -407,11 +407,11 @@ func TestCheckTCPPassing(t *testing.T) {
) )
tcpServer = mockTCPServer(`tcp`) tcpServer = mockTCPServer(`tcp`)
expectTCPStatus(t, tcpServer.Addr().String(), "passing") expectTCPStatus(t, tcpServer.Addr().String(), structs.HealthPassing)
tcpServer.Close() tcpServer.Close()
tcpServer = mockTCPServer(`tcp6`) tcpServer = mockTCPServer(`tcp6`)
expectTCPStatus(t, tcpServer.Addr().String(), "passing") expectTCPStatus(t, tcpServer.Addr().String(), structs.HealthPassing)
tcpServer.Close() tcpServer.Close()
} }
@ -579,27 +579,27 @@ func expectDockerCheckStatus(t *testing.T, dockerClient DockerClient, status str
} }
func TestDockerCheckWhenExecReturnsSuccessExitCode(t *testing.T) { func TestDockerCheckWhenExecReturnsSuccessExitCode(t *testing.T) {
expectDockerCheckStatus(t, &fakeDockerClientWithNoErrors{}, "passing", "output") expectDockerCheckStatus(t, &fakeDockerClientWithNoErrors{}, structs.HealthPassing, "output")
} }
func TestDockerCheckWhenExecCreationFails(t *testing.T) { func TestDockerCheckWhenExecCreationFails(t *testing.T) {
expectDockerCheckStatus(t, &fakeDockerClientWithCreateExecFailure{}, "critical", "Unable to create Exec, error: Exec Creation Failed") expectDockerCheckStatus(t, &fakeDockerClientWithCreateExecFailure{}, structs.HealthCritical, "Unable to create Exec, error: Exec Creation Failed")
} }
func TestDockerCheckWhenExitCodeIsNonZero(t *testing.T) { func TestDockerCheckWhenExitCodeIsNonZero(t *testing.T) {
expectDockerCheckStatus(t, &fakeDockerClientWithExecNonZeroExitCode{}, "critical", "") expectDockerCheckStatus(t, &fakeDockerClientWithExecNonZeroExitCode{}, structs.HealthCritical, "")
} }
func TestDockerCheckWhenExitCodeIsone(t *testing.T) { func TestDockerCheckWhenExitCodeIsone(t *testing.T) {
expectDockerCheckStatus(t, &fakeDockerClientWithExecExitCodeOne{}, "warning", "output") expectDockerCheckStatus(t, &fakeDockerClientWithExecExitCodeOne{}, structs.HealthWarning, "output")
} }
func TestDockerCheckWhenExecStartFails(t *testing.T) { func TestDockerCheckWhenExecStartFails(t *testing.T) {
expectDockerCheckStatus(t, &fakeDockerClientWithStartExecFailure{}, "critical", "Unable to start Exec: Couldn't Start Exec") expectDockerCheckStatus(t, &fakeDockerClientWithStartExecFailure{}, structs.HealthCritical, "Unable to start Exec: Couldn't Start Exec")
} }
func TestDockerCheckWhenExecInfoFails(t *testing.T) { func TestDockerCheckWhenExecInfoFails(t *testing.T) {
expectDockerCheckStatus(t, &fakeDockerClientWithExecInfoErrors{}, "critical", "Unable to inspect Exec: Unable to query exec info") expectDockerCheckStatus(t, &fakeDockerClientWithExecInfoErrors{}, structs.HealthCritical, "Unable to inspect Exec: Unable to query exec info")
} }
func TestDockerCheckDefaultToSh(t *testing.T) { func TestDockerCheckDefaultToSh(t *testing.T) {

View File

@ -1,9 +1,10 @@
package agent package agent
import ( import (
"github.com/hashicorp/consul/consul/structs"
"net/http" "net/http"
"strings" "strings"
"github.com/hashicorp/consul/consul/structs"
) )
func (s *HTTPServer) HealthChecksInState(resp http.ResponseWriter, req *http.Request) (interface{}, error) { func (s *HTTPServer) HealthChecksInState(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
@ -126,7 +127,7 @@ func (s *HTTPServer) HealthServiceNodes(resp http.ResponseWriter, req *http.Requ
} }
// Filter to only passing if specified // Filter to only passing if specified
if _, ok := params["passing"]; ok { if _, ok := params[structs.HealthPassing]; ok {
out.Nodes = filterNonPassing(out.Nodes) out.Nodes = filterNonPassing(out.Nodes)
} }

View File

@ -13,14 +13,16 @@ from Consul's core and API client, meaning it can be easily imported and used in
external unit tests for various applications. It works by invoking the Consul external unit tests for various applications. It works by invoking the Consul
CLI, which means it is a requirement to have Consul installed in the `$PATH`. CLI, which means it is a requirement to have Consul installed in the `$PATH`.
Following is some example usage: Following is an example usage:
```go ```go
package main package my_program
import ( import (
"github.com/hashicorp/consul/testutil"
"testing" "testing"
"github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/consul/testutil"
) )
func TestMain(t *testing.T) { func TestMain(t *testing.T) {
@ -48,13 +50,13 @@ func TestMain(t *testing.T) {
}) })
// Create a service // Create a service
srv1.AddService("redis", "passing", []string{"master"}) srv1.AddService("redis", structs.HealthPassing, []string{"master"})
// Create a service check // Create a service check
srv1.AddCheck("service:redis", "redis", "passing") srv1.AddCheck("service:redis", "redis", structs.HealthPassing)
// Create a node check // Create a node check
srv1.AddCheck("mem", "", "critical") srv1.AddCheck("mem", "", structs.HealthCritical)
// The HTTPAddr field contains the address of the Consul // The HTTPAddr field contains the address of the Consul
// API on the new test server instance. // API on the new test server instance.

View File

@ -25,6 +25,7 @@ import (
"strings" "strings"
"sync/atomic" "sync/atomic"
"github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-cleanhttp"
) )
@ -444,11 +445,11 @@ func (s *TestServer) AddService(name, status string, tags []string) {
s.put("/v1/agent/check/register", payload) s.put("/v1/agent/check/register", payload)
switch status { switch status {
case "passing": case structs.HealthPassing:
s.put("/v1/agent/check/pass/"+chkName, nil) s.put("/v1/agent/check/pass/"+chkName, nil)
case "warning": case structs.HealthWarning:
s.put("/v1/agent/check/warn/"+chkName, nil) s.put("/v1/agent/check/warn/"+chkName, nil)
case "critical": case structs.HealthCritical:
s.put("/v1/agent/check/fail/"+chkName, nil) s.put("/v1/agent/check/fail/"+chkName, nil)
default: default:
s.t.Fatalf("Unrecognized status: %s", status) s.t.Fatalf("Unrecognized status: %s", status)
@ -472,11 +473,11 @@ func (s *TestServer) AddCheck(name, serviceID, status string) {
s.put("/v1/agent/check/register", payload) s.put("/v1/agent/check/register", payload)
switch status { switch status {
case "passing": case structs.HealthPassing:
s.put("/v1/agent/check/pass/"+name, nil) s.put("/v1/agent/check/pass/"+name, nil)
case "warning": case structs.HealthWarning:
s.put("/v1/agent/check/warn/"+name, nil) s.put("/v1/agent/check/warn/"+name, nil)
case "critical": case structs.HealthCritical:
s.put("/v1/agent/check/fail/"+name, nil) s.put("/v1/agent/check/fail/"+name, nil)
default: default:
s.t.Fatalf("Unrecognized status: %s", status) s.t.Fatalf("Unrecognized status: %s", status)

View File

@ -6,6 +6,7 @@ import (
"time" "time"
consulapi "github.com/hashicorp/consul/api" consulapi "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/consul/structs"
) )
var consulAddr string var consulAddr string
@ -299,7 +300,7 @@ func TestChecksWatch_State(t *testing.T) {
Node: "foobar", Node: "foobar",
CheckID: "foobar", CheckID: "foobar",
Name: "foobar", Name: "foobar",
Status: "warning", Status: structs.HealthWarning,
}, },
} }
catalog.Register(reg, nil) catalog.Register(reg, nil)
@ -363,7 +364,7 @@ func TestChecksWatch_Service(t *testing.T) {
Node: "foobar", Node: "foobar",
CheckID: "foobar", CheckID: "foobar",
Name: "foobar", Name: "foobar",
Status: "passing", Status: structs.HealthPassing,
ServiceID: "foobar", ServiceID: "foobar",
}, },
} }