internal/topology/crowd_test.go
Rama main · réplica de lectura del repositorio original.
package topology
import (
"context"
"strconv"
"testing"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic/fake"
"github.com/sophotechlabs/spinoza/internal/api"
)
const crowd = 210
func numbered(namespace string, index int, ready int64) *unstructured.Unstructured {
name := namespace + "-" + strconv.Itoa(index)
return &unstructured.Unstructured{Object: map[string]any{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": meta(name, namespace, name),
"spec": map[string]any{"replicas": int64(1)},
"status": map[string]any{"readyReplicas": ready},
}}
}
func crowdedCluster(namespaces []string, withOrphan bool) []runtime.Object {
objects := []runtime.Object{}
for _, namespace := range namespaces {
for index := range crowd {
ready := int64(1)
if namespace == "b" && index == 0 {
ready = 0
}
objects = append(objects, numbered(namespace, index, ready))
}
}
if withOrphan {
objects = append(objects, pod("cluster-owned", "pod-orphan", "Running", "True", owner{
kind: "Rollout",
name: "fleet",
uid: "rollout-fleet",
apiVersion: "argoproj.io/v1alpha1",
}, ""))
}
return objects
}
func crowdedDescs() map[string]api.ResourceDescriptor {
out := descs()
fleet := out["argoproj.io/v1alpha1/rollouts"]
fleet.Namespaced = false
out["argoproj.io/v1alpha1/rollouts"] = fleet
return out
}
func buildCrowd(t *testing.T, namespaces []string, withOrphan bool, req Request) api.Graph {
t.Helper()
dyn := fake.NewSimpleDynamicClientWithCustomListKinds(
runtime.NewScheme(),
listKinds(),
crowdedCluster(namespaces, withOrphan)...,
)
return Build(context.Background(), listerFor(dyn), crowdedDescs(), req)
}
func TestTooManyNodesFoldIntoNamespaces(t *testing.T) {
graph := buildCrowd(t, []string{"a", "b"}, true, Request{})
nodes := nodesByID(graph)
quiet, ok := nodes["namespace/a"]
if !ok {
t.Fatalf("the quiet namespace did not fold into one node: %d nodes", len(graph.Nodes))
}
if quiet.Contains != crowd {
t.Fatalf("the namespace node folded %d objects, want %d", quiet.Contains, crowd)
}
if quiet.Category != categoryNamespace {
t.Fatalf("the namespace node is a %q", quiet.Category)
}
if quiet.Resource != "namespaces" {
t.Fatalf("the namespace node resolved to resource %q", quiet.Resource)
}
if _, shown := nodes["a-0"]; shown {
t.Fatal("a Deployment inside the quiet namespace is still drawn")
}
}
func TestTheNamespaceWithSomethingBrokenStaysOpen(t *testing.T) {
nodes := nodesByID(buildCrowd(t, []string{"a", "b"}, true, Request{}))
if _, shown := nodes["b-0"]; !shown {
t.Fatal("the failing Deployment folded away")
}
busy, ok := nodes["namespace/b"]
if !ok {
t.Fatal("the namespace node vanished")
}
if busy.Contains != crowd-1 {
t.Fatalf("the namespace node folded %d objects, want %d", busy.Contains, crowd-1)
}
}
func TestWhatIsInNoNamespaceGetsItsOwnDistrict(t *testing.T) {
nodes := nodesByID(buildCrowd(t, []string{"a", "b"}, true, Request{}))
district, ok := nodes["namespace/"]
if !ok {
t.Fatal("what is in no namespace has nowhere to fold into")
}
if district.Name != "cluster-scoped" {
t.Fatalf("the district for what has no namespace is called %q", district.Name)
}
if district.Resource != "" {
t.Fatalf("the district for what has no namespace claims resource %q", district.Resource)
}
}
func TestOpeningANamespaceShowsAllOfIt(t *testing.T) {
graph := buildCrowd(t, []string{"a", "b"}, true, Request{Expanded: []string{"namespace/a"}})
nodes := nodesByID(graph)
if _, ok := nodes["a-0"]; !ok {
t.Fatal("a Deployment in the namespace that was opened is still folded away")
}
district, ok := nodes["namespace/a"]
if !ok {
t.Fatal("the namespace node vanished when it was opened")
}
if district.Contains != 0 {
t.Fatalf("the opened namespace still claims %d hidden objects", district.Contains)
}
if _, ok := nodes["b-1"]; ok {
t.Fatal("opening one namespace opened another")
}
}
func TestOneCrowdedNamespaceHasNothingToFoldInto(t *testing.T) {
graph := buildCrowd(t, []string{"a"}, false, Request{Namespace: "a"})
if len(graph.Nodes) != crowd {
t.Fatalf("drew %d nodes, want %d", len(graph.Nodes), crowd)
}
}
func knotted(name, uid, ownerName, ownerUID string) *unstructured.Unstructured {
holder := meta(name, "prod", uid)
holder["ownerReferences"] = []any{map[string]any{
"apiVersion": "apps/v1",
"kind": "ReplicaSet",
"name": ownerName,
"uid": ownerUID,
"controller": true,
}}
return &unstructured.Unstructured{Object: map[string]any{
"apiVersion": "apps/v1",
"kind": "ReplicaSet",
"metadata": holder,
"spec": map[string]any{"replicas": int64(1)},
"status": map[string]any{"readyReplicas": int64(1)},
}}
}
func TestTwoObjectsOwningEachOtherDoNotHangTheFold(t *testing.T) {
dyn := fake.NewSimpleDynamicClientWithCustomListKinds(
runtime.NewScheme(),
listKinds(),
knotted("left", "rs-left", "right", "rs-right"),
knotted("right", "rs-right", "left", "rs-left"),
)
graph := Build(context.Background(), listerFor(dyn), descs(), Request{})
if len(graph.Nodes) != 0 {
t.Fatalf("drew %d nodes, want the cycle dropped rather than walked forever", len(graph.Nodes))
}
if len(graph.Edges) != 0 {
t.Fatalf("drew %d edges into nodes that are not there", len(graph.Edges))
}
}