474d9cfcdc
Adds another datasource for proxycfg.HTTPChecks, for use on server agents. Typically these checks are performed by local client agents and there is no equivalent of this in agentless (where servers configure consul-dataplane proxies). Hence, the data source is mostly a no-op on servers but in the case where the service is present within the local state, it delegates to the cache data source.
118 lines
3 KiB
Go
118 lines
3 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"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) {
|
|
if testing.Short() {
|
|
t.Skip("too slow for testing.Short")
|
|
}
|
|
|
|
t.Parallel()
|
|
|
|
a := NewTestAgent(t, "")
|
|
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,
|
|
NodeName: a.Config.NodeName,
|
|
}, "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
|
|
if err := a.addServiceFromSource(&service, chkTypes[2:], false, "", ConfigSourceLocal); err != nil {
|
|
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
|
|
if err := a.addServiceFromSource(&service, chkTypes[0:2], false, "", ConfigSourceLocal); err != nil {
|
|
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
|
|
if err := a.RemoveCheck(structs.NewCheckID(chkTypes[1].CheckID, nil), false); err != nil {
|
|
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])
|
|
}
|
|
}
|