mirror of https://github.com/status-im/consul.git
Implementing the health methods with tests
This commit is contained in:
parent
c6c0f34fe8
commit
2b79c125f2
|
@ -388,7 +388,6 @@ func parseServiceNodes(tx *MDBTxn, table *MDBTable, res []interface{}, err error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("Failed to get node services: %v", err))
|
panic(fmt.Errorf("Failed to get node services: %v", err))
|
||||||
}
|
}
|
||||||
println(fmt.Sprintf("res: %#v", res))
|
|
||||||
|
|
||||||
nodes := make(structs.ServiceNodes, len(res))
|
nodes := make(structs.ServiceNodes, len(res))
|
||||||
for i, r := range res {
|
for i, r := range res {
|
||||||
|
@ -408,8 +407,47 @@ func parseServiceNodes(tx *MDBTxn, table *MDBTable, res []interface{}, err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureCheck is used to create a check or updates it's state
|
// EnsureCheck is used to create a check or updates it's state
|
||||||
func (s *StateStore) EnsureCheck() error {
|
func (s *StateStore) EnsureCheck(check *structs.HealthCheck) error {
|
||||||
return nil
|
// Ensure we have a status
|
||||||
|
if check.Status == "" {
|
||||||
|
check.Status = structs.HealthUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the txn
|
||||||
|
tx, err := s.tables.StartTxn(false)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("Failed to start txn: %v", err))
|
||||||
|
}
|
||||||
|
defer tx.Abort()
|
||||||
|
|
||||||
|
// Ensure the node exists
|
||||||
|
res, err := s.nodeTable.GetTxn(tx, "id", check.Node)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(res) == 0 {
|
||||||
|
return fmt.Errorf("Missing node registration")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the service exists if specified
|
||||||
|
if check.ServiceID != "" {
|
||||||
|
res, err = s.serviceTable.GetTxn(tx, "id", check.Node, check.ServiceID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(res) == 0 {
|
||||||
|
return fmt.Errorf("Missing service registration")
|
||||||
|
}
|
||||||
|
// Ensure we set the correct service
|
||||||
|
srv := res[0].(*structs.ServiceNode)
|
||||||
|
check.ServiceName = srv.ServiceName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the check is set
|
||||||
|
if err := s.checkTable.InsertTxn(tx, check); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteNodeCheck is used to delete a node health check
|
// DeleteNodeCheck is used to delete a node health check
|
||||||
|
@ -419,18 +457,31 @@ func (s *StateStore) DeleteNodeCheck(node, id string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeChecks is used to get all the checks for a node
|
// NodeChecks is used to get all the checks for a node
|
||||||
func (s *StateStore) NodeChecks(name string) structs.HealthChecks {
|
func (s *StateStore) NodeChecks(node string) structs.HealthChecks {
|
||||||
return nil
|
return parseHealthChecks(s.checkTable.Get("id", node))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceChecks is used to get all the checks for a service
|
// ServiceChecks is used to get all the checks for a service
|
||||||
func (s *StateStore) ServiceChecks(name string) structs.HealthChecks {
|
func (s *StateStore) ServiceChecks(service string) structs.HealthChecks {
|
||||||
return nil
|
return parseHealthChecks(s.checkTable.Get("service", service))
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckInState is used to get all the checks for a service in a given state
|
// CheckInState is used to get all the checks for a service in a given state
|
||||||
func (s *StateStore) ChecksInState(name string) structs.HealthChecks {
|
func (s *StateStore) ChecksInState(state string) structs.HealthChecks {
|
||||||
return nil
|
return parseHealthChecks(s.checkTable.Get("status", state))
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseHealthChecks is used to handle the resutls of a Get against
|
||||||
|
// the checkTable
|
||||||
|
func parseHealthChecks(res []interface{}, err error) structs.HealthChecks {
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("Failed to get checks: %v", err))
|
||||||
|
}
|
||||||
|
results := make([]*structs.HealthCheck, len(res))
|
||||||
|
for i, r := range res {
|
||||||
|
results[i] = r.(*structs.HealthCheck)
|
||||||
|
}
|
||||||
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot is used to create a point in time snapshot
|
// Snapshot is used to create a point in time snapshot
|
||||||
|
|
|
@ -2,6 +2,7 @@ package consul
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/consul/consul/structs"
|
"github.com/hashicorp/consul/consul/structs"
|
||||||
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -163,6 +164,17 @@ func TestDeleteNodeService(t *testing.T) {
|
||||||
t.Fatalf("err: %v", err)
|
t.Fatalf("err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check := &structs.HealthCheck{
|
||||||
|
Node: "foo",
|
||||||
|
CheckID: "api",
|
||||||
|
Name: "Can connect",
|
||||||
|
Status: structs.HealthPassing,
|
||||||
|
ServiceID: "api",
|
||||||
|
}
|
||||||
|
if err := store.EnsureCheck(check); err != nil {
|
||||||
|
t.Fatalf("err: %v")
|
||||||
|
}
|
||||||
|
|
||||||
if err := store.DeleteNodeService("foo", "api"); err != nil {
|
if err := store.DeleteNodeService("foo", "api"); err != nil {
|
||||||
t.Fatalf("err: %v", err)
|
t.Fatalf("err: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -172,6 +184,11 @@ func TestDeleteNodeService(t *testing.T) {
|
||||||
if ok {
|
if ok {
|
||||||
t.Fatalf("has api: %#v", services)
|
t.Fatalf("has api: %#v", services)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checks := store.NodeChecks("foo")
|
||||||
|
if len(checks) != 0 {
|
||||||
|
t.Fatalf("has check: %#v", checks)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteNodeService_One(t *testing.T) {
|
func TestDeleteNodeService_One(t *testing.T) {
|
||||||
|
@ -223,8 +240,19 @@ func TestDeleteNode(t *testing.T) {
|
||||||
t.Fatalf("err: %v")
|
t.Fatalf("err: %v")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check := &structs.HealthCheck{
|
||||||
|
Node: "foo",
|
||||||
|
CheckID: "db",
|
||||||
|
Name: "Can connect",
|
||||||
|
Status: structs.HealthPassing,
|
||||||
|
ServiceID: "api",
|
||||||
|
}
|
||||||
|
if err := store.EnsureCheck(check); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := store.DeleteNode("foo"); err != nil {
|
if err := store.DeleteNode("foo"); err != nil {
|
||||||
t.Fatalf("err: %v")
|
t.Fatalf("err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
services := store.NodeServices("foo")
|
services := store.NodeServices("foo")
|
||||||
|
@ -233,6 +261,11 @@ func TestDeleteNode(t *testing.T) {
|
||||||
t.Fatalf("has api: %#v", services)
|
t.Fatalf("has api: %#v", services)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checks := store.NodeChecks("foo")
|
||||||
|
if len(checks) > 0 {
|
||||||
|
t.Fatalf("has checks: %v", checks)
|
||||||
|
}
|
||||||
|
|
||||||
found, _ := store.GetNode("foo")
|
found, _ := store.GetNode("foo")
|
||||||
if found {
|
if found {
|
||||||
t.Fatalf("found node")
|
t.Fatalf("found node")
|
||||||
|
@ -504,3 +537,120 @@ func TestStoreSnapshot(t *testing.T) {
|
||||||
t.Fatalf("bad: %v", services)
|
t.Fatalf("bad: %v", services)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnsureCheck(t *testing.T) {
|
||||||
|
store, err := NewStateStore()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
defer store.Close()
|
||||||
|
|
||||||
|
if err := store.EnsureNode(structs.Node{"foo", "127.0.0.1"}); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
if err := store.EnsureService("foo", "db1", "db", "master", 8000); err != nil {
|
||||||
|
t.Fatalf("err: %v")
|
||||||
|
}
|
||||||
|
check := &structs.HealthCheck{
|
||||||
|
Node: "foo",
|
||||||
|
CheckID: "db",
|
||||||
|
Name: "Can connect",
|
||||||
|
Status: structs.HealthPassing,
|
||||||
|
ServiceID: "db1",
|
||||||
|
}
|
||||||
|
if err := store.EnsureCheck(check); err != nil {
|
||||||
|
t.Fatalf("err: %v")
|
||||||
|
}
|
||||||
|
|
||||||
|
check2 := &structs.HealthCheck{
|
||||||
|
Node: "foo",
|
||||||
|
CheckID: "memory",
|
||||||
|
Name: "memory utilization",
|
||||||
|
Status: structs.HealthWarning,
|
||||||
|
}
|
||||||
|
if err := store.EnsureCheck(check2); err != nil {
|
||||||
|
t.Fatalf("err: %v")
|
||||||
|
}
|
||||||
|
|
||||||
|
checks := store.NodeChecks("foo")
|
||||||
|
if len(checks) != 2 {
|
||||||
|
t.Fatalf("bad: %v", checks)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(checks[0], check) {
|
||||||
|
t.Fatalf("bad: %v", checks[0])
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(checks[1], check2) {
|
||||||
|
t.Fatalf("bad: %v", checks[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
checks = store.ServiceChecks("db")
|
||||||
|
if len(checks) != 1 {
|
||||||
|
t.Fatalf("bad: %v", checks)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(checks[0], check) {
|
||||||
|
t.Fatalf("bad: %v", checks[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
checks = store.ChecksInState(structs.HealthPassing)
|
||||||
|
if len(checks) != 1 {
|
||||||
|
t.Fatalf("bad: %v", checks)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(checks[0], check) {
|
||||||
|
t.Fatalf("bad: %v", checks[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
checks = store.ChecksInState(structs.HealthWarning)
|
||||||
|
if len(checks) != 1 {
|
||||||
|
t.Fatalf("bad: %v", checks)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(checks[0], check2) {
|
||||||
|
t.Fatalf("bad: %v", checks[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteNodeCheck(t *testing.T) {
|
||||||
|
store, err := NewStateStore()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
defer store.Close()
|
||||||
|
|
||||||
|
if err := store.EnsureNode(structs.Node{"foo", "127.0.0.1"}); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
if err := store.EnsureService("foo", "db1", "db", "master", 8000); err != nil {
|
||||||
|
t.Fatalf("err: %v")
|
||||||
|
}
|
||||||
|
check := &structs.HealthCheck{
|
||||||
|
Node: "foo",
|
||||||
|
CheckID: "db",
|
||||||
|
Name: "Can connect",
|
||||||
|
Status: structs.HealthPassing,
|
||||||
|
ServiceID: "db1",
|
||||||
|
}
|
||||||
|
if err := store.EnsureCheck(check); err != nil {
|
||||||
|
t.Fatalf("err: %v")
|
||||||
|
}
|
||||||
|
|
||||||
|
check2 := &structs.HealthCheck{
|
||||||
|
Node: "foo",
|
||||||
|
CheckID: "memory",
|
||||||
|
Name: "memory utilization",
|
||||||
|
Status: structs.HealthWarning,
|
||||||
|
}
|
||||||
|
if err := store.EnsureCheck(check2); err != nil {
|
||||||
|
t.Fatalf("err: %v")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := store.DeleteNodeCheck("foo", "db"); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
checks := store.NodeChecks("foo")
|
||||||
|
if len(checks) != 1 {
|
||||||
|
t.Fatalf("bad: %v", checks)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(checks[0], check2) {
|
||||||
|
t.Fatalf("bad: %v", checks[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue