karmada/pkg/resourceinterpreter/defaultinterpreter/prune/prune_test.go

233 lines
6.4 KiB
Go
Executable File

package prune
import (
"fmt"
"strings"
"testing"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/karmada-io/karmada/pkg/util"
)
type field []string
func (f field) String() string {
return "." + strings.Join(f, ".")
}
type test struct {
name string
workload *unstructured.Unstructured
extraHooks []func(*unstructured.Unstructured)
unexpectedFields []field
unexpectedResource string
shouldNotRemoveFields []field
shouldNotRemoveResource string
containsFunc func(interface{}, string) bool
}
func TestRemoveIrrelevantField(t *testing.T) {
var tests = []*test{
{
name: "remove common object irrelevant fields",
workload: &unstructured.Unstructured{
Object: map[string]interface{}{
"metadata": map[string]interface{}{
"creationTimestamp": "2023-03-13T05:00:41Z",
"deletionTimestamp": "2023-03-13T06:00:41Z",
"deletionGracePeriodSeconds": 10,
"generation": 2,
"managedFields": []map[string]interface{}{
{
"apiVersion": "v1",
"fieldsType": "FieldsV1",
"manager": "name",
"operation": "Apply",
},
},
"resourceVersion": "22222",
"selfLink": "http://example.com",
"uid": "db56a4a6-0dff-465a-b046-2c1dea42a42b",
"ownerReferences": []map[string]interface{}{
{
"apiVersion": "v1",
"kind": "Pod",
"name": "foo",
"uid": "fb11a9a6-1daa-265b-c046-1c1dea42a42c",
},
},
"finalizers": []string{"foregroundDeletion"},
},
"status": map[string]interface{}{},
},
},
extraHooks: nil,
unexpectedFields: []field{
{"metadata", "creationTimestamp"},
{"metadata", "deletionTimestamp"},
{"metadata", "deletionGracePeriodSeconds"},
{"metadata", "generation"},
{"metadata", "managedFields"},
{"metadata", "resourceVersion"},
{"metadata", "selfLink"},
{"metadata", "uid"},
{"metadata", "ownerReferences"},
{"metadata", "finalizers"},
{"status"},
},
},
{
name: "remove service irrelevant fields",
workload: &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": util.ServiceKind,
"spec": map[string]interface{}{
"clusterIP": "10.10.10.10",
"clusterIPs": []string{"10.10.10.10"},
},
},
},
extraHooks: nil,
unexpectedFields: []field{
{"spec", "clusterIP"},
{"spec", "clusterIPs"},
},
},
{
name: "remove job irrelevant fields",
workload: &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": util.JobKind,
"spec": map[string]interface{}{
"selector": map[string]interface{}{
"matchLabels": map[string]interface{}{
"foo": "bar",
"controller-uid": "ab11a9a6-1daa-265b-c046-1c1dea42a42c",
},
},
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"controller-uid": "ab11a9a6-1daa-265b-c046-1c1dea42a42c",
"job-name": "test-job",
"foo": "bar",
},
},
},
"ttlSecondsAfterFinished": 10,
},
},
},
extraHooks: []func(*unstructured.Unstructured){RemoveJobTTLSeconds},
unexpectedFields: []field{
{"spec", "selector", "matchLabels", "controller-uid"},
{"spec", "template", "metadata", "labels", "controller-uid"},
{"spec", "template", "metadata", "labels", "job-name"},
{"spec", "ttlSecondsAfterFinished"},
},
shouldNotRemoveFields: []field{
{"spec", "selector", "matchLabels", "foo"},
{"spec", "template", "metadata", "labels", "foo"},
},
},
{
name: "remove serviceaccount irrelevant fields",
workload: &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": util.ServiceAccountKind,
"metadata": map[string]interface{}{
"name": "foo",
},
"secrets": []interface{}{
conv(map[string]interface{}{
"name": "foo-token-6pgxf",
}),
conv(map[string]interface{}{
"name": "foo-dockercfg-zdr2j",
}),
},
},
},
extraHooks: nil,
unexpectedFields: []field{{"secrets"}},
unexpectedResource: "foo-token-6pgxf",
shouldNotRemoveFields: []field{{"secrets"}},
shouldNotRemoveResource: "foo-dockercfg-zdr2j",
containsFunc: func(obj interface{}, resource string) bool {
maps, _ := obj.([]interface{})
for _, m := range maps {
if m.(map[string]interface{})["name"] == resource {
return true
}
}
return false
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := RemoveIrrelevantField(tt.workload, tt.extraHooks...); err != nil {
t.Fatalf("RemoveIrrelevantField() expects no error but got: %v", err)
return
}
unexpectedFields, err := getUnexpectedFields(tt)
if err != nil {
t.Fatal(err)
return
}
if len(unexpectedFields) > 0 {
t.Errorf("RemoveIrrelevantField() failed to remove irrelevant fields: %v", unexpectedFields)
}
shouldNotRemoveFields, err := getShouldNotRemoveFields(tt)
if err != nil {
t.Fatal(err)
return
}
if len(shouldNotRemoveFields) > 0 {
t.Errorf("RemoveIrrelevantField() should not remove those fields: %v", shouldNotRemoveFields)
}
})
}
}
func getUnexpectedFields(t *test) ([]field, error) {
var unexpectedFields []field
for _, field := range t.unexpectedFields {
val, found, err := unstructured.NestedFieldNoCopy(t.workload.Object, field...)
if err != nil {
return nil, fmt.Errorf("NestedFieldNoCopy() expect no error but got: %v", err)
}
if found {
if t.containsFunc == nil || t.containsFunc(val, t.unexpectedResource) {
unexpectedFields = append(unexpectedFields, field)
}
}
}
return unexpectedFields, nil
}
func getShouldNotRemoveFields(t *test) ([]field, error) {
var shouldNotRemoveFields []field
for _, field := range t.shouldNotRemoveFields {
val, found, err := unstructured.NestedFieldNoCopy(t.workload.Object, field...)
if err != nil {
return nil, fmt.Errorf("NestedFieldNoCopy() expect no error but got: %v", err)
}
if !found || (t.containsFunc != nil && !t.containsFunc(val, t.shouldNotRemoveResource)) {
shouldNotRemoveFields = append(shouldNotRemoveFields, field)
}
}
return shouldNotRemoveFields, nil
}
func conv(m map[string]interface{}) interface{} {
return m
}