Ctrl K
ComunidadGuías…

pkg/ownership/deletion_test.go

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

Archivo original ↗Preguntar a KiBot
package ownership_test

import (
	"context"
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"testing"

	"github.com/skyhook-io/radar/pkg/ownership"
	"github.com/skyhook-io/radar/pkg/ownership/ownershiptest"
	"github.com/skyhook-io/radar/pkg/resourceid"
)

func BenchmarkDeletionLongChain(b *testing.B) {
	fixture := ownershiptest.NewBuilder()
	root := fixture.Add("", "ConfigMap", "chain", "0")
	owner := root
	for i := 1; i < 1000; i++ {
		owner = fixture.Add("", "ConfigMap", "chain", fmt.Sprint(i), owner.OwnerRef(false))
	}
	session, err := ownershiptest.Scan(fixture.World()).Begin()
	if err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()
	for b.Loop() {
		got := ownership.NewView(session, ownership.Unrestricted()).Deletion(context.Background(), root.Ref, 1000)
		if got.Truncated || len(got.Dependents) != 999 || len(got.Possible) != 0 {
			b.Fatalf("chain returned %d dependents, %d possible, truncated %v", len(got.Dependents), len(got.Possible), got.Truncated)
		}
	}
}

func TestDeletionSharedOwnersAndUnknowns(t *testing.T) {
	root := ownershiptest.Object{Ref: at("", "ConfigMap", "alpha", "root"), APIVersion: "v1", UID: "root"}
	left := ownershiptest.Object{Ref: at("", "ConfigMap", "alpha", "left"), APIVersion: "v1", UID: "left", OwnerReferences: []metav1.OwnerReference{root.OwnerRef(false)}}
	right := ownershiptest.Object{Ref: at("", "ConfigMap", "alpha", "right"), APIVersion: "v1", UID: "right", OwnerReferences: []metav1.OwnerReference{root.OwnerRef(false)}}
	shared := ownershiptest.Object{Ref: at("", "ConfigMap", "alpha", "shared"), APIVersion: "v1", UID: "shared", OwnerReferences: []metav1.OwnerReference{left.OwnerRef(false), right.OwnerRef(false)}}
	leaf := ownershiptest.Object{Ref: at("", "ConfigMap", "alpha", "leaf"), APIVersion: "v1", UID: "leaf", OwnerReferences: []metav1.OwnerReference{shared.OwnerRef(false)}}
	external := ownershiptest.Object{Ref: at("", "Secret", "alpha", "external"), APIVersion: "v1", UID: "external"}
	for _, tc := range []struct {
		name                      string
		external, denied, missing bool
		certain, possible         int
	}{
		{"both owners collected", false, false, false, 4, 0},
		{"live owner preserves descendants", true, false, false, 2, 0},
		{"withheld owner leaves uncertainty", true, true, false, 2, 2},
		{"missing owner does not preserve descendants", true, false, true, 4, 0},
	} {
		t.Run(tc.name, func(t *testing.T) {
			w := ownershiptest.World{Resources: []ownership.ServedResource{
				{Version: "v1", Kind: "ConfigMap", Resource: "configmaps", Namespaced: true, Verbs: []string{"get", "list", "watch", "delete"}},
				{Version: "v1", Kind: "Secret", Resource: "secrets", Namespaced: true, Verbs: []string{"get", "list", "watch", "delete"}},
			}, Objects: []ownershiptest.Object{root, left, right, shared, leaf}}
			if tc.external {
				w.Objects[3].OwnerReferences = append(w.Objects[3].OwnerReferences, external.OwnerRef(false))
				if !tc.missing {
					w.Objects = append(w.Objects, external)
				}
			}
			var a ownership.Access = ownership.Unrestricted()
			if tc.denied {
				a = access{denied: []resourceid.GroupKind{{Kind: "Secret"}}}
			}
			got := view(t, w, a).Deletion(context.Background(), root.Ref, 100)
			if len(got.Dependents) != tc.certain || len(got.Possible) != tc.possible {
				t.Fatalf("got certain %v possible %v", got.Dependents, got.Possible)
			}
		})
	}
}

func TestDeletionBoundAndCancellation(t *testing.T) {
	w := ownershiptest.Fixture()
	r := at("apps", "Deployment", "alpha", "web")
	got := view(t, w, ownership.Unrestricted()).Deletion(context.Background(), r, 1)
	if !got.Truncated || len(got.Dependents) != 0 {
		t.Fatalf("bounded = %+v", got)
	}
	ctx, cancel := context.WithCancel(context.Background())
	cancel()
	got = view(t, w, ownership.Unrestricted()).Deletion(ctx, r, 100)
	if !got.Truncated || len(got.Dependents) != 0 {
		t.Fatalf("canceled = %+v", got)
	}
}

func TestDeletionCyclesInvalidReferencesAndUnvisitedCoOwner(t *testing.T) {
	for _, mode := range []string{"cap", "cycle", "unserved", "unserved reference version", "different owner kind", "invalid"} {
		t.Run(mode, func(t *testing.T) {
			r := ownershiptest.Object{Ref: at("", "ConfigMap", "alpha", "root"), APIVersion: "v1", UID: "root"}
			a := ownershiptest.Object{Ref: at("", "ConfigMap", "alpha", "a"), APIVersion: "v1", UID: "a", OwnerReferences: []metav1.OwnerReference{r.OwnerRef(false)}}
			b := ownershiptest.Object{Ref: at("", "ConfigMap", "alpha", "z"), APIVersion: "v1", UID: "b", OwnerReferences: []metav1.OwnerReference{a.OwnerRef(false)}}
			c := ownershiptest.Object{Ref: at("", "ConfigMap", "alpha", "c"), APIVersion: "v1", UID: "c", OwnerReferences: []metav1.OwnerReference{a.OwnerRef(false), b.OwnerRef(false)}}
			limit, certain, possible := 100, 0, 3
			switch mode {
			case "cap":
				limit, certain, possible = 3, 1, 1
			case "cycle":
				a.OwnerReferences = append(a.OwnerReferences, b.OwnerRef(false))
			case "unserved reference version":
				a.OwnerReferences[0].APIVersion = "v99"
			case "different owner kind":
				a.OwnerReferences[0].Kind = "UndiscoveredKind"
				possible = 0
			case "unserved":
				a.OwnerReferences = append(a.OwnerReferences, metav1.OwnerReference{APIVersion: "missing.io/v1", Kind: "Ghost", Name: "ghost", UID: "ghost"})
			case "invalid":
				a.OwnerReferences = append(a.OwnerReferences, metav1.OwnerReference{APIVersion: "bad//v1", Kind: "Ghost", Name: "ghost", UID: "ghost"})
				possible = 0
			}
			w := ownershiptest.World{Resources: []ownership.ServedResource{{Version: "v1", Kind: "ConfigMap", Resource: "configmaps", Namespaced: true, Verbs: []string{"get", "list", "watch", "delete"}}}, Objects: []ownershiptest.Object{r, a, b, c}}
			got := view(t, w, ownership.Unrestricted()).Deletion(context.Background(), r.Ref, limit)
			if len(got.Dependents) != certain || len(got.Possible) != possible || got.Truncated != (mode == "cap") {
				t.Fatalf("projection %+v", got)
			}
		})
	}
}