github.com/cilium/cilium@v1.16.2/pkg/hubble/monitor/consumer_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package monitor 5 6 import ( 7 "testing" 8 "time" 9 10 "github.com/google/uuid" 11 "github.com/sirupsen/logrus" 12 "github.com/stretchr/testify/assert" 13 14 observerTypes "github.com/cilium/cilium/pkg/hubble/observer/types" 15 "github.com/cilium/cilium/pkg/monitor/api" 16 nodeTypes "github.com/cilium/cilium/pkg/node/types" 17 "github.com/cilium/cilium/pkg/proxy/accesslog" 18 ) 19 20 type fakeObserver struct { 21 events chan *observerTypes.MonitorEvent 22 logger *logrus.Entry 23 } 24 25 func (f fakeObserver) GetEventsChannel() chan *observerTypes.MonitorEvent { 26 return f.events 27 } 28 29 func (f fakeObserver) GetLogger() logrus.FieldLogger { 30 return f.logger 31 } 32 33 func TestHubbleConsumer(t *testing.T) { 34 observer := fakeObserver{ 35 // For testing, we an events queue with a buffer size of 1 36 events: make(chan *observerTypes.MonitorEvent, 1), 37 logger: logrus.NewEntry(logrus.New()), 38 } 39 consumer := NewConsumer(observer) 40 data := []byte{0, 1, 2, 3, 4} 41 cpu := 5 42 43 consumer.NotifyPerfEvent(data, cpu) 44 expected := &observerTypes.MonitorEvent{ 45 NodeName: nodeTypes.GetName(), 46 Payload: &observerTypes.PerfEvent{ 47 Data: data, 48 CPU: cpu, 49 }, 50 } 51 received := <-observer.GetEventsChannel() 52 assert.Equal(t, expected.NodeName, received.NodeName) 53 assert.Equal(t, expected.Payload, received.Payload) 54 assert.NotEqual(t, received.UUID, uuid.UUID{}) 55 56 numLostEvents := uint64(7) 57 consumer.NotifyPerfEventLost(numLostEvents, cpu) 58 expected = &observerTypes.MonitorEvent{ 59 NodeName: nodeTypes.GetName(), 60 Payload: &observerTypes.LostEvent{ 61 Source: observerTypes.LostEventSourcePerfRingBuffer, 62 NumLostEvents: numLostEvents, 63 CPU: cpu, 64 }, 65 } 66 received = <-observer.GetEventsChannel() 67 assert.Equal(t, expected.NodeName, received.NodeName) 68 assert.Equal(t, expected.Payload, received.Payload) 69 assert.NotEqual(t, received.UUID, uuid.UUID{}) 70 71 typ := api.MessageTypeAccessLog 72 message := &accesslog.LogRecord{Timestamp: time.RFC3339} 73 consumer.NotifyAgentEvent(typ, message) 74 expected = &observerTypes.MonitorEvent{ 75 NodeName: nodeTypes.GetName(), 76 Payload: &observerTypes.AgentEvent{ 77 Type: typ, 78 Message: message, 79 }, 80 } 81 received = <-observer.GetEventsChannel() 82 assert.Equal(t, expected.NodeName, received.NodeName) 83 assert.Equal(t, expected.Payload, received.Payload) 84 assert.NotEqual(t, received.UUID, uuid.UUID{}) 85 86 // The first notification will get through, the other two will be dropped 87 consumer.NotifyAgentEvent(1, nil) 88 consumer.NotifyPerfEventLost(0, 0) // dropped 89 consumer.NotifyPerfEvent(nil, 0) // dropped 90 expected = &observerTypes.MonitorEvent{ 91 NodeName: nodeTypes.GetName(), 92 Payload: &observerTypes.AgentEvent{ 93 Type: 1, 94 }, 95 } 96 received = <-observer.GetEventsChannel() 97 assert.Equal(t, expected.NodeName, received.NodeName) 98 assert.Equal(t, expected.Payload, received.Payload) 99 assert.NotEqual(t, received.UUID, uuid.UUID{}) 100 101 // Now that the channel has one slot again, send another message 102 // (which will be dropped) to get a lost event notifications 103 consumer.NotifyAgentEvent(0, nil) // dropped 104 105 expected = &observerTypes.MonitorEvent{ 106 NodeName: nodeTypes.GetName(), 107 Payload: &observerTypes.LostEvent{ 108 Source: observerTypes.LostEventSourceEventsQueue, 109 NumLostEvents: 2, 110 }, 111 } 112 received = <-observer.GetEventsChannel() 113 assert.Equal(t, expected.NodeName, received.NodeName) 114 assert.Equal(t, expected.Payload, received.Payload) 115 assert.NotEqual(t, received.UUID, uuid.UUID{}) 116 117 // Verify that the events channel is empty now. 118 select { 119 case ev := <-observer.GetEventsChannel(): 120 assert.Fail(t, "Unexpected event", ev) 121 default: 122 } 123 }