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  }