2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2019-09-26 02:55:52 +00:00
|
|
|
package agent
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-12-10 02:26:41 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2020-11-30 17:53:46 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2019-09-26 02:55:52 +00:00
|
|
|
"github.com/hashicorp/consul/agent/cache"
|
|
|
|
cachetype "github.com/hashicorp/consul/agent/cache-types"
|
|
|
|
"github.com/hashicorp/consul/agent/checks"
|
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
|
|
"github.com/hashicorp/consul/testrpc"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Integration test for ServiceHTTPBasedChecks cache-type
|
|
|
|
// Placed in agent pkg rather than cache-types to avoid circular dependency when importing agent.TestAgent
|
|
|
|
func TestAgent_ServiceHTTPChecksNotification(t *testing.T) {
|
2020-12-07 18:42:55 +00:00
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("too slow for testing.Short")
|
|
|
|
}
|
|
|
|
|
2019-09-26 02:55:52 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2020-03-31 19:59:56 +00:00
|
|
|
a := NewTestAgent(t, "")
|
2019-09-26 02:55:52 +00:00
|
|
|
defer a.Shutdown()
|
|
|
|
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
|
|
|
|
|
|
|
|
service := structs.NodeService{
|
|
|
|
ID: "web",
|
|
|
|
Service: "web",
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
ch := make(chan cache.UpdateEvent)
|
|
|
|
|
|
|
|
// Watch for service check updates
|
|
|
|
err := a.cache.Notify(ctx, cachetype.ServiceHTTPChecksName, &cachetype.ServiceHTTPChecksRequest{
|
|
|
|
ServiceID: service.ID,
|
2022-10-12 14:49:56 +00:00
|
|
|
NodeName: a.Config.NodeName,
|
2019-09-26 02:55:52 +00:00
|
|
|
}, "service-checks:"+service.ID, ch)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to set cache notification: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
chkTypes := []*structs.CheckType{
|
|
|
|
{
|
|
|
|
CheckID: "http-check",
|
|
|
|
HTTP: "localhost:8080/health",
|
|
|
|
Interval: 5 * time.Second,
|
|
|
|
OutputMaxSize: checks.DefaultBufSize,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
CheckID: "grpc-check",
|
|
|
|
GRPC: "localhost:9090/v1.Health",
|
|
|
|
Interval: 5 * time.Second,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
CheckID: "ttl-check",
|
|
|
|
TTL: 10 * time.Second,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
// Adding TTL type should lead to a timeout, since only HTTP-based checks are watched
|
2020-11-30 18:26:58 +00:00
|
|
|
if err := a.addServiceFromSource(&service, chkTypes[2:], false, "", ConfigSourceLocal); err != nil {
|
2019-09-26 02:55:52 +00:00
|
|
|
t.Fatalf("failed to add service: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var val cache.UpdateEvent
|
|
|
|
select {
|
|
|
|
case val = <-ch:
|
|
|
|
t.Fatal("got cache update for TTL check, expected timeout")
|
|
|
|
case <-time.After(100 * time.Millisecond):
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adding service with HTTP checks should lead notification for them
|
2020-11-30 18:26:58 +00:00
|
|
|
if err := a.addServiceFromSource(&service, chkTypes[0:2], false, "", ConfigSourceLocal); err != nil {
|
2019-09-26 02:55:52 +00:00
|
|
|
t.Fatalf("failed to add service: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case val = <-ch:
|
|
|
|
case <-time.After(100 * time.Millisecond):
|
|
|
|
t.Fatal("didn't get cache update event")
|
|
|
|
}
|
|
|
|
|
|
|
|
got, ok := val.Result.([]structs.CheckType)
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("notified of result of wrong type, got %T, want []structs.CheckType", got)
|
|
|
|
}
|
|
|
|
want := chkTypes[0:2]
|
|
|
|
for i, c := range want {
|
|
|
|
require.Equal(t, *c, got[i])
|
|
|
|
}
|
|
|
|
|
|
|
|
// Removing the GRPC check should leave only the HTTP check
|
2019-12-10 02:26:41 +00:00
|
|
|
if err := a.RemoveCheck(structs.NewCheckID(chkTypes[1].CheckID, nil), false); err != nil {
|
2019-09-26 02:55:52 +00:00
|
|
|
t.Fatalf("failed to remove check: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case val = <-ch:
|
|
|
|
case <-time.After(100 * time.Millisecond):
|
|
|
|
t.Fatal("didn't get cache update event")
|
|
|
|
}
|
|
|
|
|
|
|
|
got, ok = val.Result.([]structs.CheckType)
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("notified of result of wrong type, got %T, want []structs.CheckType", got)
|
|
|
|
}
|
|
|
|
want = chkTypes[0:1]
|
|
|
|
for i, c := range want {
|
|
|
|
require.Equal(t, *c, got[i])
|
|
|
|
}
|
|
|
|
}
|