@@ -66,14 +66,22 @@ func getManifestString(t *testing.T, crdFile string) string {
66
66
return string (buff )
67
67
}
68
68
69
+ func wantErrorMsgs (wantMsgs []string ) require.ErrorAssertionFunc {
70
+ return func (t require.TestingT , haveErr error , _ ... interface {}) {
71
+ for _ , wantMsg := range wantMsgs {
72
+ require .ErrorContains (t , haveErr , wantMsg )
73
+ }
74
+ }
75
+ }
76
+
69
77
// TestInstall exists only for completeness as Install() is currently a no-op. It can be used as
70
78
// a template for real tests in the future if the func is implemented.
71
79
func TestInstall (t * testing.T ) {
72
80
tests := []struct {
73
81
name string
74
82
oldCrdPath string
75
83
release * release.Release
76
- wantErrMsgs [] string
84
+ requireErr require. ErrorAssertionFunc
77
85
wantCrdGetErr error
78
86
}{
79
87
{
@@ -91,7 +99,7 @@ func TestInstall(t *testing.T) {
91
99
Name : "test-release" ,
92
100
Manifest : "abcd" ,
93
101
},
94
- wantErrMsgs : []string {"json: cannot unmarshal string into Go value of type unstructured.detector" },
102
+ requireErr : wantErrorMsgs ( []string {"json: cannot unmarshal string into Go value of type unstructured.detector" }) ,
95
103
},
96
104
{
97
105
name : "release with no CRD objects" ,
@@ -107,7 +115,7 @@ func TestInstall(t *testing.T) {
107
115
Manifest : getManifestString (t , "crd-valid-upgrade.json" ),
108
116
},
109
117
wantCrdGetErr : fmt .Errorf ("error!" ),
110
- wantErrMsgs : []string {"error!" },
118
+ requireErr : wantErrorMsgs ( []string {"error!" }) ,
111
119
},
112
120
{
113
121
name : "fail to get old crd, not found error" ,
@@ -123,7 +131,7 @@ func TestInstall(t *testing.T) {
123
131
Name : "test-release" ,
124
132
Manifest : getManifestString (t , "crd-invalid" ),
125
133
},
126
- wantErrMsgs : []string {"json: cannot unmarshal" },
134
+ requireErr : wantErrorMsgs ( []string {"json: cannot unmarshal" }) ,
127
135
},
128
136
{
129
137
name : "valid upgrade" ,
@@ -142,7 +150,7 @@ func TestInstall(t *testing.T) {
142
150
Name : "test-release" ,
143
151
Manifest : getManifestString (t , "crd-invalid-upgrade.json" ),
144
152
},
145
- wantErrMsgs : []string {
153
+ requireErr : wantErrorMsgs ( []string {
146
154
`scope:` ,
147
155
`storedVersionRemoval:` ,
148
156
`enum:` ,
@@ -156,7 +164,7 @@ func TestInstall(t *testing.T) {
156
164
`minLength:` ,
157
165
`minProperties:` ,
158
166
`default:` ,
159
- },
167
+ }) ,
160
168
},
161
169
{
162
170
name : "new crd validation failure for existing field removal" ,
@@ -167,9 +175,9 @@ func TestInstall(t *testing.T) {
167
175
Name : "test-release" ,
168
176
Manifest : getManifestString (t , "crd-field-removed.json" ),
169
177
},
170
- wantErrMsgs : []string {
178
+ requireErr : wantErrorMsgs ( []string {
171
179
`existingFieldRemoval:` ,
172
- },
180
+ }) ,
173
181
},
174
182
{
175
183
name : "new crd validation should not fail on description changes" ,
@@ -187,10 +195,8 @@ func TestInstall(t *testing.T) {
187
195
t .Run (tc .name , func (t * testing.T ) {
188
196
preflight := newMockPreflight (getCrdFromManifestFile (t , tc .oldCrdPath ), tc .wantCrdGetErr )
189
197
err := preflight .Install (context .Background (), tc .release )
190
- if len (tc .wantErrMsgs ) != 0 {
191
- for _ , expectedErrMsg := range tc .wantErrMsgs {
192
- require .ErrorContains (t , err , expectedErrMsg )
193
- }
198
+ if tc .requireErr != nil {
199
+ tc .requireErr (t , err )
194
200
} else {
195
201
require .NoError (t , err )
196
202
}
@@ -203,7 +209,7 @@ func TestUpgrade(t *testing.T) {
203
209
name string
204
210
oldCrdPath string
205
211
release * release.Release
206
- wantErrMsgs [] string
212
+ requireErr require. ErrorAssertionFunc
207
213
wantCrdGetErr error
208
214
}{
209
215
{
@@ -221,7 +227,7 @@ func TestUpgrade(t *testing.T) {
221
227
Name : "test-release" ,
222
228
Manifest : "abcd" ,
223
229
},
224
- wantErrMsgs : []string {"json: cannot unmarshal string into Go value of type unstructured.detector" },
230
+ requireErr : wantErrorMsgs ( []string {"json: cannot unmarshal string into Go value of type unstructured.detector" }) ,
225
231
},
226
232
{
227
233
name : "release with no CRD objects" ,
@@ -237,7 +243,7 @@ func TestUpgrade(t *testing.T) {
237
243
Manifest : getManifestString (t , "crd-valid-upgrade.json" ),
238
244
},
239
245
wantCrdGetErr : fmt .Errorf ("error!" ),
240
- wantErrMsgs : []string {"error!" },
246
+ requireErr : wantErrorMsgs ( []string {"error!" }) ,
241
247
},
242
248
{
243
249
name : "fail to get old crd, not found error" ,
@@ -253,7 +259,7 @@ func TestUpgrade(t *testing.T) {
253
259
Name : "test-release" ,
254
260
Manifest : getManifestString (t , "crd-invalid" ),
255
261
},
256
- wantErrMsgs : []string {"json: cannot unmarshal" },
262
+ requireErr : wantErrorMsgs ( []string {"json: cannot unmarshal" }) ,
257
263
},
258
264
{
259
265
name : "valid upgrade" ,
@@ -272,7 +278,7 @@ func TestUpgrade(t *testing.T) {
272
278
Name : "test-release" ,
273
279
Manifest : getManifestString (t , "crd-invalid-upgrade.json" ),
274
280
},
275
- wantErrMsgs : []string {
281
+ requireErr : wantErrorMsgs ( []string {
276
282
`scope:` ,
277
283
`storedVersionRemoval:` ,
278
284
`enum:` ,
@@ -286,7 +292,7 @@ func TestUpgrade(t *testing.T) {
286
292
`minLength:` ,
287
293
`minProperties:` ,
288
294
`default:` ,
289
- },
295
+ }) ,
290
296
},
291
297
{
292
298
name : "new crd validation failure for existing field removal" ,
@@ -297,9 +303,9 @@ func TestUpgrade(t *testing.T) {
297
303
Name : "test-release" ,
298
304
Manifest : getManifestString (t , "crd-field-removed.json" ),
299
305
},
300
- wantErrMsgs : []string {
306
+ requireErr : wantErrorMsgs ( []string {
301
307
`existingFieldRemoval:` ,
302
- },
308
+ }) ,
303
309
},
304
310
{
305
311
name : "webhook conversion strategy exists" ,
@@ -316,9 +322,9 @@ func TestUpgrade(t *testing.T) {
316
322
Name : "test-release" ,
317
323
Manifest : getManifestString (t , "crd-conversion-no-webhook.json" ),
318
324
},
319
- wantErrMsgs : []string {
325
+ requireErr : wantErrorMsgs ( []string {
320
326
`validating upgrade for CRD "crontabs.stable.example.com": v1 <-> v2: ^.spec.foobarbaz: enum: allowed enum values removed` ,
321
- },
327
+ }) ,
322
328
},
323
329
{
324
330
name : "new crd validation should not fail on description changes" ,
@@ -330,16 +336,43 @@ func TestUpgrade(t *testing.T) {
330
336
Manifest : getManifestString (t , "crd-description-changed.json" ),
331
337
},
332
338
},
339
+ {
340
+ name : "success when old crd and new crd contain the exact same validation issues" ,
341
+ oldCrdPath : "crd-conversion-no-webhook.json" ,
342
+ release : & release.Release {
343
+ Name : "test-release" ,
344
+ Manifest : getManifestString (t , "crd-conversion-no-webhook.json" ),
345
+ },
346
+ },
347
+ {
348
+ name : "failure when old crd and new crd contain the exact same validation issues, but new crd introduces another validation issue" ,
349
+ oldCrdPath : "crd-conversion-no-webhook.json" ,
350
+ release : & release.Release {
351
+ Name : "test-release" ,
352
+ Manifest : getManifestString (t , "crd-conversion-no-webhook-extra-issue.json" ),
353
+ },
354
+ requireErr : func (t require.TestingT , err error , _ ... interface {}) {
355
+ require .ErrorContains (t , err ,
356
+ `validating upgrade for CRD "crontabs.stable.example.com":` ,
357
+ )
358
+ // The newly introduced issue is reported
359
+ require .Contains (t , err .Error (),
360
+ `v1 <-> v2: ^.spec.extraField: type: type changed : "boolean" -> "string"` ,
361
+ )
362
+ // The existing issue is not reported
363
+ require .NotContains (t , err .Error (),
364
+ `v1 <-> v2: ^.spec.foobarbaz: enum: allowed enum values removed` ,
365
+ )
366
+ },
367
+ },
333
368
}
334
369
335
370
for _ , tc := range tests {
336
371
t .Run (tc .name , func (t * testing.T ) {
337
372
preflight := newMockPreflight (getCrdFromManifestFile (t , tc .oldCrdPath ), tc .wantCrdGetErr )
338
373
err := preflight .Upgrade (context .Background (), tc .release )
339
- if len (tc .wantErrMsgs ) != 0 {
340
- for _ , expectedErrMsg := range tc .wantErrMsgs {
341
- require .ErrorContains (t , err , expectedErrMsg )
342
- }
374
+ if tc .requireErr != nil {
375
+ tc .requireErr (t , err )
343
376
} else {
344
377
require .NoError (t , err )
345
378
}
0 commit comments