@@ -23,14 +23,21 @@ import (
2323 "testing"
2424 "time"
2525
26+ "github.com/google/go-cmp/cmp"
2627 . "github.com/onsi/gomega"
2728 "github.com/pkg/errors"
2829 corev1 "k8s.io/api/core/v1"
2930 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31+ utilfeature "k8s.io/component-base/featuregate/testing"
32+ "k8s.io/utils/pointer"
3033 "sigs.k8s.io/controller-runtime/pkg/client"
3134
3235 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"
3339 tlog "sigs.k8s.io/cluster-api/internal/log"
40+ fakeruntimeclient "sigs.k8s.io/cluster-api/internal/runtime/client/fake"
3441 "sigs.k8s.io/cluster-api/internal/test/builder"
3542)
3643
@@ -308,3 +315,233 @@ func isOwnerReferenceEqual(a, b metav1.OwnerReference) bool {
308315 }
309316 return true
310317}
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