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