Ctrl K
ComunidadGuías…

pkg/k8score/dynamic_cache_bounded_test.go

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

Archivo original ↗Preguntar a KiBot
package k8score

import (
	"fmt"
	"testing"

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

type namespaceReadInformer struct {
	cache.SharedIndexInformer
	indexer cache.Indexer
	synced  bool
}

func (i namespaceReadInformer) GetIndexer() cache.Indexer { return i.indexer }
func (i namespaceReadInformer) HasSynced() bool           { return i.synced }

type namespaceOnlyIndexer struct {
	cache.Indexer
	namespaces []string
}

func (i *namespaceOnlyIndexer) List() []any {
	panic("bounded namespace read must not materialize global cache")
}
func (i *namespaceOnlyIndexer) ByIndex(index, value string) ([]any, error) {
	if index != cache.NamespaceIndex {
		panic("expected namespace index")
	}
	i.namespaces = append(i.namespaces, value)
	return i.Indexer.ByIndex(index, value)
}

func TestListWatchedNamespaceReadOnlyScopesBeforeLimiting(t *testing.T) {
	gvr := schema.GroupVersionResource{Group: "example.com", Version: "v1", Resource: "widgets"}
	idx := &namespaceOnlyIndexer{Indexer: cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})}
	seed := func(ns, name string) {
		t.Helper()
		u := &unstructured.Unstructured{Object: map[string]any{"apiVersion": "example.com/v1", "kind": "Widget", "metadata": map[string]any{"namespace": ns, "name": name}}}
		if err := idx.Add(u); err != nil {
			t.Fatal(err)
		}
	}
	for n := 0; n < 2000; n++ {
		seed("foreign", fmt.Sprintf("x%d", n))
	}
	seed("target", "one")
	d := &DynamicResourceCache{informers: map[informerKey]*informerEntry{{gvr: gvr}: {informer: namespaceReadInformer{indexer: idx, synced: true}}}}
	got, truncated, err := d.ListWatchedNamespaceReadOnly(gvr, "target", 500)
	if err != nil || truncated || len(got) != 1 || got[0].GetNamespace() != "target" {
		t.Fatalf("foreign cache affected result: %v %v %v", got, truncated, err)
	}
	for n := 0; n < 600; n++ {
		seed("target", fmt.Sprintf("x%d", n))
	}
	got, truncated, err = d.ListWatchedNamespaceReadOnly(gvr, "target", 500)
	if err != nil || !truncated || len(got) != 0 {
		t.Fatalf("candidate limit lost: %d %v %v", len(got), truncated, err)
	}
	again, againTruncated, againErr := d.ListWatchedNamespaceReadOnly(gvr, "target", 500)
	if againErr != nil || !againTruncated || len(again) != 0 {
		t.Fatal("large namespace produced unstable sample")
	}
	for _, ns := range idx.namespaces {
		if ns != "target" {
			t.Fatalf("read unrelated namespace %q", ns)
		}
	}
	if _, _, err = d.ListWatchedNamespaceReadOnly(gvr, "", 500); err == nil {
		t.Fatal("unscoped read accepted")
	}
	if _, _, err = d.ListWatchedNamespaceReadOnly(gvr, "target", 0); err == nil {
		t.Fatal("unbounded read accepted")
	}
	if len(d.informers) != 1 {
		t.Fatal("read started informer")
	}
}

func TestListWatchedNamespaceReadOnlyDoesNotStartOrUseUnsyncedWatch(t *testing.T) {
	gvr := schema.GroupVersionResource{Group: "example.com", Version: "v1", Resource: "widgets"}
	d := &DynamicResourceCache{informers: map[informerKey]*informerEntry{}}
	if _, _, err := d.ListWatchedNamespaceReadOnly(gvr, "target", 5); err == nil {
		t.Fatal("missing watch accepted")
	}
	if len(d.informers) != 0 {
		t.Fatal("watch created")
	}
	d.informers[informerKey{gvr: gvr, ns: "target"}] = &informerEntry{informer: namespaceReadInformer{synced: false}}
	if _, _, err := d.ListWatchedNamespaceReadOnly(gvr, "target", 5); err == nil {
		t.Fatal("unsynced watch accepted")
	}
}

func TestListWatchedNamespaceReadOnlyRejectsStoppedCache(t *testing.T) {
	gvr := schema.GroupVersionResource{Group: "example.com", Version: "v1", Resource: "widgets"}
	idx := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
	d := &DynamicResourceCache{stopped: true, informers: map[informerKey]*informerEntry{{gvr: gvr}: {informer: namespaceReadInformer{indexer: idx, synced: true}}}}
	if rows, truncated, err := d.ListWatchedNamespaceReadOnly(gvr, "target", 500); err == nil || rows != nil || truncated {
		t.Fatalf("stopped cache returned evidence: rows=%v truncated=%v err=%v", rows, truncated, err)
	}
}