github.com/cilium/cilium@v1.16.2/pkg/hubble/observer/local_node_watcher_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Hubble 3 4 package observer 5 6 import ( 7 "context" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 12 flowpb "github.com/cilium/cilium/api/v1/flow" 13 "github.com/cilium/cilium/pkg/node" 14 "github.com/cilium/cilium/pkg/node/types" 15 ) 16 17 func Test_LocalNodeWatcher(t *testing.T) { 18 ctx, cancel := context.WithCancel(context.Background()) 19 defer cancel() 20 21 localNode := node.LocalNode{ 22 Node: types.Node{ 23 Name: "ip-1-2-3-4.us-west-2.compute.internal", 24 Labels: map[string]string{ 25 "kubernetes.io/arch": "amd64", 26 "kubernetes.io/os": "linux", 27 "kubernetes.io/hostname": "ip-1-2-3-4.us-west-2.compute.internal", 28 "topology.kubernetes.io/region": "us-west-2", 29 "topology.kubernetes.io/zone": "us-west-2d", 30 }, 31 }, 32 } 33 localNodeLabelSlice := []string{ 34 "kubernetes.io/arch=amd64", 35 "kubernetes.io/hostname=ip-1-2-3-4.us-west-2.compute.internal", 36 "kubernetes.io/os=linux", 37 "topology.kubernetes.io/region=us-west-2", 38 "topology.kubernetes.io/zone=us-west-2d", 39 } 40 updatedNode := node.LocalNode{ 41 Node: types.Node{ 42 Name: "kind-kind", 43 Labels: map[string]string{ 44 "kubernetes.io/arch": "arm64", 45 "kubernetes.io/os": "linux", 46 "kubernetes.io/hostname": "kind-kind", 47 }, 48 }, 49 } 50 updatedNodeLabelSlice := []string{ 51 "kubernetes.io/arch=arm64", 52 "kubernetes.io/hostname=kind-kind", 53 "kubernetes.io/os=linux", 54 } 55 56 var watcher *LocalNodeWatcher 57 58 t.Run("NewLocalNodeWatcher", func(t *testing.T) { 59 var err error 60 watcher, err = NewLocalNodeWatcher(ctx, node.NewTestLocalNodeStore(localNode)) 61 require.NoError(t, err) 62 require.NotNil(t, watcher) 63 }) 64 65 t.Run("OnDecodedFlow", func(t *testing.T) { 66 var flow flowpb.Flow 67 stop, err := watcher.OnDecodedFlow(ctx, &flow) 68 require.False(t, stop) 69 require.NoError(t, err) 70 require.Equal(t, localNodeLabelSlice, flow.GetNodeLabels()) 71 }) 72 73 t.Run("update", func(t *testing.T) { 74 watcher.update(updatedNode) 75 var flow flowpb.Flow 76 stop, err := watcher.OnDecodedFlow(ctx, &flow) 77 require.False(t, stop) 78 require.NoError(t, err) 79 require.Equal(t, updatedNodeLabelSlice, flow.GetNodeLabels()) 80 }) 81 82 t.Run("complete", func(t *testing.T) { 83 watcher.complete(nil) 84 var flow flowpb.Flow 85 stop, err := watcher.OnDecodedFlow(ctx, &flow) 86 require.False(t, stop) 87 require.NoError(t, err) 88 require.Empty(t, flow.GetNodeLabels()) 89 }) 90 } 91 92 func Test_sortedLabelSlice(t *testing.T) { 93 tt := []struct { 94 name string 95 input map[string]string 96 want []string 97 }{ 98 { 99 name: "nil", 100 input: nil, 101 want: []string{}, 102 }, 103 { 104 name: "empty", 105 input: map[string]string{}, 106 want: []string{}, 107 }, 108 { 109 name: "key=val", 110 input: map[string]string{ 111 "key": "val", 112 }, 113 want: []string{"key=val"}, 114 }, 115 { 116 name: "ordering", 117 input: map[string]string{ 118 "b": "foo", 119 "a": "bar", 120 "c": "qux", 121 }, 122 want: []string{"a=bar", "b=foo", "c=qux"}, 123 }, 124 } 125 126 for _, tc := range tt { 127 t.Run(tc.name, func(t *testing.T) { 128 require.Equal(t, tc.want, sortedLabelSlice(tc.input)) 129 }) 130 } 131 }