Ctrl K
ComunidadGuías…

internal/resources/informer_memory_bench_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package resources

import (
	"encoding/json"
	"fmt"
	"runtime"
	"strconv"
	"strings"
	"testing"

	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/client-go/tools/cache"
)

const informerBenchmarkObjectCount = 5000

func benchmarkInformerPod(tb testing.TB, index int) *unstructured.Unstructured {
	tb.Helper()
	name := fmt.Sprintf("checkout-%05d", index)
	namespace := "team-" + strconv.Itoa(index%50)
	lastApplied := fmt.Sprintf(
		`{"apiVersion":"v1","kind":"Pod","metadata":{"name":%q,"namespace":%q},"spec":{"containers":[{"name":"app","image":"registry.example.com/shop/checkout:v42","env":%q}]}}`,
		name,
		namespace,
		strings.Repeat("configured-value-", 96),
	)
	fields := map[string]any{
		"f:metadata": map[string]any{
			"f:annotations": map[string]any{
				".": map[string]any{},
				"f:kubectl.kubernetes.io/last-applied-configuration": map[string]any{},
			},
			"f:labels": map[string]any{
				".":                        map[string]any{},
				"f:app.kubernetes.io/name": map[string]any{},
				"f:team":                   map[string]any{},
			},
		},
		"f:spec": map[string]any{
			"f:containers": map[string]any{
				"k:{\"name\":\"app\"}": map[string]any{
					".":           map[string]any{},
					"f:env":       map[string]any{},
					"f:image":     map[string]any{},
					"f:name":      map[string]any{},
					"f:resources": map[string]any{},
				},
			},
			"f:nodeName":           map[string]any{},
			"f:serviceAccountName": map[string]any{},
			"f:volumes":            map[string]any{},
		},
	}
	annotations := map[string]any{
		"checksum/config":      fmt.Sprintf("%064d", index),
		"prometheus.io/path":   "/metrics",
		"prometheus.io/port":   "9090",
		"prometheus.io/scrape": "true",
	}
	annotations["kubectl.kubernetes.io/last-applied-configuration"] = lastApplied
	value := map[string]any{
		"apiVersion": "v1",
		"kind":       "Pod",
		"metadata": map[string]any{
			"name":      name,
			"namespace": namespace,
			"uid":       "4b7b7d42-" + name,
			"labels": map[string]any{
				"app.kubernetes.io/name":       "checkout",
				"app.kubernetes.io/instance":   "shop",
				"app.kubernetes.io/managed-by": "Helm",
				"pod-template-hash":            strconv.Itoa(1000000000 + index),
				"team":                         namespace,
			},
			"annotations": annotations,
			"managedFields": []any{
				map[string]any{
					"apiVersion": "v1",
					"fieldsType": "FieldsV1",
					"fieldsV1":   fields,
					"manager":    "kube-controller-manager",
					"operation":  "Update",
				},
				map[string]any{
					"apiVersion":  "v1",
					"fieldsType":  "FieldsV1",
					"fieldsV1":    fields,
					"manager":     "kubelet",
					"operation":   "Update",
					"subresource": "status",
				},
			},
		},
		"spec": map[string]any{
			"containers": []any{
				map[string]any{
					"env": []any{
						map[string]any{"name": "LOG_LEVEL", "value": "info"},
						map[string]any{"name": "REGION", "value": "eu-central-1"},
						map[string]any{"name": "WORKERS", "value": "8"},
					},
					"image": "registry.example.com/shop/checkout:v42",
					"name":  "app",
					"ports": []any{
						map[string]any{"containerPort": float64(8080), "name": "http", "protocol": "TCP"},
						map[string]any{"containerPort": float64(9090), "name": "metrics", "protocol": "TCP"},
					},
					"resources": map[string]any{
						"limits":   map[string]any{"cpu": "1", "memory": "1Gi"},
						"requests": map[string]any{"cpu": "250m", "memory": "256Mi"},
					},
					"volumeMounts": []any{
						map[string]any{"mountPath": "/etc/shop", "name": "config", "readOnly": true},
						map[string]any{"mountPath": "/var/run/secrets/shop", "name": "credentials", "readOnly": true},
					},
				},
			},
			"nodeName":           "worker-" + strconv.Itoa(index%200),
			"serviceAccountName": "checkout",
			"volumes": []any{
				map[string]any{"configMap": map[string]any{"name": "checkout"}, "name": "config"},
				map[string]any{"name": "credentials", "secret": map[string]any{"secretName": "checkout"}},
			},
		},
		"status": map[string]any{
			"conditions": []any{
				map[string]any{"status": "True", "type": "PodReadyToStartContainers"},
				map[string]any{"status": "True", "type": "Initialized"},
				map[string]any{"status": "True", "type": "Ready"},
				map[string]any{"status": "True", "type": "ContainersReady"},
				map[string]any{"status": "True", "type": "PodScheduled"},
			},
			"containerStatuses": []any{
				map[string]any{
					"containerID":  "containerd://" + fmt.Sprintf("%064d", index),
					"image":        "registry.example.com/shop/checkout:v42",
					"imageID":      "registry.example.com/shop/checkout@sha256:" + fmt.Sprintf("%064d", index),
					"name":         "app",
					"ready":        true,
					"restartCount": float64(0),
					"started":      true,
					"state":        map[string]any{"running": map[string]any{"startedAt": "2026-08-29T12:00:00Z"}},
				},
			},
			"hostIP": "10.0." + strconv.Itoa(index%200) + ".10",
			"phase":  "Running",
			"podIP":  "10.244." + strconv.Itoa(index%250) + ".20",
		},
	}

	encoded, err := json.Marshal(value)
	if err != nil {
		tb.Fatalf("marshal benchmark pod: %v", err)
	}
	obj := &unstructured.Unstructured{}
	if err := obj.UnmarshalJSON(encoded); err != nil {
		tb.Fatalf("decode benchmark pod: %v", err)
	}
	return obj
}

func retainedInformerBytes(b *testing.B, transformed bool) uint64 {
	b.Helper()
	runtime.GC()
	var before runtime.MemStats
	runtime.ReadMemStats(&before)

	indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{
		cache.NamespaceIndex: cache.MetaNamespaceIndexFunc,
	})
	for index := range informerBenchmarkObjectCount {
		obj := benchmarkInformerPod(b, index)
		if transformed {
			value, err := stripManagedFields(obj)
			if err != nil {
				b.Fatalf("transform benchmark pod: %v", err)
			}
			var ok bool
			obj, ok = value.(*unstructured.Unstructured)
			if !ok {
				b.Fatalf("transformed object type = %T", value)
			}
		}
		if err := indexer.Add(obj); err != nil {
			b.Fatalf("add benchmark pod: %v", err)
		}
	}

	runtime.GC()
	var after runtime.MemStats
	runtime.ReadMemStats(&after)
	runtime.KeepAlive(indexer)
	if after.HeapAlloc <= before.HeapAlloc {
		b.Fatalf("heap did not grow: before %d, after %d", before.HeapAlloc, after.HeapAlloc)
	}
	return after.HeapAlloc - before.HeapAlloc
}

func benchmarkInformerCacheMemory(b *testing.B, transformed bool) {
	b.Helper()
	var retained uint64
	for b.Loop() {
		retained += retainedInformerBytes(b, transformed)
	}
	average := float64(retained) / float64(b.N)
	b.ReportMetric(informerBenchmarkObjectCount, "objects")
	b.ReportMetric(average, "B/cache")
	b.ReportMetric(average/informerBenchmarkObjectCount, "B/object")
}

func BenchmarkInformerCacheMemoryWithoutTransform(b *testing.B) {
	benchmarkInformerCacheMemory(b, false)
}

func BenchmarkInformerCacheMemoryWithTransform(b *testing.B) {
	benchmarkInformerCacheMemory(b, true)
}