@@ -3,6 +3,8 @@ package e2e
3
3
import (
4
4
"encoding/json"
5
5
"fmt"
6
+ "strings"
7
+ "sync"
6
8
"testing"
7
9
8
10
"github.com/coreos/go-semver/semver"
@@ -196,7 +198,7 @@ var (
196
198
Selector : & metav1.LabelSelector {
197
199
MatchLabels : map [string ]string {"app" : "nginx" },
198
200
},
199
- Replicas : & doubleInstance ,
201
+ Replicas : & singleInstance ,
200
202
Template : corev1.PodTemplateSpec {
201
203
ObjectMeta : metav1.ObjectMeta {
202
204
Labels : map [string ]string {"app" : "nginx" },
@@ -612,3 +614,149 @@ func TestSusbcriptionWithStartingCSV(t *testing.T) {
612
614
require .NoError (t , err )
613
615
}
614
616
617
+ func TestSubscriptionUpdatesMultipleIntermediates (t * testing.T ) {
618
+ defer cleaner .NotifyTestComplete (t , true )
619
+
620
+ crdPlural := genName ("ins" )
621
+ crdName := crdPlural + ".cluster.com"
622
+
623
+ crd := apiextensions.CustomResourceDefinition {
624
+ ObjectMeta : metav1.ObjectMeta {
625
+ Name : crdName ,
626
+ },
627
+ Spec : apiextensions.CustomResourceDefinitionSpec {
628
+ Group : "cluster.com" ,
629
+ Version : "v1alpha1" ,
630
+ Names : apiextensions.CustomResourceDefinitionNames {
631
+ Plural : crdPlural ,
632
+ Singular : crdPlural ,
633
+ Kind : crdPlural ,
634
+ ListKind : "list" + crdPlural ,
635
+ },
636
+ Scope : "Namespaced" ,
637
+ },
638
+ }
639
+
640
+ // Create CSV
641
+ packageName := genName ("nginx-" )
642
+ stableChannel := "stable"
643
+
644
+ namedStrategy := newNginxInstallStrategy (genName ("dep-" ), nil , nil )
645
+ csvA := newCSV ("nginx-a" , testNamespace , "" , * semver .New ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd }, nil , namedStrategy )
646
+ csvB := newCSV ("nginx-b" , testNamespace , "nginx-a" , * semver .New ("0.2.0" ), []apiextensions.CustomResourceDefinition {crd }, nil , namedStrategy )
647
+ csvC := newCSV ("nginx-c" , testNamespace , "nginx-b" , * semver .New ("0.3.0" ), []apiextensions.CustomResourceDefinition {crd }, nil , namedStrategy )
648
+
649
+ // Create PackageManifests
650
+ manifests := []registry.PackageManifest {
651
+ {
652
+ PackageName : packageName ,
653
+ Channels : []registry.PackageChannel {
654
+ {Name : stableChannel , CurrentCSVName : csvA .GetName ()},
655
+ },
656
+ DefaultChannelName : stableChannel ,
657
+ },
658
+ }
659
+
660
+ // Create the CatalogSource with just one version
661
+ c := newKubeClient (t )
662
+ crc := newCRClient (t )
663
+ catalogSourceName := genName ("mock-nginx-" )
664
+ _ , cleanupCatalogSource := createInternalCatalogSource (t , c , crc , catalogSourceName , testNamespace , manifests , []apiextensions.CustomResourceDefinition {crd }, []v1alpha1.ClusterServiceVersion {csvA })
665
+ defer cleanupCatalogSource ()
666
+
667
+ // Attempt to get the catalog source before creating install plan
668
+ _ , err := fetchCatalogSource (t , crc , catalogSourceName , testNamespace , catalogSourceRegistryPodSynced )
669
+ require .NoError (t , err )
670
+
671
+ subscriptionName := genName ("sub-nginx-" )
672
+ cleanupSubscription := createSubscriptionForCatalog (t , crc , testNamespace , subscriptionName , catalogSourceName , packageName , stableChannel , csvA .GetName (), v1alpha1 .ApprovalAutomatic )
673
+ defer cleanupSubscription ()
674
+
675
+ subscription , err := fetchSubscription (t , crc , testNamespace , subscriptionName , subscriptionHasInstallPlanChecker )
676
+ require .NoError (t , err )
677
+ require .NotNil (t , subscription )
678
+
679
+ // Wait for csvA to be installed
680
+ _ , err = awaitCSV (t , crc , testNamespace , csvA .GetName (), csvSucceededChecker )
681
+ require .NoError (t , err )
682
+
683
+ // Set up async watches that will fail the test if csvB doesn't get created in between csvA and csvC
684
+ var wg sync.WaitGroup
685
+ go func (t * testing.T ) {
686
+ wg .Add (1 )
687
+ defer wg .Done ()
688
+ _ , err := awaitCSV (t , crc , testNamespace , csvB .GetName (), csvAnyChecker )
689
+ require .NoError (t , err )
690
+ }(t )
691
+ // Update the catalog to include multiple updates
692
+ packages := []registry.PackageManifest {
693
+ {
694
+ PackageName : packageName ,
695
+ Channels : []registry.PackageChannel {
696
+ {Name : stableChannel , CurrentCSVName : csvC .GetName ()},
697
+ },
698
+ DefaultChannelName : stableChannel ,
699
+ },
700
+ }
701
+
702
+ updateInternalCatalog (t , c , crc , catalogSourceName , testNamespace , []apiextensions.CustomResourceDefinition {crd }, []v1alpha1.ClusterServiceVersion {csvA , csvB , csvC }, packages )
703
+
704
+ // wait for checks on intermediate csvs to succeed
705
+ wg .Wait ()
706
+
707
+ // Wait for csvC to be installed
708
+ _ , err = awaitCSV (t , crc , testNamespace , csvC .GetName (), csvSucceededChecker )
709
+ require .NoError (t , err )
710
+
711
+ // Should eventually GC the CSVs
712
+ err = waitForCSVToDelete (t , crc , csvA .Name )
713
+ require .NoError (t , err )
714
+ err = waitForCSVToDelete (t , crc , csvB .Name )
715
+ require .NoError (t , err )
716
+
717
+ // TODO: check installplans, subscription status, etc
718
+ }
719
+
720
+ func updateInternalCatalog (t * testing.T , c operatorclient.ClientInterface , crc versioned.Interface , catalogSourceName , namespace string , crds []apiextensions.CustomResourceDefinition , csvs []v1alpha1.ClusterServiceVersion , packages []registry.PackageManifest ) {
721
+ fetchedInitialCatalog , err := fetchCatalogSource (t , crc , catalogSourceName , namespace , catalogSourceRegistryPodSynced )
722
+ require .NoError (t , err )
723
+
724
+ // Get initial configmap
725
+ configMap , err := c .KubernetesInterface ().CoreV1 ().ConfigMaps (testNamespace ).Get (fetchedInitialCatalog .Spec .ConfigMap , metav1.GetOptions {})
726
+ require .NoError (t , err )
727
+
728
+ // Update package to point to new csv
729
+ manifestsRaw , err := yaml .Marshal (packages )
730
+ require .NoError (t , err )
731
+ configMap .Data [registry .ConfigMapPackageName ] = string (manifestsRaw )
732
+
733
+ // Update raw CRDs
734
+ var crdsRaw []byte
735
+ crdStrings := []string {}
736
+ for _ , crd := range crds {
737
+ crdStrings = append (crdStrings , serializeCRD (t , crd ))
738
+ }
739
+ crdsRaw , err = yaml .Marshal (crdStrings )
740
+ require .NoError (t , err )
741
+ configMap .Data [registry .ConfigMapCRDName ] = strings .Replace (string (crdsRaw ), "- |\n " , "- " , - 1 )
742
+
743
+ // Update raw CSVs
744
+ csvsRaw , err := yaml .Marshal (csvs )
745
+ require .NoError (t , err )
746
+ configMap .Data [registry .ConfigMapCSVName ] = string (csvsRaw )
747
+
748
+ // Update configmap
749
+ _ , err = c .KubernetesInterface ().CoreV1 ().ConfigMaps (testNamespace ).Update (configMap )
750
+ require .NoError (t , err )
751
+
752
+ // wait for catalog to update
753
+ _ , err = fetchCatalogSource (t , crc , catalogSourceName , testNamespace , func (catalog * v1alpha1.CatalogSource ) bool {
754
+ if catalog .Status .LastSync != fetchedInitialCatalog .Status .LastSync && catalog .Status .ConfigMapResource .ResourceVersion != fetchedInitialCatalog .Status .ConfigMapResource .ResourceVersion {
755
+ fmt .Println ("catalog updated" )
756
+ return true
757
+ }
758
+ fmt .Println ("waiting for catalog pod to be available" )
759
+ return false
760
+ })
761
+ require .NoError (t , err )
762
+ }
0 commit comments