VictoriaMetrics/lib/promscrape/discovery/kubernetes/node_test.go
Aliaksandr Valialkin f325410c26
lib/promscrape: optimize service discovery speed
- Return meta-labels for the discovered targets via promutils.Labels
  instead of map[string]string. This improves the speed of generating
  meta-labels for discovered targets by up to 5x.

- Remove memory allocations in hot paths during ScrapeWork generation.
  The ScrapeWork contains scrape settings for a single discovered target.
  This improves the service discovery speed by up to 2x.
2022-11-29 21:26:00 -08:00

342 lines
12 KiB
Go

package kubernetes
import (
"bytes"
"reflect"
"sort"
"strconv"
"testing"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promutils"
)
func TestParseNodeListFailure(t *testing.T) {
f := func(s string) {
t.Helper()
r := bytes.NewBufferString(s)
objectsByKey, _, err := parseNodeList(r)
if err == nil {
t.Fatalf("expecting non-nil error")
}
if len(objectsByKey) != 0 {
t.Fatalf("unexpected non-empty objectsByKey: %v", objectsByKey)
}
}
f(``)
f(`[1,23]`)
f(`{"items":[{"metadata":1}]}`)
f(`{"items":[{"metadata":{"labels":[1]}}]}`)
}
func TestParseNodeListSuccess(t *testing.T) {
data := `{
"kind": "NodeList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/nodes",
"resourceVersion": "22627"
},
"items": [
{
"metadata": {
"name": "m01",
"selfLink": "/api/v1/nodes/m01",
"uid": "b48dd901-ead0-476a-b209-d2d908d65109",
"resourceVersion": "22309",
"creationTimestamp": "2020-03-16T20:44:23Z",
"labels": {
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "m01",
"kubernetes.io/os": "linux",
"minikube.k8s.io/commit": "eb13446e786c9ef70cb0a9f85a633194e62396a1",
"minikube.k8s.io/name": "minikube",
"minikube.k8s.io/updated_at": "2020_03_16T22_44_27_0700",
"minikube.k8s.io/version": "v1.8.2",
"node-role.kubernetes.io/master": ""
},
"annotations": {
"kubeadm.alpha.kubernetes.io/cri-socket": "/var/run/dockershim.sock",
"node.alpha.kubernetes.io/ttl": "0",
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
}
},
"spec": {
"podCIDR": "10.244.0.0/24",
"podCIDRs": [
"10.244.0.0/24"
],
"providerID": "aws:///foo-bar/baz"
},
"status": {
"capacity": {
"cpu": "4",
"ephemeral-storage": "474705032Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "16314884Ki",
"pods": "110"
},
"allocatable": {
"cpu": "4",
"ephemeral-storage": "437488156767",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "16212484Ki",
"pods": "110"
},
"conditions": [
{
"type": "MemoryPressure",
"status": "False",
"lastHeartbeatTime": "2020-03-20T13:30:38Z",
"lastTransitionTime": "2020-03-16T20:44:18Z",
"reason": "KubeletHasSufficientMemory",
"message": "kubelet has sufficient memory available"
},
{
"type": "DiskPressure",
"status": "False",
"lastHeartbeatTime": "2020-03-20T13:30:38Z",
"lastTransitionTime": "2020-03-16T20:44:18Z",
"reason": "KubeletHasNoDiskPressure",
"message": "kubelet has no disk pressure"
},
{
"type": "PIDPressure",
"status": "False",
"lastHeartbeatTime": "2020-03-20T13:30:38Z",
"lastTransitionTime": "2020-03-16T20:44:18Z",
"reason": "KubeletHasSufficientPID",
"message": "kubelet has sufficient PID available"
},
{
"type": "Ready",
"status": "True",
"lastHeartbeatTime": "2020-03-20T13:30:38Z",
"lastTransitionTime": "2020-03-16T20:44:39Z",
"reason": "KubeletReady",
"message": "kubelet is posting ready status"
}
],
"addresses": [
{
"type": "InternalIP",
"address": "172.17.0.2"
},
{
"type": "Hostname",
"address": "m01"
}
],
"daemonEndpoints": {
"kubeletEndpoint": {
"Port": 10250
}
},
"nodeInfo": {
"machineID": "e64aad27e586485b9a9cbd699840c0ab",
"systemUUID": "4d9f5caa-25de-46c6-8d54-d1c5141b78cc",
"bootID": "947ffc57-db48-4a03-b7c6-18ce0b85238d",
"kernelVersion": "4.15.0-91-generic",
"osImage": "Ubuntu 19.10",
"containerRuntimeVersion": "docker://19.3.2",
"kubeletVersion": "v1.17.3",
"kubeProxyVersion": "v1.17.3",
"operatingSystem": "linux",
"architecture": "amd64"
},
"images": [
{
"names": [
"k8s.gcr.io/etcd@sha256:4afb99b4690b418ffc2ceb67e1a17376457e441c1f09ab55447f0aaf992fa646",
"k8s.gcr.io/etcd:3.4.3-0"
],
"sizeBytes": 288426917
},
{
"names": [
"k8s.gcr.io/kube-apiserver@sha256:33400ea29255bd20714b6b8092b22ebb045ae134030d6bf476bddfed9d33e900",
"k8s.gcr.io/kube-apiserver:v1.17.3"
],
"sizeBytes": 170986003
},
{
"names": [
"k8s.gcr.io/kube-controller-manager@sha256:2f0bf4d08e72a1fd6327c8eca3a72ad21af3a608283423bb3c10c98e68759844",
"k8s.gcr.io/kube-controller-manager:v1.17.3"
],
"sizeBytes": 160918035
},
{
"names": [
"k8s.gcr.io/kube-proxy@sha256:3a70e2ab8d1d623680191a1a1f1dcb0bdbfd388784b1f153d5630a7397a63fd4",
"k8s.gcr.io/kube-proxy:v1.17.3"
],
"sizeBytes": 115964919
},
{
"names": [
"k8s.gcr.io/kube-scheduler@sha256:b091f0db3bc61a3339fd3ba7ebb06c984c4ded32e1f2b1ef0fbdfab638e88462",
"k8s.gcr.io/kube-scheduler:v1.17.3"
],
"sizeBytes": 94435859
},
{
"names": [
"kubernetesui/dashboard@sha256:fc90baec4fb62b809051a3227e71266c0427240685139bbd5673282715924ea7",
"kubernetesui/dashboard:v2.0.0-beta8"
],
"sizeBytes": 90835427
},
{
"names": [
"gcr.io/k8s-minikube/storage-provisioner@sha256:088daa9fcbccf04c3f415d77d5a6360d2803922190b675cb7fc88a9d2d91985a",
"gcr.io/k8s-minikube/storage-provisioner:v1.8.1"
],
"sizeBytes": 80815640
},
{
"names": [
"kindest/kindnetd@sha256:bc1833b3da442bb639008dd5a62861a0419d3f64b58fce6fb38b749105232555",
"kindest/kindnetd:0.5.3"
],
"sizeBytes": 78486107
},
{
"names": [
"k8s.gcr.io/coredns@sha256:7ec975f167d815311a7136c32e70735f0d00b73781365df1befd46ed35bd4fe7",
"k8s.gcr.io/coredns:1.6.5"
],
"sizeBytes": 41578211
},
{
"names": [
"kubernetesui/metrics-scraper@sha256:2026f9f7558d0f25cc6bab74ea201b4e9d5668fbc378ef64e13fddaea570efc0",
"kubernetesui/metrics-scraper:v1.0.2"
],
"sizeBytes": 40101552
},
{
"names": [
"k8s.gcr.io/pause@sha256:f78411e19d84a252e53bff71a4407a5686c46983a2c2eeed83929b888179acea",
"k8s.gcr.io/pause:3.1"
],
"sizeBytes": 742472
}
]
}
}
]
}
`
r := bytes.NewBufferString(data)
objectsByKey, meta, err := parseNodeList(r)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
expectedResourceVersion := "22627"
if meta.ResourceVersion != expectedResourceVersion {
t.Fatalf("unexpected resource version; got %s; want %s", meta.ResourceVersion, expectedResourceVersion)
}
sortedLabelss := getSortedLabelss(objectsByKey)
expectedLabelss := []*promutils.Labels{
promutils.NewLabelsFromMap(map[string]string{
"instance": "m01",
"__address__": "172.17.0.2:10250",
"__meta_kubernetes_node_name": "m01",
"__meta_kubernetes_node_provider_id": "aws:///foo-bar/baz",
"__meta_kubernetes_node_label_beta_kubernetes_io_arch": "amd64",
"__meta_kubernetes_node_label_beta_kubernetes_io_os": "linux",
"__meta_kubernetes_node_label_kubernetes_io_arch": "amd64",
"__meta_kubernetes_node_label_kubernetes_io_hostname": "m01",
"__meta_kubernetes_node_label_kubernetes_io_os": "linux",
"__meta_kubernetes_node_label_minikube_k8s_io_commit": "eb13446e786c9ef70cb0a9f85a633194e62396a1",
"__meta_kubernetes_node_label_minikube_k8s_io_name": "minikube",
"__meta_kubernetes_node_label_minikube_k8s_io_updated_at": "2020_03_16T22_44_27_0700",
"__meta_kubernetes_node_label_minikube_k8s_io_version": "v1.8.2",
"__meta_kubernetes_node_label_node_role_kubernetes_io_master": "",
"__meta_kubernetes_node_labelpresent_beta_kubernetes_io_arch": "true",
"__meta_kubernetes_node_labelpresent_beta_kubernetes_io_os": "true",
"__meta_kubernetes_node_labelpresent_kubernetes_io_arch": "true",
"__meta_kubernetes_node_labelpresent_kubernetes_io_hostname": "true",
"__meta_kubernetes_node_labelpresent_kubernetes_io_os": "true",
"__meta_kubernetes_node_labelpresent_minikube_k8s_io_commit": "true",
"__meta_kubernetes_node_labelpresent_minikube_k8s_io_name": "true",
"__meta_kubernetes_node_labelpresent_minikube_k8s_io_updated_at": "true",
"__meta_kubernetes_node_labelpresent_minikube_k8s_io_version": "true",
"__meta_kubernetes_node_labelpresent_node_role_kubernetes_io_master": "true",
"__meta_kubernetes_node_annotation_kubeadm_alpha_kubernetes_io_cri_socket": "/var/run/dockershim.sock",
"__meta_kubernetes_node_annotation_node_alpha_kubernetes_io_ttl": "0",
"__meta_kubernetes_node_annotation_volumes_kubernetes_io_controller_managed_attach_detach": "true",
"__meta_kubernetes_node_annotationpresent_kubeadm_alpha_kubernetes_io_cri_socket": "true",
"__meta_kubernetes_node_annotationpresent_node_alpha_kubernetes_io_ttl": "true",
"__meta_kubernetes_node_annotationpresent_volumes_kubernetes_io_controller_managed_attach_detach": "true",
"__meta_kubernetes_node_address_InternalIP": "172.17.0.2",
"__meta_kubernetes_node_address_Hostname": "m01",
}),
}
if !areEqualLabelss(sortedLabelss, expectedLabelss) {
t.Fatalf("unexpected labels:\ngot\n%v\nwant\n%v", sortedLabelss, expectedLabelss)
}
}
func getSortedLabelss(objectsByKey map[string]object) []*promutils.Labels {
gw := newTestGroupWatcher()
var result []*promutils.Labels
for _, o := range objectsByKey {
labelss := o.getTargetLabels(gw)
for _, labels := range labelss {
labels.Sort()
result = append(result, labels)
}
}
return result
}
func newTestGroupWatcher() *groupWatcher {
var gw groupWatcher
gw.m = map[string]*urlWatcher{
"node": {
role: "node",
objectsByKey: map[string]object{
"/test-node": &Node{
Metadata: ObjectMeta{
Labels: promutils.NewLabelsFromMap(map[string]string{"node-label": "xyz"}),
},
},
},
},
}
gw.attachNodeMetadata = true
return &gw
}
func areEqualLabelss(a, b []*promutils.Labels) bool {
sortLabelss(a)
sortLabelss(b)
return reflect.DeepEqual(a, b)
}
func sortLabelss(a []*promutils.Labels) {
sort.Slice(a, func(i, j int) bool {
return marshalLabels(a[i]) < marshalLabels(a[j])
})
}
func marshalLabels(a *promutils.Labels) string {
var b []byte
for _, label := range a.Labels {
b = strconv.AppendQuote(b, label.Name)
b = append(b, ':')
b = strconv.AppendQuote(b, label.Value)
b = append(b, ',')
}
return string(b)
}