github.com/netdata/go.d.plugin@v0.58.1/agent/discovery/sd/kubernetes/kubernetes_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package kubernetes 4 5 import ( 6 "fmt" 7 "os" 8 "testing" 9 10 "github.com/netdata/go.d.plugin/agent/discovery/sd/model" 11 "github.com/netdata/go.d.plugin/pkg/k8sclient" 12 13 "github.com/stretchr/testify/assert" 14 corev1 "k8s.io/api/core/v1" 15 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 16 "k8s.io/apimachinery/pkg/runtime" 17 "k8s.io/client-go/kubernetes" 18 "k8s.io/client-go/kubernetes/fake" 19 ) 20 21 var discoveryTags model.Tags = map[string]struct{}{"k8s": {}} 22 23 func TestMain(m *testing.M) { 24 _ = os.Setenv(envNodeName, "m01") 25 _ = os.Setenv(k8sclient.EnvFakeClient, "true") 26 code := m.Run() 27 _ = os.Unsetenv(envNodeName) 28 _ = os.Unsetenv(k8sclient.EnvFakeClient) 29 os.Exit(code) 30 } 31 32 func TestNewKubeDiscoverer(t *testing.T) { 33 tests := map[string]struct { 34 cfg Config 35 wantErr bool 36 }{ 37 "pod and service config": { 38 wantErr: false, 39 cfg: Config{Pod: &PodConfig{}, Service: &ServiceConfig{}}, 40 }, 41 "pod config": { 42 wantErr: false, 43 cfg: Config{Pod: &PodConfig{}}, 44 }, 45 "service config": { 46 wantErr: false, 47 cfg: Config{Service: &ServiceConfig{}}, 48 }, 49 "empty config": { 50 wantErr: true, 51 cfg: Config{}, 52 }, 53 } 54 for name, test := range tests { 55 t.Run(name, func(t *testing.T) { 56 disc, err := NewKubeDiscoverer(test.cfg) 57 58 if test.wantErr { 59 assert.Error(t, err) 60 assert.Nil(t, disc) 61 } else { 62 assert.NoError(t, err) 63 assert.NotNil(t, disc) 64 } 65 }) 66 } 67 } 68 69 func TestKubeDiscoverer_Discover(t *testing.T) { 70 const prod = "prod" 71 const dev = "dev" 72 prodNamespace := newNamespace(prod) 73 devNamespace := newNamespace(dev) 74 75 tests := map[string]func() discoverySim{ 76 "multiple namespaces pod td": func() discoverySim { 77 httpdProd, nginxProd := newHTTPDPod(), newNGINXPod() 78 httpdProd.Namespace = prod 79 nginxProd.Namespace = prod 80 81 httpdDev, nginxDev := newHTTPDPod(), newNGINXPod() 82 httpdDev.Namespace = dev 83 nginxDev.Namespace = dev 84 85 disc, _ := preparePodDiscoverer( 86 []string{prod, dev}, 87 prodNamespace, devNamespace, httpdProd, nginxProd, httpdDev, nginxDev) 88 89 return discoverySim{ 90 td: disc, 91 sortBeforeVerify: true, 92 wantTargetGroups: []model.TargetGroup{ 93 preparePodTargetGroup(httpdDev), 94 preparePodTargetGroup(nginxDev), 95 preparePodTargetGroup(httpdProd), 96 preparePodTargetGroup(nginxProd), 97 }, 98 } 99 }, 100 "multiple namespaces ClusterIP service td": func() discoverySim { 101 httpdProd, nginxProd := newHTTPDClusterIPService(), newNGINXClusterIPService() 102 httpdProd.Namespace = prod 103 nginxProd.Namespace = prod 104 105 httpdDev, nginxDev := newHTTPDClusterIPService(), newNGINXClusterIPService() 106 httpdDev.Namespace = dev 107 nginxDev.Namespace = dev 108 109 disc, _ := prepareSvcDiscoverer( 110 []string{prod, dev}, 111 prodNamespace, devNamespace, httpdProd, nginxProd, httpdDev, nginxDev) 112 113 return discoverySim{ 114 td: disc, 115 sortBeforeVerify: true, 116 wantTargetGroups: []model.TargetGroup{ 117 prepareSvcTargetGroup(httpdDev), 118 prepareSvcTargetGroup(nginxDev), 119 prepareSvcTargetGroup(httpdProd), 120 prepareSvcTargetGroup(nginxProd), 121 }, 122 } 123 }, 124 } 125 126 for name, createSim := range tests { 127 t.Run(name, func(t *testing.T) { 128 sim := createSim() 129 sim.run(t) 130 }) 131 } 132 } 133 134 func prepareDiscoverer(role string, namespaces []string, objects ...runtime.Object) (*KubeDiscoverer, kubernetes.Interface) { 135 client := fake.NewSimpleClientset(objects...) 136 disc := &KubeDiscoverer{ 137 namespaces: namespaces, 138 client: client, 139 discoverers: nil, 140 started: make(chan struct{}), 141 } 142 switch role { 143 case "pod": 144 disc.podConf = &PodConfig{Tags: "k8s"} 145 case "svc": 146 disc.svcConf = &ServiceConfig{Tags: "k8s"} 147 } 148 return disc, client 149 } 150 151 func newNamespace(name string) *corev1.Namespace { 152 return &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: name}} 153 } 154 155 func mustCalcHash(obj any) uint64 { 156 hash, err := calcHash(obj) 157 if err != nil { 158 panic(fmt.Sprintf("hash calculation: %v", err)) 159 } 160 return hash 161 }