@@ -34,6 +34,7 @@ import (
34
34
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
35
35
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
36
36
"k8s.io/apimachinery/pkg/types"
37
+ "k8s.io/apimachinery/pkg/util/sets"
37
38
"k8s.io/apimachinery/pkg/util/wait"
38
39
ctrlruntime "sigs.k8s.io/controller-runtime"
39
40
ctrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -287,6 +288,98 @@ func TestARSOnlyContainsSelectedCRDVersion(t *testing.T) {
287
288
}
288
289
}
289
290
291
+ func TestMultiVersionCRD (t * testing.T ) {
292
+ const (
293
+ apiExportName = "example.com"
294
+ )
295
+
296
+ // force a non-standard order, because it should not matter for the sync
297
+ var selectedVersions = []string {"v2" , "v1" }
298
+
299
+ ctx := context .Background ()
300
+ ctrlruntime .SetLogger (logr .Discard ())
301
+
302
+ // setup a test environment in kcp
303
+ orgKubconfig := utils .CreateOrganization (t , ctx , "ars-multi-versions" , apiExportName )
304
+
305
+ // start a service cluster
306
+ envtestKubeconfig , envtestClient , _ := utils .RunEnvtest (t , []string {
307
+ "test/crds/crontab-multi-versions.yaml" ,
308
+ })
309
+
310
+ // publish Crontabs
311
+ t .Logf ("Publishing CronTabs…" )
312
+ pr := & syncagentv1alpha1.PublishedResource {
313
+ ObjectMeta : metav1.ObjectMeta {
314
+ Name : "publish-crontabs" ,
315
+ },
316
+ Spec : syncagentv1alpha1.PublishedResourceSpec {
317
+ Resource : syncagentv1alpha1.SourceResourceDescriptor {
318
+ APIGroup : "example.com" ,
319
+ Versions : selectedVersions ,
320
+ Kind : "CronTab" ,
321
+ },
322
+ },
323
+ }
324
+
325
+ if err := envtestClient .Create (ctx , pr ); err != nil {
326
+ t .Fatalf ("Failed to create PublishedResource: %v" , err )
327
+ }
328
+
329
+ // let the agent do its thing
330
+ utils .RunAgent (ctx , t , "bob" , orgKubconfig , envtestKubeconfig , apiExportName )
331
+
332
+ // wait for the APIExport to be updated
333
+ t .Logf ("Waiting for APIExport to be updated…" )
334
+ orgClient := utils .GetClient (t , orgKubconfig )
335
+ apiExportKey := types.NamespacedName {Name : apiExportName }
336
+
337
+ var arsName string
338
+ err := wait .PollUntilContextTimeout (ctx , 500 * time .Millisecond , 1 * time .Minute , false , func (ctx context.Context ) (done bool , err error ) {
339
+ apiExport := & kcpapisv1alpha1.APIExport {}
340
+ err = orgClient .Get (ctx , apiExportKey , apiExport )
341
+ if err != nil {
342
+ return false , err
343
+ }
344
+
345
+ if len (apiExport .Spec .LatestResourceSchemas ) == 0 {
346
+ return false , nil
347
+ }
348
+
349
+ arsName = apiExport .Spec .LatestResourceSchemas [0 ]
350
+
351
+ return true , nil
352
+ })
353
+ if err != nil {
354
+ t .Fatalf ("Failed to wait for APIExport to be updated: %v" , err )
355
+ }
356
+
357
+ // check the APIResourceSchema
358
+ ars := & kcpapisv1alpha1.APIResourceSchema {}
359
+ err = orgClient .Get (ctx , types.NamespacedName {Name : arsName }, ars )
360
+ if err != nil {
361
+ t .Fatalf ("APIResourceSchema does not exist: %v" , err )
362
+ }
363
+
364
+ if len (ars .Spec .Versions ) != len (selectedVersions ) {
365
+ t .Fatalf ("Expected %d versions to remain in the ARS, but found %d." , len (selectedVersions ), len (ars .Spec .Versions ))
366
+ }
367
+
368
+ // Projection tests already ensure the correct order, all we have to check
369
+ // here is that all versions are present (and more importantly that creating
370
+ // the multi-version ARS has worked at all).
371
+ expectedVersions := sets .New (selectedVersions ... )
372
+ foundVersions := sets .New [string ]()
373
+
374
+ for _ , v := range ars .Spec .Versions {
375
+ foundVersions .Insert (v .Name )
376
+ }
377
+
378
+ if ! expectedVersions .Equal (foundVersions ) {
379
+ t .Fatalf ("Expected versions %v, but ARS contains %v." , sets .List (expectedVersions ), sets .List (foundVersions ))
380
+ }
381
+ }
382
+
290
383
func TestProjection (t * testing.T ) {
291
384
const (
292
385
apiExportName = "example.com"
0 commit comments