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  }