@@ -682,6 +682,182 @@ func TestClusterExtensionDeleteFinalizerFails(t *testing.T) {
682
682
require .Contains (t , cond .Message , finalizersMessage )
683
683
}
684
684
685
+ func TestClusterExtensionUpgradeFails (t * testing.T ) {
686
+ cl , reconciler := newClientAndReconciler (t )
687
+ reconciler .Unpacker = & MockUnpacker {
688
+ result : & source.Result {
689
+ State : source .StateUnpacked ,
690
+ Bundle : fstest.MapFS {},
691
+ },
692
+ }
693
+
694
+ ctx := context .Background ()
695
+ extKey := types.NamespacedName {Name : fmt .Sprintf ("cluster-extension-test-%s" , rand .String (8 ))}
696
+
697
+ t .Log ("When the cluster extension specifies a channel with version that exist" )
698
+ t .Log ("By initializing cluster state" )
699
+ pkgName := "prometheus"
700
+ pkgVer := "1.0.0"
701
+ pkgChan := "beta"
702
+ namespace := fmt .Sprintf ("test-ns-%s" , rand .String (8 ))
703
+ serviceAccount := fmt .Sprintf ("test-sa-%s" , rand .String (8 ))
704
+
705
+ clusterExtension := & ocv1alpha1.ClusterExtension {
706
+ ObjectMeta : metav1.ObjectMeta {Name : extKey .Name },
707
+ Spec : ocv1alpha1.ClusterExtensionSpec {
708
+ Source : ocv1alpha1.SourceConfig {
709
+ SourceType : "Catalog" ,
710
+ Catalog : & ocv1alpha1.CatalogSource {
711
+ PackageName : pkgName ,
712
+ Version : pkgVer ,
713
+ Channels : []string {pkgChan },
714
+ },
715
+ },
716
+ Install : ocv1alpha1.ClusterExtensionInstallConfig {
717
+ Namespace : namespace ,
718
+ ServiceAccount : ocv1alpha1.ServiceAccountReference {
719
+ Name : serviceAccount ,
720
+ },
721
+ },
722
+ },
723
+ }
724
+ err := cl .Create (ctx , clusterExtension )
725
+ require .NoError (t , err )
726
+
727
+ t .Log ("It sets resolution success status" )
728
+ t .Log ("By running reconcile" )
729
+ reconciler .Resolver = resolve .Func (func (_ context.Context , _ * ocv1alpha1.ClusterExtension , _ * ocv1alpha1.BundleMetadata ) (* declcfg.Bundle , * bsemver.Version , * declcfg.Deprecation , error ) {
730
+ v := bsemver .MustParse ("1.0.0" )
731
+ return & declcfg.Bundle {
732
+ Name : "prometheus.v1.0.0" ,
733
+ Package : "prometheus" ,
734
+ Image :
"quay.io/operatorhubio/[email protected] " ,
735
+ }, & v , nil , nil
736
+ })
737
+ reconciler .Applier = & MockApplier {
738
+ objs : []client.Object {},
739
+ }
740
+ reconciler .Manager = & MockManagedContentCacheManager {
741
+ cache : & MockManagedContentCache {},
742
+ }
743
+ res , err := reconciler .Reconcile (ctx , ctrl.Request {NamespacedName : extKey })
744
+ require .Equal (t , ctrl.Result {}, res )
745
+ require .NoError (t , err )
746
+
747
+ t .Log ("By fetching updated cluster extension after reconcile" )
748
+ require .NoError (t , cl .Get (ctx , extKey , clusterExtension ))
749
+
750
+ t .Log ("By checking the status fields" )
751
+ require .Equal (t , ocv1alpha1.BundleMetadata {Name : "prometheus.v1.0.0" , Version : "1.0.0" }, clusterExtension .Status .Install .Bundle )
752
+
753
+ t .Log ("By checking the expected installed conditions" )
754
+ installedCond := apimeta .FindStatusCondition (clusterExtension .Status .Conditions , ocv1alpha1 .TypeInstalled )
755
+ require .NotNil (t , installedCond )
756
+ require .Equal (t , metav1 .ConditionTrue , installedCond .Status )
757
+ require .Equal (t , ocv1alpha1 .ReasonSucceeded , installedCond .Reason )
758
+
759
+ t .Log ("By checking the expected progressing conditions" )
760
+ progressingCond := apimeta .FindStatusCondition (clusterExtension .Status .Conditions , ocv1alpha1 .TypeProgressing )
761
+ require .NotNil (t , progressingCond )
762
+ require .Equal (t , metav1 .ConditionFalse , progressingCond .Status )
763
+ require .Equal (t , ocv1alpha1 .ReasonSucceeded , progressingCond .Reason )
764
+
765
+ tcs := []struct {
766
+ name string
767
+ modification func (* controllers.ClusterExtensionReconciler )
768
+ }{
769
+ {
770
+ name : "getting installed bundle fails" ,
771
+ modification : func (cer * controllers.ClusterExtensionReconciler ) {
772
+ cer .InstalledBundleGetter = & MockInstalledBundleGetter {
773
+ bundle : nil ,
774
+ err : errors .New ("boom" ),
775
+ }
776
+ },
777
+ },
778
+ {
779
+ name : "resolution fails" ,
780
+ modification : func (cer * controllers.ClusterExtensionReconciler ) {
781
+ cer .Resolver = resolve .Func (func (_ context.Context , _ * ocv1alpha1.ClusterExtension , _ * ocv1alpha1.BundleMetadata ) (* declcfg.Bundle , * bsemver.Version , * declcfg.Deprecation , error ) {
782
+ return nil , nil , nil , errors .New ("boom" )
783
+ })
784
+ },
785
+ },
786
+ {
787
+ name : "unpack fails" ,
788
+ modification : func (cer * controllers.ClusterExtensionReconciler ) {
789
+ cer .Unpacker = & MockUnpacker {
790
+ err : errors .New ("boom" ),
791
+ }
792
+ },
793
+ },
794
+ {
795
+ name : "applier fails" ,
796
+ modification : func (cer * controllers.ClusterExtensionReconciler ) {
797
+ cer .Applier = & MockApplier {
798
+ err : errors .New ("boom" ),
799
+ }
800
+ },
801
+ },
802
+ }
803
+ for _ , tc := range tcs {
804
+ t .Run (tc .name , func (t * testing.T ) {
805
+ t .Log ("By resetting the reconciler" )
806
+ reconciler .InstalledBundleGetter = & MockInstalledBundleGetter {
807
+ bundle : & ocv1alpha1.BundleMetadata {Name : "prometheus.v1.0.0" , Version : "1.0.0" },
808
+ }
809
+ reconciler .Unpacker = & MockUnpacker {
810
+ result : & source.Result {
811
+ State : source .StateUnpacked ,
812
+ Bundle : fstest.MapFS {},
813
+ },
814
+ }
815
+ reconciler .Resolver = resolve .Func (func (_ context.Context , _ * ocv1alpha1.ClusterExtension , _ * ocv1alpha1.BundleMetadata ) (* declcfg.Bundle , * bsemver.Version , * declcfg.Deprecation , error ) {
816
+ v := bsemver .MustParse ("1.0.0" )
817
+ return & declcfg.Bundle {
818
+ Name : "prometheus.v1.0.0" ,
819
+ Package : "prometheus" ,
820
+ Image :
"quay.io/operatorhubio/[email protected] " ,
821
+ }, & v , nil , nil
822
+ })
823
+ reconciler .Applier = & MockApplier {
824
+ objs : []client.Object {},
825
+ }
826
+ // Here we modify the reconciler to test that a failure of each
827
+ // step up until the installation is successful results in no modification
828
+ // of the existing Installed condition and associated fields, but does
829
+ // result in modification of the Progressing condition to communicate the
830
+ // failure.
831
+ t .Log ("By modifying the reconciler to fail on next reconcile" )
832
+ tc .modification (reconciler )
833
+
834
+ t .Log ("By running reconciliation again" )
835
+ res , err = reconciler .Reconcile (ctx , ctrl.Request {NamespacedName : extKey })
836
+ require .Equal (t , ctrl.Result {}, res )
837
+ require .Error (t , err )
838
+
839
+ t .Log ("By fetching updated cluster extension after reconcile" )
840
+ require .NoError (t , cl .Get (ctx , extKey , clusterExtension ))
841
+
842
+ t .Log ("By checking the status fields" )
843
+ require .Equal (t , ocv1alpha1.BundleMetadata {Name : "prometheus.v1.0.0" , Version : "1.0.0" }, clusterExtension .Status .Install .Bundle )
844
+
845
+ t .Log ("By checking the expected installed conditions" )
846
+ installedCond = apimeta .FindStatusCondition (clusterExtension .Status .Conditions , ocv1alpha1 .TypeInstalled )
847
+ require .NotNil (t , installedCond )
848
+ require .Equal (t , metav1 .ConditionTrue , installedCond .Status )
849
+ require .Equal (t , ocv1alpha1 .ReasonSucceeded , installedCond .Reason )
850
+
851
+ t .Log ("By checking the expected progressing conditions" )
852
+ progressingCond = apimeta .FindStatusCondition (clusterExtension .Status .Conditions , ocv1alpha1 .TypeProgressing )
853
+ require .NotNil (t , progressingCond )
854
+ require .Equal (t , metav1 .ConditionTrue , progressingCond .Status )
855
+ require .Equal (t , ocv1alpha1 .ReasonRetrying , progressingCond .Reason )
856
+ })
857
+ }
858
+ require .NoError (t , cl .DeleteAllOf (ctx , & ocv1alpha1.ClusterExtension {}))
859
+ }
860
+
685
861
func verifyInvariants (ctx context.Context , t * testing.T , c client.Client , ext * ocv1alpha1.ClusterExtension ) {
686
862
key := client .ObjectKeyFromObject (ext )
687
863
require .NoError (t , c .Get (ctx , key , ext ))
0 commit comments