agent/checks: reflect node failure as alias check failure

This commit is contained in:
Mitchell Hashimoto 2018-06-30 06:38:45 -07:00
parent f0658a0ede
commit 60c75b88da
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
2 changed files with 61 additions and 5 deletions

View File

@ -27,6 +27,7 @@ type CheckAlias struct {
CheckID types.CheckID // ID of this check CheckID types.CheckID // ID of this check
RPC RPC // Used to query remote server if necessary RPC RPC // Used to query remote server if necessary
RPCReq structs.NodeSpecificRequest // Base request
Notify CheckNotifier // For updating the check state Notify CheckNotifier // For updating the check state
stop bool stop bool
@ -55,7 +56,8 @@ func (c *CheckAlias) Stop() {
// run is invoked in a goroutine until Stop() is called. // run is invoked in a goroutine until Stop() is called.
func (c *CheckAlias) run(stopCh chan struct{}) { func (c *CheckAlias) run(stopCh chan struct{}) {
args := structs.NodeSpecificRequest{Node: c.Node} args := c.RPCReq
args.Node = c.Node
args.AllowStale = true args.AllowStale = true
args.MaxQueryTime = 1 * time.Minute args.MaxQueryTime = 1 * time.Minute
@ -112,7 +114,12 @@ func (c *CheckAlias) run(stopCh chan struct{}) {
msg = "No checks found." msg = "No checks found."
} }
for _, chk := range out.HealthChecks { for _, chk := range out.HealthChecks {
if chk.ServiceID != c.ServiceID || chk.Node != c.Node { if chk.Node != c.Node {
continue
}
// We allow ServiceID == "" so that we also check node checks
if chk.ServiceID != "" && chk.ServiceID != c.ServiceID {
continue continue
} }

View File

@ -67,6 +67,55 @@ func TestCheckAlias_remoteNoChecks(t *testing.T) {
}) })
} }
// If the node is critical then the check is critical
func TestCheckAlias_remoteNodeFailure(t *testing.T) {
t.Parallel()
notify := mock.NewNotify()
chkID := types.CheckID("foo")
rpc := &mockRPC{}
chk := &CheckAlias{
Node: "remote",
ServiceID: "web",
CheckID: chkID,
Notify: notify,
RPC: rpc,
}
rpc.Reply.Store(structs.IndexedHealthChecks{
HealthChecks: []*structs.HealthCheck{
// Should ignore non-matching node
&structs.HealthCheck{
Node: "A",
ServiceID: "web",
Status: api.HealthCritical,
},
// Node failure
&structs.HealthCheck{
Node: "remote",
ServiceID: "",
Status: api.HealthCritical,
},
// Match
&structs.HealthCheck{
Node: "remote",
ServiceID: "web",
Status: api.HealthPassing,
},
},
})
chk.Start()
defer chk.Stop()
retry.Run(t, func(r *retry.R) {
if got, want := notify.State(chkID), api.HealthCritical; got != want {
r.Fatalf("got state %q want %q", got, want)
}
})
}
// Only passing should result in passing // Only passing should result in passing
func TestCheckAlias_remotePassing(t *testing.T) { func TestCheckAlias_remotePassing(t *testing.T) {
t.Parallel() t.Parallel()