package util import ( "reflect" "testing" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1" policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" ) func TestResourceMatches(t *testing.T) { resource := &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Pod", "metadata": map[string]interface{}{ "name": "test", "namespace": "default", "labels": map[string]interface{}{ "foo": "bar", }, }, }, } misMatch := policyv1alpha1.ResourceSelector{APIVersion: "v1", Kind: "Pod", Name: "unmatched"} matchAll := policyv1alpha1.ResourceSelector{APIVersion: "v1", Kind: "Pod"} matchLabels := policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", LabelSelector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, } matchName := policyv1alpha1.ResourceSelector{APIVersion: "v1", Kind: "Pod", Name: "test"} if p := ResourceSelectorPriority(resource, misMatch); p != PriorityMisMatch { t.Errorf("misMatch shall not be %v", p) return } if p := ResourceSelectorPriority(resource, matchAll); p != PriorityMatchAll { t.Errorf("matchAll shall not be %v", p) return } if p := ResourceSelectorPriority(resource, matchLabels); p != PriorityMatchLabelSelector { t.Errorf("matchLabels shall not be %v", p) return } if p := ResourceSelectorPriority(resource, matchName); p != PriorityMatchName { t.Errorf("matchName shall not be %v", p) return } type args struct { rs policyv1alpha1.ResourceSelector } tests := []struct { name string args args want bool }{ { name: "miss match", args: args{ rs: misMatch, }, want: false, }, { name: "match all", args: args{ rs: matchAll, }, want: true, }, { name: "match labels", args: args{ rs: matchLabels, }, want: true, }, { name: "match name", args: args{ rs: matchName, }, want: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := ResourceMatches(resource, tt.args.rs); got != tt.want { t.Errorf("ResourceMatches() = %v, want %v", got, tt.want) } }) } } func TestResourceSelectorPriority(t *testing.T) { resource := &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Pod", "metadata": map[string]interface{}{ "name": "test", "namespace": "default", "labels": map[string]interface{}{ "foo": "bar", }, }, }, } type args struct { rs policyv1alpha1.ResourceSelector } tests := []struct { name string args args want ImplicitPriority }{ { name: "APIVersion not matched", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "unmatched", Kind: "Pod", Name: "foo", Namespace: "default", }, }, want: PriorityMisMatch, }, { name: "Kind not matched", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Unmatched", Name: "foo", Namespace: "default", }, }, want: PriorityMisMatch, }, { name: "namespace not matched", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", Name: "foo", Namespace: "Unmatched", }, }, want: PriorityMisMatch, }, { name: "namespace unset and name matched", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", Name: "test", }, }, want: PriorityMatchName, }, { name: "[case 1] name not matched", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", Name: "unmatched", LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "foo": "bar", }, }, }, }, want: PriorityMisMatch, }, { name: "[case 1] name matched, labels not matched and ignore", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", Name: "test", LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "foo": "unmatched", }, }, }, }, want: PriorityMatchName, }, { name: "[case 2] name not matched, labels unset", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", Name: "unmatched", }, }, want: PriorityMisMatch, }, { name: "[case 2] name matched, labels unset", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", Name: "test", }, }, want: PriorityMatchName, }, { name: "[case 3] name unset, labels not matched", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "foo": "unmatched", }, }, }, }, want: PriorityMisMatch, }, { name: "[case 3] name unset, labels matched", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "foo": "bar", }, }, }, }, want: PriorityMatchLabelSelector, }, { name: "[case 4] name and labels unset, match all", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", }, }, want: PriorityMatchAll, }, { name: "[case 4] labels error", args: args{ rs: policyv1alpha1.ResourceSelector{ APIVersion: "v1", Kind: "Pod", LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "": "bar", }, }, }, }, want: PriorityMisMatch, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := ResourceSelectorPriority(resource, tt.args.rs); got != tt.want { t.Errorf("ResourceSelectorPriority() = %v, want %v", got, tt.want) } }) } } func TestClusterMatches(t *testing.T) { cluster := &clusterv1alpha1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: "cluster1", Labels: map[string]string{ "foo": "bar", }, }, Spec: clusterv1alpha1.ClusterSpec{ Zone: "zone1", Region: "region1", Provider: "provider1", }, } tests := []struct { name string affinity policyv1alpha1.ClusterAffinity want bool }{ { name: "test cluster excluded and names", affinity: policyv1alpha1.ClusterAffinity{ ExcludeClusters: []string{cluster.Name}, ClusterNames: []string{cluster.Name}, }, want: false, }, { name: "test cluster excluded and label selector", affinity: policyv1alpha1.ClusterAffinity{ ExcludeClusters: []string{cluster.Name}, LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, want: false, }, { name: "test cluster excluded and field selector", affinity: policyv1alpha1.ClusterAffinity{ ExcludeClusters: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Zone}}, }, }, }, want: false, }, { name: "test cluster names", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, }, want: true, }, { name: "test cluster names not matched", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{"cluster2"}, }, want: false, }, { name: "test cluster names and label selector", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, ClusterNames: []string{cluster.Name}, }, want: true, }, { name: "test cluster names and label selector not matched", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "unmatched"}, }, ClusterNames: []string{cluster.Name}, }, want: false, }, { name: "test cluster names and field selector(zone)", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Zone}}, }, }, }, want: true, }, { name: "test cluster names and field selector(provider)", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ProviderField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Provider}}, }, }, }, want: true, }, { name: "test cluster names and field selector(region)", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: RegionField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Region}}, }, }, }, want: true, }, { name: "test cluster names and field selector(zone not in)", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Zone}}, }, }, }, want: false, }, { name: "test cluster names and field selector(provider not in)", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ProviderField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Provider}}, }, }, }, want: false, }, { name: "test cluster names and field selector(region not in)", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: RegionField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Region}}, }, }, }, want: false, }, { name: "test label selector and field selector(zone)", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Zone}}, }, }, }, want: true, }, { name: "test label selector and field selector(provider)", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ProviderField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Provider}}, }, }, }, want: true, }, { name: "test label selector and field selector(region)", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: RegionField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Region}}, }, }, }, want: true, }, { name: "test label selector and field selector(zone not in)", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Zone}}, }, }, }, want: false, }, { name: "test label selector and field selector(provider)", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ProviderField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Provider}}, }, }, }, want: false, }, { name: "test label selector and field selector(region)", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: RegionField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Region}}, }, }, }, want: false, }, { name: "test label selector", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, want: true, }, { name: "test label selector not matched", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "unmatched"}, }, }, want: false, }, { name: "test empty cluster affinity matched", affinity: policyv1alpha1.ClusterAffinity{}, want: true, }, { name: "test label selector error", affinity: policyv1alpha1.ClusterAffinity{ LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"": "bar"}, }, }, want: false, }, { name: "test field selector error", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ""}, }, }, }, want: false, }, { name: "test field selector zone matched", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Zone}}, }, }, }, want: true, }, { name: "test field selector zone not matched", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Zone}}, }, }, }, want: false, }, { name: "test field selector zone not matched", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpIn, Values: []string{"zone2"}}, }, }, }, want: false, }, { name: "test field selector region matched", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: RegionField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Region}}, }, }, }, want: true, }, { name: "test field selector region not matched", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: RegionField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Region}}, }, }, }, want: false, }, { name: "test field selector region not matched", affinity: policyv1alpha1.ClusterAffinity{ ClusterNames: []string{cluster.Name}, FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: RegionField, Operator: corev1.NodeSelectorOpIn, Values: []string{"region2"}}, }, }, }, want: false, }, { name: "test field selector provider matched", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ProviderField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Provider}}, }, }, }, want: true, }, { name: "test field selector provider not matched", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ProviderField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Provider}}, }, }, }, want: false, }, { name: "test field selector provider not matched", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ProviderField, Operator: corev1.NodeSelectorOpIn, Values: []string{"provider2"}}, }, }, }, want: false, }, { name: "test field selector other key not matched", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: "metadata.name", Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Name}}, }, }, }, want: false, }, { name: "test field selector cluster names and label selector", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Zone}}, }, }, LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, ClusterNames: []string{cluster.Name}, }, want: true, }, { name: "test field selector cluster names and label selector not matched", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Zone}}, }, }, LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, ClusterNames: []string{"cluster2"}, }, want: false, }, { name: "test field selector cluster names and label selector not matched", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpNotIn, Values: []string{cluster.Spec.Zone}}, }, }, LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, ClusterNames: []string{cluster.Name}, }, want: false, }, { name: "test field selector cluster names and label selector not matched", affinity: policyv1alpha1.ClusterAffinity{ FieldSelector: &policyv1alpha1.FieldSelector{ MatchExpressions: []corev1.NodeSelectorRequirement{ {Key: ZoneField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Zone}}, }, }, LabelSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"foo": "Unmatched"}, }, ClusterNames: []string{cluster.Name}, }, want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := ClusterMatches(cluster, tt.affinity); got != tt.want { t.Errorf("ClusterMatches() = %v, want %v", got, tt.want) } }) } } func TestResourceMatchSelectors(t *testing.T) { resource := &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Pod", "metadata": map[string]interface{}{ "name": "test", "namespace": "default", "labels": map[string]interface{}{ "foo": "bar", }, }, }, } matched := policyv1alpha1.ResourceSelector{APIVersion: "v1", Kind: "Pod"} unmatched := policyv1alpha1.ResourceSelector{APIVersion: "v1", Kind: "Unmatched"} if !ResourceMatches(resource, matched) { t.Error("matched shall be matched") return } if ResourceMatches(resource, unmatched) { t.Error("unmatched shall not be matched") return } type args struct { selectors []policyv1alpha1.ResourceSelector } tests := []struct { name string args args want bool }{ { name: "empty", args: args{ selectors: nil, }, want: false, }, { name: "selectors are [matched, unmatched]", args: args{ selectors: []policyv1alpha1.ResourceSelector{matched, unmatched}, }, want: true, }, { name: "selectors are [unmatched, matched]", args: args{ selectors: []policyv1alpha1.ResourceSelector{unmatched, matched}, }, want: true, }, { name: "selectors are [unmatched, unmatched]", args: args{ selectors: []policyv1alpha1.ResourceSelector{unmatched, unmatched}, }, want: false, }, { name: "selectors are [matched, matched]", args: args{ selectors: []policyv1alpha1.ResourceSelector{matched, matched}, }, want: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := ResourceMatchSelectors(resource, tt.args.selectors...); got != tt.want { t.Errorf("ResourceMatchSelectors() = %v, want %v", got, tt.want) } }) } } func TestResourceMatchSelectorsPriority(t *testing.T) { resource := &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Pod", "metadata": map[string]interface{}{ "name": "test", "namespace": "default", "labels": map[string]interface{}{ "foo": "bar", }, }, }, } p1 := policyv1alpha1.ResourceSelector{APIVersion: "v1", Kind: "Pod"} p3 := policyv1alpha1.ResourceSelector{APIVersion: "v1", Kind: "Pod", Name: "test"} if p := ResourceSelectorPriority(resource, p1); p != PriorityMatchAll { t.Errorf("p1 shall not be %v", p) return } if p := ResourceSelectorPriority(resource, p3); p != PriorityMatchName { t.Errorf("p3 shall not be %v", p) return } type args struct { selectors []policyv1alpha1.ResourceSelector } tests := []struct { name string args args want ImplicitPriority }{ { name: "empty", args: args{ selectors: nil, }, want: 0, }, { name: "priority of selectors are [1, 1]", args: args{ selectors: []policyv1alpha1.ResourceSelector{p1, p1}, }, want: 1, }, { name: "priority of selectors are [1, 3]", args: args{ selectors: []policyv1alpha1.ResourceSelector{p1, p3}, }, want: 3, }, { name: "priority of selectors are [3, 1]", args: args{ selectors: []policyv1alpha1.ResourceSelector{p3, p1}, }, want: 3, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := ResourceMatchSelectorsPriority(resource, tt.args.selectors...); got != tt.want { t.Errorf("ResourceMatchSelectorsPriority() = %v, want %v", got, tt.want) } }) } } func Test_extractClusterFields(t *testing.T) { type args struct { cluster *clusterv1alpha1.Cluster } tests := []struct { name string args args want labels.Set }{ { name: "empty", args: args{ cluster: &clusterv1alpha1.Cluster{}, }, want: labels.Set{}, }, { name: "provider is set", args: args{ cluster: &clusterv1alpha1.Cluster{ Spec: clusterv1alpha1.ClusterSpec{ Provider: "foo", }, }, }, want: labels.Set{ ProviderField: "foo", }, }, { name: "region is set", args: args{ cluster: &clusterv1alpha1.Cluster{ Spec: clusterv1alpha1.ClusterSpec{ Region: "foo", }, }, }, want: labels.Set{ RegionField: "foo", }, }, { name: "zone is set", args: args{ cluster: &clusterv1alpha1.Cluster{ Spec: clusterv1alpha1.ClusterSpec{ Zone: "foo", }, }, }, want: labels.Set{ ZoneField: "foo", }, }, { name: "all are set", args: args{ cluster: &clusterv1alpha1.Cluster{ Spec: clusterv1alpha1.ClusterSpec{ Provider: "foo", Region: "bar", Zone: "baz", }, }, }, want: labels.Set{ ProviderField: "foo", RegionField: "bar", ZoneField: "baz", }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := extractClusterFields(tt.args.cluster); !reflect.DeepEqual(got, tt.want) { t.Errorf("extractClusterFields() = %v, want %v", got, tt.want) } }) } }