@@ -20,6 +20,7 @@ import (
20
20
"reflect"
21
21
"testing"
22
22
23
+ "github.com/google/go-cmp/cmp"
23
24
corev1 "k8s.io/api/core/v1"
24
25
"k8s.io/apimachinery/pkg/api/resource"
25
26
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -31,6 +32,7 @@ import (
31
32
featuregatetesting "k8s.io/component-base/featuregate/testing"
32
33
"k8s.io/kubernetes/pkg/apis/core"
33
34
"k8s.io/kubernetes/pkg/features"
35
+ "k8s.io/utils/ptr"
34
36
)
35
37
36
38
func testVolumeClaim (name string , namespace string , spec core.PersistentVolumeClaimSpec ) * core.PersistentVolumeClaim {
@@ -40,6 +42,122 @@ func testVolumeClaim(name string, namespace string, spec core.PersistentVolumeCl
40
42
}
41
43
}
42
44
45
+ func TestPersistentVolumeClaimEvaluatorMatchingScopes (t * testing.T ) {
46
+ evaluator := NewPersistentVolumeClaimEvaluator (nil )
47
+ testCases := map [string ]struct {
48
+ claim * core.PersistentVolumeClaim
49
+ selectors []corev1.ScopedResourceSelectorRequirement
50
+ wantSelectors []corev1.ScopedResourceSelectorRequirement
51
+ }{
52
+ "EmptyPVC" : {
53
+ claim : & core.PersistentVolumeClaim {},
54
+ selectors : []corev1.ScopedResourceSelectorRequirement {
55
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpDoesNotExist },
56
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpExists },
57
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" }},
58
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpNotIn , Values : []string {"class4" }},
59
+ },
60
+ wantSelectors : []corev1.ScopedResourceSelectorRequirement {
61
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpDoesNotExist },
62
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpNotIn , Values : []string {"class4" }},
63
+ },
64
+ },
65
+ "VolumeAttributesClass" : {
66
+ claim : & core.PersistentVolumeClaim {
67
+ Spec : core.PersistentVolumeClaimSpec {
68
+ VolumeAttributesClassName : ptr .To ("class1" ),
69
+ },
70
+ },
71
+ selectors : []corev1.ScopedResourceSelectorRequirement {
72
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpDoesNotExist },
73
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpExists },
74
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" }},
75
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class4" }},
76
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpNotIn , Values : []string {"class4" }},
77
+ },
78
+ wantSelectors : []corev1.ScopedResourceSelectorRequirement {
79
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpExists },
80
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" }},
81
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpNotIn , Values : []string {"class4" }},
82
+ },
83
+ },
84
+ "VolumeAttributesClassWithTarget" : {
85
+ claim : & core.PersistentVolumeClaim {
86
+ Spec : core.PersistentVolumeClaimSpec {
87
+ VolumeAttributesClassName : ptr .To ("class1" ),
88
+ },
89
+ Status : core.PersistentVolumeClaimStatus {
90
+ CurrentVolumeAttributesClassName : ptr .To ("class2" ),
91
+ },
92
+ },
93
+ selectors : []corev1.ScopedResourceSelectorRequirement {
94
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpDoesNotExist },
95
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpExists },
96
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" }},
97
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class2" }},
98
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" , "class2" }},
99
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" , "class2" , "class4" }},
100
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class4" }},
101
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpNotIn , Values : []string {"class4" }},
102
+ },
103
+ wantSelectors : []corev1.ScopedResourceSelectorRequirement {
104
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpExists },
105
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" }},
106
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class2" }},
107
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" , "class2" }},
108
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" , "class2" , "class4" }},
109
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpNotIn , Values : []string {"class4" }},
110
+ },
111
+ },
112
+ "VolumeAttributesClassWithModityStatus" : {
113
+ claim : & core.PersistentVolumeClaim {
114
+ Spec : core.PersistentVolumeClaimSpec {
115
+ VolumeAttributesClassName : ptr .To ("class1" ),
116
+ },
117
+ Status : core.PersistentVolumeClaimStatus {
118
+ CurrentVolumeAttributesClassName : ptr .To ("class2" ),
119
+ ModifyVolumeStatus : & core.ModifyVolumeStatus {
120
+ TargetVolumeAttributesClassName : "class3" ,
121
+ },
122
+ },
123
+ },
124
+ selectors : []corev1.ScopedResourceSelectorRequirement {
125
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpDoesNotExist },
126
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpExists },
127
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" }},
128
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class2" }},
129
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class3" }},
130
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" , "class2" , "class3" }},
131
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" , "class2" , "class3" , "class4" }},
132
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class4" }},
133
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpNotIn , Values : []string {"class4" }},
134
+ },
135
+ wantSelectors : []corev1.ScopedResourceSelectorRequirement {
136
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpExists },
137
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" }},
138
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class2" }},
139
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class3" }},
140
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" , "class2" , "class3" }},
141
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpIn , Values : []string {"class1" , "class2" , "class3" , "class4" }},
142
+ {ScopeName : corev1 .ResourceQuotaScopeVolumeAttributesClass , Operator : corev1 .ScopeSelectorOpNotIn , Values : []string {"class4" }},
143
+ },
144
+ },
145
+ }
146
+
147
+ for testName , testCase := range testCases {
148
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .VolumeAttributesClass , true )
149
+ t .Run (testName , func (t * testing.T ) {
150
+ gotSelectors , err := evaluator .MatchingScopes (testCase .claim , testCase .selectors )
151
+ if err != nil {
152
+ t .Error (err )
153
+ }
154
+ if diff := cmp .Diff (testCase .wantSelectors , gotSelectors ); diff != "" {
155
+ t .Errorf ("%v: unexpected diff (-want, +got):\n %s" , testName , diff )
156
+ }
157
+ })
158
+ }
159
+ }
160
+
43
161
func TestPersistentVolumeClaimEvaluatorUsage (t * testing.T ) {
44
162
classGold := "gold"
45
163
validClaim := testVolumeClaim ("foo" , "ns" , core.PersistentVolumeClaimSpec {
0 commit comments