@@ -1244,9 +1244,9 @@ var _ = Describe("Subscription", func() {
12441244 require .Len (GinkgoT (), installPlan .Status .CatalogSources , 1 )
12451245 })
12461246
1247- // CatSrc :
1247+ // CatSrc1 :
12481248 //
1249- // Package A (apackage)
1249+ // Package 1 (apackage)
12501250 // Default Channel: Stable
12511251 // Channel Stable:
12521252 // Operator A (Requires: CRD 1, CRD 2 )
@@ -1256,12 +1256,19 @@ var _ = Describe("Subscription", func() {
12561256 // Default Channel: Stable
12571257 // Channel Stable:
12581258 // Operator B (Provides: CRD)
1259- // CatSrc2:
1259+ // Channel Alpha:
1260+ // Operator D (Provides: CRD)
12601261 //
1261- // Package B (bpackage)
1262+ // CatSrc2:
1263+ // Package 2 (bpackage)
12621264 // Default Channel: Stable
12631265 // Channel Stable:
12641266 // Operator C (Provides: CRD 2)
1267+ // Package 3 (cpackage)
1268+ // Default Channel: Stable
1269+ // Channel Stable:
1270+ // Operator E (Provides: CRD 2)
1271+ //
12651272 // Then create a subscription:
12661273 //
12671274 // CatalogSource: CatSrc
@@ -1270,10 +1277,11 @@ var _ = Describe("Subscription", func() {
12701277 // StartingCSV: CSV A
12711278 //
12721279 // Check installed:
1280+ // CSV A, CSV B, CSV E
12731281 //
1274- // CSV A, CSV B, CSV C
1275- //
1276- // CSV A required B and C but didn't get them from Package A
1282+ // CSV ABC: not chosen as it is the same package with CSV A
1283+ // CSV D: not chosen as it is in non-default channel
1284+ // CSV C: not chosen as it is the same package with CSV B (which is chosen)
12771285 It ("creation with dependencies required and provided in different versions of an operator in the same package" , func () {
12781286
12791287 kubeClient := newKubeClient ()
@@ -1323,6 +1331,7 @@ var _ = Describe("Subscription", func() {
13231331 // Create CSV
13241332 packageName1 := genName ("apackage" )
13251333 packageName2 := genName ("bpackage" )
1334+ packageName3 := genName ("cpackage" )
13261335
13271336 namedStrategy := newNginxInstallStrategy ((genName ("dep" )), permissions , nil )
13281337 depNamedStrategy := newNginxInstallStrategy ((genName ("dep" )), permissions , nil )
@@ -1338,6 +1347,8 @@ var _ = Describe("Subscription", func() {
13381347 csvC := newCSV ("nginx-c-dep" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd2 }, nil , depNamedStrategy2 )
13391348 // csvD provides CRD1 in the same catalogsource with csvA (apackage)
13401349 csvD := newCSV ("nginx-d-dep" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd }, nil , depNamedStrategy )
1350+ // csvE provides CRD2 in the different catalogsource with csvC (bpackage)
1351+ csvE := newCSV ("nginx-e-dep" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd2 }, nil , depNamedStrategy2 )
13411352
13421353 // Create PackageManifests 1
13431354 // Contain csvA, ABC and B
@@ -1370,6 +1381,13 @@ var _ = Describe("Subscription", func() {
13701381 },
13711382 DefaultChannelName : stableChannel ,
13721383 },
1384+ {
1385+ PackageName : packageName3 ,
1386+ Channels : []registry.PackageChannel {
1387+ {Name : stableChannel , CurrentCSVName : csvE .GetName ()},
1388+ },
1389+ DefaultChannelName : stableChannel ,
1390+ },
13731391 }
13741392
13751393 catalogSourceName := genName ("catsrc" )
@@ -1390,7 +1408,7 @@ var _ = Describe("Subscription", func() {
13901408 }
13911409
13921410 catalogSourceName2 := genName ("catsrc" )
1393- catsrc2 , cleanup2 := createInternalCatalogSource (kubeClient , crClient , catalogSourceName2 , testNamespace , manifests2 , []apiextensions.CustomResourceDefinition {crd2 }, []v1alpha1.ClusterServiceVersion {csvC })
1411+ catsrc2 , cleanup2 := createInternalCatalogSource (kubeClient , crClient , catalogSourceName2 , testNamespace , manifests2 , []apiextensions.CustomResourceDefinition {crd2 }, []v1alpha1.ClusterServiceVersion {csvC , csvE })
13941412 defer cleanup2 ()
13951413
13961414 // Ensure that the catalog source is resolved before we create a subscription.
@@ -1412,7 +1430,7 @@ var _ = Describe("Subscription", func() {
14121430 // Fetch CSVs A, B and C
14131431 _ , err = fetchCSV (crClient , csvB .Name , testNamespace , csvSucceededChecker )
14141432 require .NoError (GinkgoT (), err )
1415- _ , err = fetchCSV (crClient , csvC .Name , testNamespace , csvSucceededChecker )
1433+ _ , err = fetchCSV (crClient , csvE .Name , testNamespace , csvSucceededChecker )
14161434 require .NoError (GinkgoT (), err )
14171435 _ , err = fetchCSV (crClient , csvA .Name , testNamespace , csvSucceededChecker )
14181436 require .NoError (GinkgoT (), err )
@@ -1423,6 +1441,187 @@ var _ = Describe("Subscription", func() {
14231441 _ , err = crClient .OperatorsV1alpha1 ().ClusterServiceVersions (testNamespace ).Get (context .Background (), csvD .Name , metav1.GetOptions {})
14241442 require .Error (GinkgoT (), err )
14251443 })
1444+
1445+ // csvA owns CRD1 & csvB owns CRD2 and requires CRD1
1446+ // Create subscription for csvB lead to installation of csvB and csvA
1447+ // Update catsrc to upgrade csvA to csvNewA which now requires CRD1
1448+ // csvNewA can't be installed due to no other operators provide CRD1 for it
1449+ // (Note: OLM can't pick csvA as dependency for csvNewA as it is from the same
1450+ // same package)
1451+ // Update catsrc again to upgrade csvB to csvNewB which now owns both CRD1 and
1452+ // CRD2.
1453+ // Now csvNewA and csvNewB are installed successfully as csvNewB provides CRD1
1454+ // that csvNewA requires
1455+ It ("creation in case of transferring providedAPIs" , func () {
1456+
1457+ kubeClient := newKubeClient ()
1458+ crClient := newCRClient ()
1459+
1460+ permissions := deploymentPermissions ()
1461+
1462+ crdPlural := genName ("ins" )
1463+ crdName := crdPlural + ".cluster.com"
1464+ crdPlural2 := genName ("ins" )
1465+ crdName2 := crdPlural2 + ".cluster.com"
1466+
1467+ crd := apiextensions.CustomResourceDefinition {
1468+ ObjectMeta : metav1.ObjectMeta {
1469+ Name : crdName ,
1470+ },
1471+ Spec : apiextensions.CustomResourceDefinitionSpec {
1472+ Group : "cluster.com" ,
1473+ Version : "v1alpha1" ,
1474+ Names : apiextensions.CustomResourceDefinitionNames {
1475+ Plural : crdPlural ,
1476+ Singular : crdPlural ,
1477+ Kind : crdPlural ,
1478+ ListKind : "list" + crdPlural ,
1479+ },
1480+ Scope : "Namespaced" ,
1481+ },
1482+ }
1483+
1484+ crd2 := apiextensions.CustomResourceDefinition {
1485+ ObjectMeta : metav1.ObjectMeta {
1486+ Name : crdName2 ,
1487+ },
1488+ Spec : apiextensions.CustomResourceDefinitionSpec {
1489+ Group : "cluster.com" ,
1490+ Version : "v1alpha1" ,
1491+ Names : apiextensions.CustomResourceDefinitionNames {
1492+ Plural : crdPlural2 ,
1493+ Singular : crdPlural2 ,
1494+ Kind : crdPlural2 ,
1495+ ListKind : "list" + crdPlural2 ,
1496+ },
1497+ Scope : "Namespaced" ,
1498+ },
1499+ }
1500+
1501+ // Create CSV
1502+ packageName1 := genName ("apackage" )
1503+ packageName2 := genName ("bpackage" )
1504+
1505+ namedStrategy := newNginxInstallStrategy ((genName ("dep" )), permissions , nil )
1506+ namedStrategy2 := newNginxInstallStrategy ((genName ("dep" )), permissions , nil )
1507+ // csvA provides CRD
1508+ csvA := newCSV ("nginx-a" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd }, nil , namedStrategy )
1509+ // csvB provides CRD2 and requires CRD
1510+ csvB := newCSV ("nginx-b" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd2 }, []apiextensions.CustomResourceDefinition {crd }, namedStrategy2 )
1511+ // New csvA requires CRD (transfer CRD ownership to the new csvB)
1512+ csvNewA := newCSV ("nginx-new-a" , testNamespace , "nginx-a" , semver .MustParse ("0.2.0" ), nil , []apiextensions.CustomResourceDefinition {crd }, namedStrategy )
1513+ // New csvB provides CRD and CRD2
1514+ csvNewB := newCSV ("nginx-new-b" , testNamespace , "nginx-b" , semver .MustParse ("0.2.0" ), []apiextensions.CustomResourceDefinition {crd , crd2 }, nil , namedStrategy2 )
1515+
1516+ // Create PackageManifests 1
1517+ // Contain csvA, ABC and B
1518+ manifests := []registry.PackageManifest {
1519+ {
1520+ PackageName : packageName1 ,
1521+ Channels : []registry.PackageChannel {
1522+ {Name : stableChannel , CurrentCSVName : csvA .GetName ()},
1523+ },
1524+ DefaultChannelName : stableChannel ,
1525+ },
1526+ {
1527+ PackageName : packageName2 ,
1528+ Channels : []registry.PackageChannel {
1529+ {Name : stableChannel , CurrentCSVName : csvB .GetName ()},
1530+ },
1531+ DefaultChannelName : stableChannel ,
1532+ },
1533+ }
1534+
1535+ catalogSourceName := genName ("catsrc" )
1536+ catsrc , cleanup := createInternalCatalogSource (kubeClient , crClient , catalogSourceName , testNamespace , manifests , []apiextensions.CustomResourceDefinition {crd , crd2 }, []v1alpha1.ClusterServiceVersion {csvA , csvB })
1537+ defer cleanup ()
1538+
1539+ // Ensure that the catalog source is resolved before we create a subscription.
1540+ _ , err := fetchCatalogSourceOnStatus (crClient , catsrc .GetName (), testNamespace , catalogSourceRegistryPodSynced )
1541+ require .NoError (GinkgoT (), err )
1542+
1543+ subscriptionSpec := & v1alpha1.SubscriptionSpec {
1544+ CatalogSource : catsrc .GetName (),
1545+ CatalogSourceNamespace : catsrc .GetNamespace (),
1546+ Package : packageName2 ,
1547+ Channel : stableChannel ,
1548+ StartingCSV : csvB .GetName (),
1549+ InstallPlanApproval : v1alpha1 .ApprovalAutomatic ,
1550+ }
1551+
1552+ // Create a subscription that has a dependency
1553+ subscriptionName := genName ("sub-" )
1554+ cleanupSubscription := createSubscriptionForCatalogWithSpec (GinkgoT (), crClient , testNamespace , subscriptionName , subscriptionSpec )
1555+ defer cleanupSubscription ()
1556+
1557+ subscription , err := fetchSubscription (crClient , testNamespace , subscriptionName , subscriptionStateAtLatestChecker )
1558+ require .NoError (GinkgoT (), err )
1559+ require .NotNil (GinkgoT (), subscription )
1560+
1561+ // Check that a single catalog source was used to resolve the InstallPlan
1562+ _ , err = fetchInstallPlan (GinkgoT (), crClient , subscription .Status .InstallPlanRef .Name , buildInstallPlanPhaseCheckFunc (v1alpha1 .InstallPlanPhaseComplete ))
1563+ require .NoError (GinkgoT (), err )
1564+ // Fetch CSVs A and B
1565+ _ , err = fetchCSV (crClient , csvA .Name , testNamespace , csvSucceededChecker )
1566+ require .NoError (GinkgoT (), err )
1567+ _ , err = fetchCSV (crClient , csvB .Name , testNamespace , csvSucceededChecker )
1568+ require .NoError (GinkgoT (), err )
1569+
1570+ // Update PackageManifest
1571+ manifests = []registry.PackageManifest {
1572+ {
1573+ PackageName : packageName1 ,
1574+ Channels : []registry.PackageChannel {
1575+ {Name : stableChannel , CurrentCSVName : csvNewA .GetName ()},
1576+ },
1577+ DefaultChannelName : stableChannel ,
1578+ },
1579+ {
1580+ PackageName : packageName2 ,
1581+ Channels : []registry.PackageChannel {
1582+ {Name : stableChannel , CurrentCSVName : csvB .GetName ()},
1583+ },
1584+ DefaultChannelName : stableChannel ,
1585+ },
1586+ }
1587+ updateInternalCatalog (GinkgoT (), kubeClient , crClient , catalogSourceName , testNamespace , []apiextensions.CustomResourceDefinition {crd , crd2 }, []v1alpha1.ClusterServiceVersion {csvNewA , csvA , csvB }, manifests )
1588+ csvAsub := strings .Join ([]string {packageName1 , stableChannel , catalogSourceName , testNamespace }, "-" )
1589+ _ , err = fetchSubscription (crClient , testNamespace , csvAsub , subscriptionStateUpgradeAvailableChecker )
1590+ require .NoError (GinkgoT (), err )
1591+ // Ensure csvNewA is not installed
1592+ _ , err = crClient .OperatorsV1alpha1 ().ClusterServiceVersions (testNamespace ).Get (context .Background (), csvNewA .Name , metav1.GetOptions {})
1593+ require .Error (GinkgoT (), err )
1594+ // Ensure csvA still exists
1595+ _ , err = fetchCSV (crClient , csvA .Name , testNamespace , csvSucceededChecker )
1596+ require .NoError (GinkgoT (), err )
1597+
1598+ // Update packagemanifest again
1599+ manifests = []registry.PackageManifest {
1600+ {
1601+ PackageName : packageName1 ,
1602+ Channels : []registry.PackageChannel {
1603+ {Name : stableChannel , CurrentCSVName : csvNewA .GetName ()},
1604+ },
1605+ DefaultChannelName : stableChannel ,
1606+ },
1607+ {
1608+ PackageName : packageName2 ,
1609+ Channels : []registry.PackageChannel {
1610+ {Name : stableChannel , CurrentCSVName : csvNewB .GetName ()},
1611+ },
1612+ DefaultChannelName : stableChannel ,
1613+ },
1614+ }
1615+ updateInternalCatalog (GinkgoT (), kubeClient , crClient , catalogSourceName , testNamespace , []apiextensions.CustomResourceDefinition {crd , crd2 }, []v1alpha1.ClusterServiceVersion {csvA , csvB , csvNewA , csvNewB }, manifests )
1616+ _ , err = fetchSubscription (crClient , testNamespace , subscriptionName , subscriptionStateUpgradePendingChecker )
1617+ require .NoError (GinkgoT (), err )
1618+ // Ensure csvNewA is installed
1619+ _ , err = fetchCSV (crClient , csvNewA .Name , testNamespace , csvSucceededChecker )
1620+ require .NoError (GinkgoT (), err )
1621+ // Ensure csvNewB is installed
1622+ _ , err = fetchCSV (crClient , csvNewB .Name , testNamespace , csvSucceededChecker )
1623+ require .NoError (GinkgoT (), err )
1624+ })
14261625})
14271626
14281627const (
0 commit comments