77 "fmt"
88 "io/fs"
99 "path/filepath"
10+ "reflect"
1011 "regexp"
1112 "testing"
1213 texttemplate "text/template"
@@ -17,8 +18,6 @@ import (
1718 commonclient "github.com/codeready-toolchain/toolchain-common/pkg/client"
1819 "github.com/codeready-toolchain/toolchain-common/pkg/test"
1920 "github.com/pkg/errors"
20- apierrors "k8s.io/apimachinery/pkg/api/errors"
21- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2221 "k8s.io/apimachinery/pkg/types"
2322 runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
2423
@@ -141,12 +140,10 @@ func getTestTemplates(t *testing.T) map[string][]byte {
141140}
142141
143142func TestGenerateTiers (t * testing.T ) {
144-
145143 s := addToScheme (t )
146144 logf .SetLogger (zap .New (zap .UseDevMode (true )))
147145
148146 t .Run ("ok" , func (t * testing.T ) {
149-
150147 expectedTemplateRefs := map [string ]map [string ]interface {}{
151148 "advanced" : {
152149 "clusterresources" : "advanced-clusterresources-abcd123-654321a" ,
@@ -280,22 +277,35 @@ func TestGenerateTiers(t *testing.T) {
280277 // when
281278 err := GenerateTiers (s , ensureObjectFuncForClient (clt ), namespace , getTestMetadata (), getTestTemplates (t ))
282279 require .NoError (t , err )
280+ // here we're just capturing the state after the first call so that we can compare with the state after the second call
281+ tierTmpls := toolchainv1alpha1.TierTemplateList {}
282+ err = clt .List (context .TODO (), & tierTmpls , runtimeclient .InNamespace (namespace ))
283+ require .NoError (t , err )
284+ require .Len (t , tierTmpls .Items , 16 ) // 4 items for advanced and base tiers + 3 for nocluster tier + 4 for appstudio
285+ origTemplates := map [string ]* toolchainv1alpha1.TierTemplate {}
286+ for _ , tmpl := range tierTmpls .Items {
287+ origTemplates [tmpl .Name ] = tmpl .DeepCopy ()
288+ }
283289
284290 // when calling CreateOrUpdateResources a second time
285291 err = GenerateTiers (s , ensureObjectFuncForClient (clt ), namespace , getTestMetadata (), getTestTemplates (t ))
286292
287293 // then
288294 require .NoError (t , err )
289295 // verify that all TierTemplate CRs were updated
290- tierTmpls : = toolchainv1alpha1.TierTemplateList {}
296+ tierTmpls = toolchainv1alpha1.TierTemplateList {}
291297 err = clt .List (context .TODO (), & tierTmpls , runtimeclient .InNamespace (namespace ))
292298 require .NoError (t , err )
293299 require .Len (t , tierTmpls .Items , 16 ) // 4 items for advanced and base tiers + 3 for nocluster tier + 4 for appstudio
300+ // check that the tier templates are unchanged
294301 for _ , tierTmpl := range tierTmpls .Items {
295- assert .Equal (t , int64 (1 ), tierTmpl .Generation ) // unchanged
296- }
297-
298- // verify that 4 NSTemplateTier CRs were created:
302+ // these two should always mean the same thing. If they don't, it means there's an issue with serde of
303+ // the templates where template json -> object in cluster -> template json doesn't yield the same thing.
304+ // (the json reprentation is used to detect generation change in our test.Client).
305+ // This is usually caused by e.g explicitly using a zero value of some property in the template file.
306+ assert .True (t , reflect .DeepEqual (origTemplates [tierTmpl .Name ].Spec , tierTmpl .Spec ), "deep equal different on %T %s" , tierTmpl , tierTmpl .Name )
307+ assert .Equal (t , int64 (1 ), tierTmpl .Generation , "generation different on %T %s" , tierTmpl , tierTmpl .Name ) // unchanged
308+ } // verify that 4 NSTemplateTier CRs were created:
299309 for _ , tierName := range []string {"advanced" , "base" , "nocluster" , "appstudio" } {
300310 tier := toolchainv1alpha1.NSTemplateTier {}
301311 err = clt .Get (context .TODO (), types.NamespacedName {Namespace : namespace , Name : tierName }, & tier )
@@ -446,27 +456,25 @@ func TestGenerateTiers(t *testing.T) {
446456 })
447457
448458 t .Run ("failures" , func (t * testing.T ) {
449-
450459 namespace := "host-operator" + uuid .NewString ()[:7 ]
451460
452461 t .Run ("nstemplatetiers" , func (t * testing.T ) {
453-
454- t .Run ("failed to create nstemplatetiers" , func (t * testing.T ) {
462+ t .Run ("failed to patch nstemplatetiers" , func (t * testing.T ) {
455463 // given
456464 clt := test .NewFakeClient (t )
457- clt .MockCreate = func (ctx context.Context , obj runtimeclient.Object , opts ... runtimeclient.CreateOption ) error {
458- if obj .GetObjectKind (). GroupVersionKind (). Kind == "NSTemplateTier" {
465+ clt .MockPatch = func (ctx context.Context , obj runtimeclient.Object , patch runtimeclient. Patch , opts ... runtimeclient.PatchOption ) error {
466+ if _ , ok := obj .( * toolchainv1alpha1. NSTemplateTier ); ok {
459467 // simulate a client/server error
460468 return errors .Errorf ("an error" )
461469 }
462- return clt . Client . Create (ctx , obj , opts ... )
470+ return test . Patch (ctx , clt , obj , patch , opts ... )
463471 }
464472
465473 // when
466474 err := GenerateTiers (s , ensureObjectFuncForClient (clt ), namespace , getTestMetadata (), getTestTemplates (t ))
467475 // then
468476 require .Error (t , err )
469- assert .Regexp (t , "unable to create or update the '\\ w+' NSTemplateTier: unable to create resource of kind: NSTemplateTier, version: v1alpha1 : an error" , err .Error ())
477+ assert .Regexp (t , "unable to create NSTemplateTiers: unable to create or update the '\\ w+' NSTemplateTier: unable to patch 'toolchain.dev.openshift.com/v1alpha1, Kind=NSTemplateTier' called ' \\ w+' in namespace '[a-zA-Z0-9-]+' : an error" , err .Error ())
470478 })
471479
472480 t .Run ("missing tier.yaml file" , func (t * testing.T ) {
@@ -481,40 +489,15 @@ func TestGenerateTiers(t *testing.T) {
481489 require .EqualError (t , err , "unable to init NSTemplateTier generator: tier appstudio is missing a tier.yaml file" )
482490 })
483491
484- t .Run ("failed to update nstemplatetiers" , func (t * testing.T ) {
485- // given
486- // initialize the client with an existing `advanced` NSTemplatetier
487- clt := test .NewFakeClient (t , & toolchainv1alpha1.NSTemplateTier {
488- ObjectMeta : metav1.ObjectMeta {
489- Namespace : namespace ,
490- Name : "advanced" ,
491- },
492- })
493- clt .MockUpdate = func (ctx context.Context , obj runtimeclient.Object , opts ... runtimeclient.UpdateOption ) error {
494- if obj .GetObjectKind ().GroupVersionKind ().Kind == "NSTemplateTier" {
495- // simulate a client/server error
496- return errors .Errorf ("an error" )
497- }
498- return clt .Client .Update (ctx , obj , opts ... )
499- }
500-
501- // when
502- err := GenerateTiers (s , ensureObjectFuncForClient (clt ), namespace , getTestMetadata (), getTestTemplates (t ))
503-
504- // then
505- require .Error (t , err )
506- assert .Contains (t , err .Error (), "unable to create NSTemplateTiers: unable to create or update the 'advanced' NSTemplateTier: unable to create resource of kind: NSTemplateTier, version: v1alpha1: unable to update the resource" )
507- })
508-
509- t .Run ("failed to create nstemplatetiers" , func (t * testing.T ) {
492+ t .Run ("failed to patch nstemplatetiers" , func (t * testing.T ) {
510493 // given
511494 clt := test .NewFakeClient (t )
512- clt .MockCreate = func (ctx context.Context , obj runtimeclient.Object , opts ... runtimeclient.CreateOption ) error {
495+ clt .MockPatch = func (ctx context.Context , obj runtimeclient.Object , patch runtimeclient. Patch , opts ... runtimeclient.PatchOption ) error {
513496 if _ , ok := obj .(* toolchainv1alpha1.TierTemplate ); ok {
514497 // simulate a client/server error
515498 return errors .Errorf ("an error" )
516499 }
517- return clt . Client . Create (ctx , obj , opts ... )
500+ return test . Patch (ctx , clt , obj , patch , opts ... )
518501 }
519502
520503 // when
@@ -529,7 +512,6 @@ func TestGenerateTiers(t *testing.T) {
529512}
530513
531514func TestLoadTemplatesByTiers (t * testing.T ) {
532-
533515 logf .SetLogger (zap .New (zap .UseDevMode (true )))
534516
535517 t .Run ("ok" , func (t * testing.T ) {
@@ -591,7 +573,6 @@ func TestLoadTemplatesByTiers(t *testing.T) {
591573 })
592574
593575 t .Run ("failures" , func (t * testing.T ) {
594-
595576 t .Run ("unparseable content" , func (t * testing.T ) {
596577 // given
597578 testTemplates := getTestTemplates (t )
@@ -663,13 +644,11 @@ func TestLoadTemplatesByTiers(t *testing.T) {
663644}
664645
665646func TestNewNSTemplateTier (t * testing.T ) {
666-
667647 s := scheme .Scheme
668648 err := toolchainv1alpha1 .AddToScheme (s )
669649 require .NoError (t , err )
670650
671651 t .Run ("ok" , func (t * testing.T ) {
672-
673652 t .Run ("with test assets" , func (t * testing.T ) {
674653 // given
675654 namespace := "host-operator-" + uuid .NewString ()[:7 ]
@@ -740,7 +719,6 @@ func TestNewTierTemplate(t *testing.T) {
740719 namespace := "host-operator-" + uuid .NewString ()[:7 ]
741720
742721 t .Run ("ok" , func (t * testing.T ) {
743-
744722 t .Run ("with test assets" , func (t * testing.T ) {
745723 // given
746724
@@ -780,7 +758,6 @@ func TestNewTierTemplate(t *testing.T) {
780758 })
781759
782760 t .Run ("failures" , func (t * testing.T ) {
783-
784761 t .Run ("invalid template" , func (t * testing.T ) {
785762 // given
786763 testTemplates := getTestTemplates (t )
@@ -796,15 +773,9 @@ func TestNewTierTemplate(t *testing.T) {
796773}
797774
798775func ensureObjectFuncForClient (cl runtimeclient.Client ) EnsureObject {
799- return func (toEnsure runtimeclient.Object , canUpdate bool , _ string ) (bool , error ) {
800- if ! canUpdate {
801- if err := cl .Create (context .TODO (), toEnsure ); err != nil && ! apierrors .IsAlreadyExists (err ) {
802- return false , err
803- }
804- return true , nil
805- }
806- applyCl := commonclient .NewApplyClient (cl )
807- return applyCl .ApplyObject (context .TODO (), toEnsure , commonclient .ForceUpdate (true ))
776+ return func (toEnsure runtimeclient.Object , _ string ) error {
777+ applyCl := commonclient .NewSSAApplyClient (cl , "testFieldManager" )
778+ return applyCl .ApplyObject (context .TODO (), toEnsure )
808779 }
809780}
810781
@@ -862,7 +833,6 @@ func expectedTemplateFromBasedOnTierConfig(t *testing.T, tier, templateFileName
862833}
863834
864835func TestNewNSTemplateTiers (t * testing.T ) {
865-
866836 // given
867837 s := addToScheme (t )
868838
0 commit comments