1
16
17 package csistoragecapacity
18
19 import (
20 "testing"
21
22 "github.com/google/go-cmp/cmp"
23 apiequality "k8s.io/apimachinery/pkg/api/equality"
24 "k8s.io/apimachinery/pkg/api/resource"
25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
27 "k8s.io/kubernetes/pkg/apis/storage"
28 )
29
30
31 func getValidCSIStorageCapacity(name string, capacityStr string) *storage.CSIStorageCapacity {
32 mib := resource.MustParse("1Mi")
33 c := &storage.CSIStorageCapacity{
34 ObjectMeta: metav1.ObjectMeta{
35 Name: name,
36 Namespace: metav1.NamespaceDefault,
37 ResourceVersion: "1",
38 },
39 StorageClassName: "bar",
40 NodeTopology: &metav1.LabelSelector{
41 MatchExpressions: []metav1.LabelSelectorRequirement{
42 {
43 Key: "node",
44 Operator: metav1.LabelSelectorOpIn,
45 Values: []string{
46 "node1",
47 },
48 },
49 },
50 },
51 Capacity: &mib,
52 }
53 if capacityStr != "" {
54 capacityQuantity := resource.MustParse(capacityStr)
55 c.Capacity = &capacityQuantity
56 }
57 return c
58 }
59
60 func TestCSIStorageCapacityStrategy(t *testing.T) {
61 ctx := genericapirequest.WithRequestInfo(genericapirequest.NewContext(), &genericapirequest.RequestInfo{
62 APIGroup: "storage.k8s.io",
63 APIVersion: "v1alphav1",
64 Resource: "csistoragecapacities",
65 })
66 if !Strategy.NamespaceScoped() {
67 t.Errorf("CSIStorageCapacity must be namespace scoped")
68 }
69 if Strategy.AllowCreateOnUpdate() {
70 t.Errorf("CSIStorageCapacity should not allow create on update")
71 }
72
73 capacity := getValidCSIStorageCapacity("valid", "")
74 original := capacity.DeepCopy()
75 Strategy.PrepareForCreate(ctx, capacity)
76 errs := Strategy.Validate(ctx, capacity)
77 if len(errs) != 0 {
78 t.Errorf("unexpected error validating %v", errs)
79 }
80
81
82 if !apiequality.Semantic.DeepEqual(capacity, original) {
83 t.Errorf("unexpected objects difference after creation: %v", cmp.Diff(original, capacity))
84 }
85
86
87 fields := []struct {
88 name string
89 update func(capacity *storage.CSIStorageCapacity)
90 }{
91 {
92 name: "Topology",
93 update: func(capacity *storage.CSIStorageCapacity) {
94 capacity.NodeTopology.MatchLabels = map[string]string{"some-label": "some-value"}
95 },
96 },
97 {
98 name: "StorageClass",
99 update: func(capacity *storage.CSIStorageCapacity) {
100 capacity.StorageClassName += "-suffix"
101 },
102 },
103 }
104 for _, field := range fields {
105 t.Run(field.name, func(t *testing.T) {
106 newCapacity := capacity.DeepCopy()
107 field.update(newCapacity)
108 Strategy.PrepareForUpdate(ctx, newCapacity, capacity)
109 errs = Strategy.ValidateUpdate(ctx, newCapacity, capacity)
110 if len(errs) == 0 {
111 t.Errorf("Expected a validation error")
112 }
113 })
114 }
115 }
116
117 func TestCSIStorageCapacityValidation(t *testing.T) {
118 ctx := genericapirequest.WithRequestInfo(genericapirequest.NewContext(), &genericapirequest.RequestInfo{
119 APIGroup: "storage.k8s.io",
120 APIVersion: "v1alphav1",
121 Resource: "csistoragecapacities",
122 })
123
124 tests := []struct {
125 name string
126 expectError bool
127 old, update *storage.CSIStorageCapacity
128 }{
129 {
130 name: "before: no capacity, update: 1Gi capacity",
131 old: getValidCSIStorageCapacity("test", ""),
132 update: getValidCSIStorageCapacity("test", "1Gi"),
133 },
134 {
135 name: "before: 1Gi capacity, update: no capacity",
136 old: getValidCSIStorageCapacity("test", "1Gi"),
137 update: getValidCSIStorageCapacity("test", ""),
138 },
139 {
140 name: "name change",
141 expectError: true,
142 old: getValidCSIStorageCapacity("a", ""),
143 update: getValidCSIStorageCapacity("b", ""),
144 },
145 {
146 name: "storage class name change",
147 expectError: true,
148 old: getValidCSIStorageCapacity("test", ""),
149 update: func() *storage.CSIStorageCapacity {
150 capacity := getValidCSIStorageCapacity("test", "")
151 capacity.StorageClassName += "-update"
152 return capacity
153 }(),
154 },
155 }
156
157 for _, test := range tests {
158 t.Run(test.name, func(t *testing.T) {
159 oldCapacity := test.old.DeepCopy()
160 Strategy.PrepareForCreate(ctx, oldCapacity)
161 errs := Strategy.Validate(ctx, oldCapacity)
162 if len(errs) != 0 {
163 t.Errorf("unexpected validating errors for create: %v", errs)
164 }
165
166 newCapacity := test.update.DeepCopy()
167 Strategy.PrepareForUpdate(ctx, newCapacity, test.old)
168 errs = Strategy.ValidateUpdate(ctx, newCapacity, oldCapacity)
169 if len(errs) > 0 && !test.expectError {
170 t.Errorf("unexpected validation failure: %+v", errs)
171 }
172 if len(errs) == 0 && test.expectError {
173 t.Errorf("validation unexpectedly succeeded")
174 }
175 })
176 }
177 }
178
View as plain text