@@ -23,14 +23,21 @@ import (
23
23
"testing"
24
24
"time"
25
25
26
+ "github.com/google/go-cmp/cmp"
26
27
. "github.com/onsi/gomega"
27
28
"github.com/pkg/errors"
28
29
corev1 "k8s.io/api/core/v1"
29
30
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31
+ utilfeature "k8s.io/component-base/featuregate/testing"
32
+ "k8s.io/utils/pointer"
30
33
"sigs.k8s.io/controller-runtime/pkg/client"
31
34
32
35
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
36
+ runtimecatalog "sigs.k8s.io/cluster-api/exp/runtime/catalog"
37
+ runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
38
+ "sigs.k8s.io/cluster-api/feature"
33
39
tlog "sigs.k8s.io/cluster-api/internal/log"
40
+ fakeruntimeclient "sigs.k8s.io/cluster-api/internal/runtime/client/fake"
34
41
"sigs.k8s.io/cluster-api/internal/test/builder"
35
42
)
36
43
@@ -308,3 +315,233 @@ func isOwnerReferenceEqual(a, b metav1.OwnerReference) bool {
308
315
}
309
316
return true
310
317
}
318
+
319
+ func TestReconciler_reconcileVariables (t * testing.T ) {
320
+ defer utilfeature .SetFeatureGateDuringTest (t , feature .Gates , feature .RuntimeSDK , true )()
321
+
322
+ g := NewWithT (t )
323
+ catalog := runtimecatalog .New ()
324
+ _ = runtimehooksv1 .AddToCatalog (catalog )
325
+
326
+ clusterClassWithInlineVariables := builder .ClusterClass (metav1 .NamespaceDefault , "class1" ).
327
+ WithVariables (
328
+ []clusterv1.ClusterClassVariable {
329
+ {
330
+ Name : "cpu" ,
331
+ Schema : clusterv1.VariableSchema {
332
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
333
+ Type : "integer" ,
334
+ },
335
+ },
336
+ },
337
+ {
338
+ Name : "memory" ,
339
+ Schema : clusterv1.VariableSchema {
340
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
341
+ Type : "string" ,
342
+ },
343
+ },
344
+ },
345
+ }... ,
346
+ )
347
+ tests := []struct {
348
+ name string
349
+ clusterClass * clusterv1.ClusterClass
350
+ want []clusterv1.ClusterClassStatusVariable
351
+ patchResponse * runtimehooksv1.DiscoverVariablesResponse
352
+ wantErr bool
353
+ }{
354
+ {
355
+ name : "Reconcile inline variables to ClusterClass status" ,
356
+ clusterClass : clusterClassWithInlineVariables .DeepCopy ().Build (),
357
+ want : []clusterv1.ClusterClassStatusVariable {
358
+ {
359
+ Name : "cpu" ,
360
+ Definitions : []clusterv1.ClusterClassStatusVariableDefinition {
361
+ {
362
+ From : clusterv1 .VariableDefinitionFromInline ,
363
+ Schema : clusterv1.VariableSchema {
364
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
365
+ Type : "integer" ,
366
+ },
367
+ },
368
+ },
369
+ },
370
+ },
371
+ {
372
+ Name : "memory" ,
373
+ Definitions : []clusterv1.ClusterClassStatusVariableDefinition {
374
+ {
375
+ From : clusterv1 .VariableDefinitionFromInline ,
376
+ Schema : clusterv1.VariableSchema {
377
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
378
+ Type : "string" ,
379
+ },
380
+ },
381
+ },
382
+ },
383
+ },
384
+ },
385
+ },
386
+ {
387
+ name : "Reconcile variables from inline and external variables to ClusterClass status" ,
388
+ clusterClass : clusterClassWithInlineVariables .DeepCopy ().WithPatches (
389
+ []clusterv1.ClusterClassPatch {
390
+ {
391
+ Name : "patch1" ,
392
+ External : & clusterv1.ExternalPatchDefinition {
393
+ DiscoverVariablesExtension : pointer .String ("variables-one" ),
394
+ }}}).
395
+ Build (),
396
+ patchResponse : & runtimehooksv1.DiscoverVariablesResponse {
397
+ CommonResponse : runtimehooksv1.CommonResponse {
398
+ Status : runtimehooksv1 .ResponseStatusSuccess ,
399
+ },
400
+ Variables : []clusterv1.ClusterClassVariable {
401
+ {
402
+ Name : "cpu" ,
403
+ Schema : clusterv1.VariableSchema {
404
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
405
+ Type : "string" ,
406
+ },
407
+ },
408
+ },
409
+ {
410
+ Name : "memory" ,
411
+ Schema : clusterv1.VariableSchema {
412
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
413
+ Type : "string" ,
414
+ },
415
+ },
416
+ },
417
+ {
418
+ Name : "location" ,
419
+ Schema : clusterv1.VariableSchema {
420
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
421
+ Type : "string" ,
422
+ },
423
+ },
424
+ },
425
+ },
426
+ },
427
+ want : []clusterv1.ClusterClassStatusVariable {
428
+ {
429
+ Name : "cpu" ,
430
+ DefinitionsConflict : true ,
431
+ Definitions : []clusterv1.ClusterClassStatusVariableDefinition {
432
+ {
433
+ From : clusterv1 .VariableDefinitionFromInline ,
434
+ Schema : clusterv1.VariableSchema {
435
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
436
+ Type : "integer" ,
437
+ },
438
+ },
439
+ },
440
+ {
441
+ From : "patch1" ,
442
+ Schema : clusterv1.VariableSchema {
443
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
444
+ Type : "string" ,
445
+ },
446
+ },
447
+ },
448
+ },
449
+ },
450
+ {
451
+ Name : "location" ,
452
+ DefinitionsConflict : false ,
453
+ Definitions : []clusterv1.ClusterClassStatusVariableDefinition {
454
+ {
455
+ From : "patch1" ,
456
+ Schema : clusterv1.VariableSchema {
457
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
458
+ Type : "string" ,
459
+ },
460
+ },
461
+ },
462
+ },
463
+ },
464
+ {
465
+ Name : "memory" ,
466
+ DefinitionsConflict : false ,
467
+ Definitions : []clusterv1.ClusterClassStatusVariableDefinition {
468
+ {
469
+ From : clusterv1 .VariableDefinitionFromInline ,
470
+ Schema : clusterv1.VariableSchema {
471
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
472
+ Type : "string" ,
473
+ },
474
+ },
475
+ },
476
+ {
477
+ From : "patch1" ,
478
+ Schema : clusterv1.VariableSchema {
479
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
480
+ Type : "string" ,
481
+ },
482
+ },
483
+ },
484
+ },
485
+ },
486
+ },
487
+ },
488
+ {
489
+ name : "Error if external patch defines a variable with same name multiple times" ,
490
+ wantErr : true ,
491
+ clusterClass : clusterClassWithInlineVariables .DeepCopy ().WithPatches (
492
+ []clusterv1.ClusterClassPatch {
493
+ {
494
+ Name : "patch1" ,
495
+ External : & clusterv1.ExternalPatchDefinition {
496
+ DiscoverVariablesExtension : pointer .String ("variables-one" ),
497
+ }}}).
498
+ Build (),
499
+ patchResponse : & runtimehooksv1.DiscoverVariablesResponse {
500
+ CommonResponse : runtimehooksv1.CommonResponse {
501
+ Status : runtimehooksv1 .ResponseStatusSuccess ,
502
+ },
503
+ Variables : []clusterv1.ClusterClassVariable {
504
+ {
505
+ Name : "cpu" ,
506
+ Schema : clusterv1.VariableSchema {
507
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
508
+ Type : "string" ,
509
+ },
510
+ },
511
+ },
512
+ {
513
+ Name : "cpu" ,
514
+ Schema : clusterv1.VariableSchema {
515
+ OpenAPIV3Schema : clusterv1.JSONSchemaProps {
516
+ Type : "integer" ,
517
+ },
518
+ },
519
+ },
520
+ },
521
+ },
522
+ },
523
+ }
524
+ for _ , tt := range tests {
525
+ t .Run (tt .name , func (t * testing.T ) {
526
+ fakeRuntimeClient := fakeruntimeclient .NewRuntimeClientBuilder ().
527
+ WithCallExtensionResponses (
528
+ map [string ]runtimehooksv1.ResponseObject {
529
+ "variables-one" : tt .patchResponse ,
530
+ }).
531
+ WithCatalog (catalog ).
532
+ Build ()
533
+
534
+ r := & Reconciler {
535
+ RuntimeClient : fakeRuntimeClient ,
536
+ }
537
+
538
+ err := r .reconcileVariables (ctx , tt .clusterClass )
539
+ if tt .wantErr {
540
+ g .Expect (err ).To (HaveOccurred ())
541
+ return
542
+ }
543
+ g .Expect (err ).NotTo (HaveOccurred ())
544
+ g .Expect (tt .clusterClass .Status .Variables ).To (Equal (tt .want ), cmp .Diff (tt .clusterClass .Status .Variables , tt .want ))
545
+ })
546
+ }
547
+ }
0 commit comments