1package agent 2 3import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/require" 9 10 "github.com/hashicorp/consul/agent/cache" 11 cachetype "github.com/hashicorp/consul/agent/cache-types" 12 "github.com/hashicorp/consul/agent/checks" 13 "github.com/hashicorp/consul/agent/structs" 14 "github.com/hashicorp/consul/testrpc" 15) 16 17// Integration test for ServiceHTTPBasedChecks cache-type 18// Placed in agent pkg rather than cache-types to avoid circular dependency when importing agent.TestAgent 19func TestAgent_ServiceHTTPChecksNotification(t *testing.T) { 20 if testing.Short() { 21 t.Skip("too slow for testing.Short") 22 } 23 24 t.Parallel() 25 26 a := NewTestAgent(t, "") 27 defer a.Shutdown() 28 testrpc.WaitForTestAgent(t, a.RPC, "dc1") 29 30 service := structs.NodeService{ 31 ID: "web", 32 Service: "web", 33 } 34 35 ctx, cancel := context.WithCancel(context.Background()) 36 defer cancel() 37 38 ch := make(chan cache.UpdateEvent) 39 40 // Watch for service check updates 41 err := a.cache.Notify(ctx, cachetype.ServiceHTTPChecksName, &cachetype.ServiceHTTPChecksRequest{ 42 ServiceID: service.ID, 43 }, "service-checks:"+service.ID, ch) 44 if err != nil { 45 t.Fatalf("failed to set cache notification: %v", err) 46 } 47 48 chkTypes := []*structs.CheckType{ 49 { 50 CheckID: "http-check", 51 HTTP: "localhost:8080/health", 52 Interval: 5 * time.Second, 53 OutputMaxSize: checks.DefaultBufSize, 54 }, 55 { 56 CheckID: "grpc-check", 57 GRPC: "localhost:9090/v1.Health", 58 Interval: 5 * time.Second, 59 }, 60 { 61 CheckID: "ttl-check", 62 TTL: 10 * time.Second, 63 }, 64 } 65 // Adding TTL type should lead to a timeout, since only HTTP-based checks are watched 66 if err := a.addServiceFromSource(&service, chkTypes[2:], false, "", ConfigSourceLocal); err != nil { 67 t.Fatalf("failed to add service: %v", err) 68 } 69 70 var val cache.UpdateEvent 71 select { 72 case val = <-ch: 73 t.Fatal("got cache update for TTL check, expected timeout") 74 case <-time.After(100 * time.Millisecond): 75 } 76 77 // Adding service with HTTP checks should lead notification for them 78 if err := a.addServiceFromSource(&service, chkTypes[0:2], false, "", ConfigSourceLocal); err != nil { 79 t.Fatalf("failed to add service: %v", err) 80 } 81 82 select { 83 case val = <-ch: 84 case <-time.After(100 * time.Millisecond): 85 t.Fatal("didn't get cache update event") 86 } 87 88 got, ok := val.Result.([]structs.CheckType) 89 if !ok { 90 t.Fatalf("notified of result of wrong type, got %T, want []structs.CheckType", got) 91 } 92 want := chkTypes[0:2] 93 for i, c := range want { 94 require.Equal(t, *c, got[i]) 95 } 96 97 // Removing the GRPC check should leave only the HTTP check 98 if err := a.RemoveCheck(structs.NewCheckID(chkTypes[1].CheckID, nil), false); err != nil { 99 t.Fatalf("failed to remove check: %v", err) 100 } 101 102 select { 103 case val = <-ch: 104 case <-time.After(100 * time.Millisecond): 105 t.Fatal("didn't get cache update event") 106 } 107 108 got, ok = val.Result.([]structs.CheckType) 109 if !ok { 110 t.Fatalf("notified of result of wrong type, got %T, want []structs.CheckType", got) 111 } 112 want = chkTypes[0:1] 113 for i, c := range want { 114 require.Equal(t, *c, got[i]) 115 } 116} 117