github.com/cilium/cilium@v1.16.2/pkg/hubble/metrics/port-distribution/handler_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Hubble 3 4 package portdistribution 5 6 import ( 7 "context" 8 "testing" 9 10 "github.com/prometheus/client_golang/prometheus" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 wrappers "google.golang.org/protobuf/types/known/wrapperspb" 14 15 pb "github.com/cilium/cilium/api/v1/flow" 16 "github.com/cilium/cilium/pkg/hubble/metrics/api" 17 monitorAPI "github.com/cilium/cilium/pkg/monitor/api" 18 ) 19 20 func TestPortDistributionHandler(t *testing.T) { 21 registry := prometheus.NewRegistry() 22 opts := api.Options{"sourceContext": "namespace", "destinationContext": "namespace"} 23 24 portHandler := &portDistributionHandler{} 25 26 t.Run("Init", func(t *testing.T) { 27 require.NoError(t, portHandler.Init(registry, opts)) 28 }) 29 30 t.Run("Status", func(t *testing.T) { 31 require.Equal(t, "destination=namespace,source=namespace", portHandler.Status()) 32 }) 33 34 t.Run("ProcessFlow_SkipReply", func(t *testing.T) { 35 flow := buildFlow(8080, pb.Verdict_FORWARDED, true) 36 portHandler.ProcessFlow(context.TODO(), flow) 37 38 metricFamilies, err := registry.Gather() 39 require.NoError(t, err) 40 41 require.Empty(t, metricFamilies) 42 }) 43 44 t.Run("ProcessFlow_SkipDropped", func(t *testing.T) { 45 flow := buildFlow(8080, pb.Verdict_DROPPED, false) 46 portHandler.ProcessFlow(context.TODO(), flow) 47 48 metricFamilies, err := registry.Gather() 49 require.NoError(t, err) 50 51 require.Empty(t, metricFamilies) 52 }) 53 54 t.Run("ProcessFlow", func(t *testing.T) { 55 flow := buildFlow(8080, pb.Verdict_FORWARDED, false) 56 portHandler.ProcessFlow(context.TODO(), flow) 57 58 metricFamilies, err := registry.Gather() 59 require.NoError(t, err) 60 61 assert.Equal(t, "hubble_port_distribution_total", *metricFamilies[0].Name) 62 require.Len(t, metricFamilies[0].Metric, 1) 63 metric := metricFamilies[0].Metric[0] 64 65 assert.Equal(t, "destination", *metric.Label[0].Name) 66 assert.Equal(t, "bar", *metric.Label[0].Value) 67 68 assert.Equal(t, "port", *metric.Label[1].Name) 69 assert.Equal(t, "8080", *metric.Label[1].Value) 70 71 assert.Equal(t, "protocol", *metric.Label[2].Name) 72 assert.Equal(t, "TCP", *metric.Label[2].Value) 73 74 assert.Equal(t, "source", *metric.Label[3].Name) 75 assert.Equal(t, "foo", *metric.Label[3].Value) 76 77 assert.Equal(t, 1., *metric.Counter.Value) 78 79 //send another flow with same labels 80 portHandler.ProcessFlow(context.TODO(), flow) 81 metricFamilies, _ = registry.Gather() 82 metric = metricFamilies[0].Metric[0] 83 assert.Equal(t, 2., *metric.Counter.Value) 84 }) 85 86 t.Run("ProcessFlow_MultiplePorts", func(t *testing.T) { 87 registry := prometheus.NewRegistry() 88 opts := api.Options{"sourceContext": "namespace", "destinationContext": "namespace"} 89 90 portHandler := &portDistributionHandler{} 91 require.NoError(t, portHandler.Init(registry, opts)) 92 93 flow1 := buildFlow(8081, pb.Verdict_FORWARDED, false) 94 portHandler.ProcessFlow(context.TODO(), flow1) 95 96 flow2 := buildFlow(8082, pb.Verdict_FORWARDED, false) 97 portHandler.ProcessFlow(context.TODO(), flow2) 98 portHandler.ProcessFlow(context.TODO(), flow2) 99 100 metricFamilies, err := registry.Gather() 101 require.NoError(t, err) 102 103 assert.Equal(t, "hubble_port_distribution_total", *metricFamilies[0].Name) 104 require.Len(t, metricFamilies[0].Metric, 2) 105 106 for _, metric := range metricFamilies[0].Metric { 107 switch *metric.Label[1].Value { 108 case "8081": 109 assert.Equal(t, 1., *metric.Counter.Value) 110 case "8082": 111 assert.Equal(t, 2., *metric.Counter.Value) 112 } 113 } 114 }) 115 116 } 117 118 func buildFlow(port uint32, verdict pb.Verdict, reply bool) *pb.Flow { 119 return &pb.Flow{ 120 EventType: &pb.CiliumEventType{Type: monitorAPI.MessageTypePolicyVerdict}, 121 L4: &pb.Layer4{ 122 Protocol: &pb.Layer4_TCP{ 123 TCP: &pb.TCP{ 124 DestinationPort: port, 125 }, 126 }, 127 }, 128 Source: &pb.Endpoint{Namespace: "foo"}, 129 Destination: &pb.Endpoint{Namespace: "bar"}, 130 Verdict: verdict, 131 IsReply: &wrappers.BoolValue{Value: reply}, 132 } 133 }