github.com/cilium/cilium@v1.16.2/pkg/hubble/relay/server/health_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package server 5 6 import ( 7 "context" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 healthpb "google.golang.org/grpc/health/grpc_health_v1" 13 14 v1 "github.com/cilium/cilium/pkg/hubble/api/v1" 15 "github.com/cilium/cilium/pkg/hubble/relay/pool" 16 "github.com/cilium/cilium/pkg/lock" 17 ) 18 19 func TestHealthServer(t *testing.T) { 20 21 fpr := &fakePeerStatusReporter{} 22 hs := newHealthServer(fpr, 10*time.Millisecond) 23 24 hs.start() 25 t.Run("initially unavailable", func(t *testing.T) { 26 eventuallServingStatus(t, hs.svc, healthpb.HealthCheckResponse_NOT_SERVING) 27 }) 28 t.Run("updated available", func(t *testing.T) { 29 fpr.setStatus(pool.Status{ 30 PeerServiceConnected: true, 31 AvailablePeers: 3, 32 }) 33 eventuallServingStatus(t, hs.svc, healthpb.HealthCheckResponse_SERVING) 34 }) 35 t.Run("updated if no available peers", func(t *testing.T) { 36 fpr.setStatus(pool.Status{ 37 PeerServiceConnected: true, 38 AvailablePeers: 0, 39 }) 40 eventuallServingStatus(t, hs.svc, healthpb.HealthCheckResponse_NOT_SERVING) 41 }) 42 t.Run("updated if peers back", func(t *testing.T) { 43 fpr.setStatus(pool.Status{ 44 PeerServiceConnected: true, 45 AvailablePeers: 6, 46 }) 47 eventuallServingStatus(t, hs.svc, healthpb.HealthCheckResponse_SERVING) 48 }) 49 t.Run("updated if peer service unavailable", func(t *testing.T) { 50 fpr.setStatus(pool.Status{ 51 PeerServiceConnected: false, 52 AvailablePeers: 6, 53 }) 54 eventuallServingStatus(t, hs.svc, healthpb.HealthCheckResponse_NOT_SERVING) 55 }) 56 hs.stop() 57 } 58 59 func eventuallServingStatus(t *testing.T, svc healthpb.HealthServer, status healthpb.HealthCheckResponse_ServingStatus) { 60 t.Helper() 61 assert.EventuallyWithT(t, func(c *assert.CollectT) { 62 res, err := svc.Check(context.TODO(), &healthpb.HealthCheckRequest{ 63 Service: "", 64 }) 65 assert.NoError(c, err) 66 assert.Equal(c, status, res.Status) 67 68 res, err = svc.Check(context.TODO(), &healthpb.HealthCheckRequest{ 69 Service: v1.ObserverServiceName, 70 }) 71 assert.NoError(c, err) 72 assert.Equal(c, status, res.Status) 73 }, 5*time.Second, 10*time.Millisecond) 74 } 75 76 type fakePeerStatusReporter struct { 77 mu lock.Mutex 78 79 status pool.Status 80 } 81 82 func (f *fakePeerStatusReporter) setStatus(stat pool.Status) { 83 f.mu.Lock() 84 defer f.mu.Unlock() 85 f.status = stat 86 } 87 88 // Status implements peerStatusReporter. 89 func (f *fakePeerStatusReporter) Status() pool.Status { 90 f.mu.Lock() 91 defer f.mu.Unlock() 92 return f.status 93 }