karmada/pkg/util/selector_test.go

1090 lines
28 KiB
Go

/*
Copyright 2022 The Karmada Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
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{
Zones: []string{"zone1", "zone2", "zone3"},
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: cluster.Spec.Zones},
},
},
},
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 & region)",
affinity: policyv1alpha1.ClusterAffinity{
ClusterNames: []string{cluster.Name},
FieldSelector: &policyv1alpha1.FieldSelector{
MatchExpressions: []corev1.NodeSelectorRequirement{
{Key: ZoneField, Operator: corev1.NodeSelectorOpIn, Values: cluster.Spec.Zones},
{Key: RegionField, Operator: corev1.NodeSelectorOpIn, Values: []string{cluster.Spec.Region}},
},
},
},
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: cluster.Spec.Zones},
},
},
},
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: cluster.Spec.Zones},
},
},
},
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: cluster.Spec.Zones},
},
},
},
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: cluster.Spec.Zones},
},
},
},
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: cluster.Spec.Zones},
},
},
},
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: cluster.Spec.Zones},
},
},
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: cluster.Spec.Zones},
},
},
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: cluster.Spec.Zones},
},
},
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: cluster.Spec.Zones},
},
},
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: "all are set",
args: args{
cluster: &clusterv1alpha1.Cluster{
Spec: clusterv1alpha1.ClusterSpec{
Provider: "foo",
Region: "bar",
},
},
},
want: labels.Set{
ProviderField: "foo",
RegionField: "bar",
},
},
}
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)
}
})
}
}
func Test_matchZones(t *testing.T) {
tests := []struct {
name string
zoneMatchExpression *corev1.NodeSelectorRequirement
zones []string
matched bool
}{
{
name: "empty zones for In operator",
zoneMatchExpression: &corev1.NodeSelectorRequirement{
Key: ZoneField,
Operator: corev1.NodeSelectorOpIn,
Values: []string{"foo"},
},
zones: nil,
matched: false,
},
{
name: "partial zones for In operator",
zoneMatchExpression: &corev1.NodeSelectorRequirement{
Key: ZoneField,
Operator: corev1.NodeSelectorOpIn,
Values: []string{"foo"},
},
zones: []string{"foo", "bar"},
matched: false,
},
{
name: "all zones for In operator",
zoneMatchExpression: &corev1.NodeSelectorRequirement{
Key: ZoneField,
Operator: corev1.NodeSelectorOpIn,
Values: []string{"foo", "bar"},
},
zones: []string{"foo", "bar"},
matched: true,
},
{
name: "empty zones for NotIn operator",
zoneMatchExpression: &corev1.NodeSelectorRequirement{
Key: ZoneField,
Operator: corev1.NodeSelectorOpNotIn,
Values: []string{"foo"},
},
zones: nil,
matched: true,
},
{
name: "partial zones for NotIn operator",
zoneMatchExpression: &corev1.NodeSelectorRequirement{
Key: ZoneField,
Operator: corev1.NodeSelectorOpNotIn,
Values: []string{"foo"},
},
zones: []string{"foo", "bar"},
matched: false,
},
{
name: "empty zones for Exists operator",
zoneMatchExpression: &corev1.NodeSelectorRequirement{
Key: ZoneField,
Operator: corev1.NodeSelectorOpExists,
Values: nil,
},
zones: nil,
matched: false,
},
{
name: "empty zones for DoesNotExist operator",
zoneMatchExpression: &corev1.NodeSelectorRequirement{
Key: ZoneField,
Operator: corev1.NodeSelectorOpDoesNotExist,
Values: nil,
},
zones: nil,
matched: true,
},
{
name: "unknown operator",
zoneMatchExpression: &corev1.NodeSelectorRequirement{
Key: ZoneField,
Operator: corev1.NodeSelectorOpGt,
Values: nil,
},
zones: []string{"foo"},
matched: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := matchZones(tt.zoneMatchExpression, tt.zones); got != tt.matched {
t.Errorf("matchZones() got %v, but expected %v", got, tt.matched)
}
})
}
}