internal/unstr/unstr_test.go
Rama main · réplica de lectura del repositorio original.
package unstr
import (
"testing"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func object(fields map[string]any) *unstructured.Unstructured {
return &unstructured.Unstructured{Object: fields}
}
func conditioned(entries ...any) *unstructured.Unstructured {
return object(map[string]any{
"status": map[string]any{"conditions": entries},
})
}
func TestStringReadsANestedField(t *testing.T) {
obj := object(map[string]any{"spec": map[string]any{"url": "https://charts.example.com"}})
if got := String(obj, "spec", "url"); got != "https://charts.example.com" {
t.Fatalf("String = %q", got)
}
}
func TestStringIsEmptyForWhatIsNotThere(t *testing.T) {
obj := object(map[string]any{"spec": map[string]any{"replicas": int64(3)}})
cases := map[string][]string{
"a missing field": {"spec", "url"},
"a missing parent": {"status", "url"},
"the wrong type": {"spec", "replicas"},
}
for name, path := range cases {
t.Run(name, func(t *testing.T) {
if got := String(obj, path...); got != "" {
t.Fatalf("String = %q, want empty", got)
}
})
}
}
func TestBoolReadsANestedFlag(t *testing.T) {
obj := object(map[string]any{"spec": map[string]any{"suspend": true}})
if !Bool(obj, "spec", "suspend") {
t.Fatal("Bool did not read the flag")
}
if Bool(obj, "spec", "missing") {
t.Fatal("Bool invented a flag")
}
}
func TestIntReadsANestedNumber(t *testing.T) {
obj := object(map[string]any{"status": map[string]any{"readyReplicas": int64(4)}})
if got := Int(obj, "status", "readyReplicas"); got != 4 {
t.Fatalf("Int = %d", got)
}
if got := Int(obj, "status", "missing"); got != 0 {
t.Fatalf("Int = %d, want zero for what is not there", got)
}
}
func TestSliceReadsANestedList(t *testing.T) {
obj := object(map[string]any{"spec": map[string]any{"containers": []any{"app", "sidecar"}}})
if got := Slice(obj, "spec", "containers"); len(got) != 2 {
t.Fatalf("Slice = %v", got)
}
if got := Slice(obj, "spec", "missing"); got != nil {
t.Fatalf("Slice = %v, want nil for what is not there", got)
}
}
func TestMapReadsANestedObject(t *testing.T) {
obj := object(map[string]any{"status": map[string]any{"usage": map[string]any{"cpu": "5m"}}})
usage, ok := Map(obj, "status", "usage")
if !ok {
t.Fatal("Map did not read the object")
}
if usage["cpu"] != "5m" {
t.Fatalf("usage = %v", usage)
}
if _, ok := Map(obj, "status", "missing"); ok {
t.Fatal("Map invented an object")
}
}
func TestAtReadsAStringKey(t *testing.T) {
entry := map[string]any{"type": "Ready", "observedGeneration": int64(2)}
if got := At(entry, "type"); got != "Ready" {
t.Fatalf("At = %q", got)
}
if got := At(entry, "observedGeneration"); got != "" {
t.Fatalf("At = %q, want empty for a value that is not a string", got)
}
if got := At(entry, "missing"); got != "" {
t.Fatalf("At = %q, want empty for a key that is not there", got)
}
}
func TestReadyReportsTheStatusAndMessage(t *testing.T) {
obj := conditioned(
map[string]any{"type": "Reconciling", "status": "True"},
map[string]any{"type": "Ready", "status": "False", "message": "artifact not found"},
)
status, message := Ready(obj)
if status != "False" {
t.Fatalf("status = %q", status)
}
if message != "artifact not found" {
t.Fatalf("message = %q", message)
}
}
func TestReadyIsEmptyWithoutAReadyCondition(t *testing.T) {
cases := map[string]*unstructured.Unstructured{
"no conditions at all": object(map[string]any{"status": map[string]any{}}),
"no ready condition": conditioned(map[string]any{"type": "Reconciling", "status": "True"}),
"a condition that is not an object": conditioned("Ready"),
}
for name, obj := range cases {
t.Run(name, func(t *testing.T) {
status, message := Ready(obj)
if status != "" || message != "" {
t.Fatalf("Ready = %q, %q, want both empty", status, message)
}
})
}
}
func TestReadySummaryNamesWhatIsWrong(t *testing.T) {
cases := []struct {
name string
obj *unstructured.Unstructured
want string
}{
{
name: "ready",
obj: conditioned(map[string]any{"type": "Ready", "status": "True"}),
want: "Ready",
},
{
name: "not ready with a reason",
obj: conditioned(map[string]any{"type": "Ready", "status": "False", "reason": "ArtifactFailed"}),
want: "ArtifactFailed",
},
{
name: "not ready without a reason",
obj: conditioned(map[string]any{"type": "Ready", "status": "False"}),
want: "NotReady",
},
{
name: "no ready condition",
obj: conditioned(map[string]any{"type": "Reconciling", "status": "True"}),
want: "",
},
{
name: "a condition that is not an object",
obj: conditioned("Ready"),
want: "",
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if got := ReadySummary(tc.obj); got != tc.want {
t.Fatalf("ReadySummary = %q, want %q", got, tc.want)
}
})
}
}