Skip to content

Commit 0b3bfb0

Browse files
committed
test(subscription): add an e2e test for validating that subscriptions
step through multiple intermediate versions we have tests for this for CSVs, but not one for subscriptions.
1 parent 4d6bb6c commit 0b3bfb0

File tree

3 files changed

+153
-25
lines changed

3 files changed

+153
-25
lines changed

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ container:
9898

9999
clean-e2e:
100100
kubectl delete crds --all
101-
kubectl delete apiservices.apiregistration.k8s.io v1alpha1.packages.apps.redhat.com
102101
kubectl delete -f test/e2e/resources/0000_50_olm_00-namespace.yaml
103102

104103
clean:

test/e2e/catalog_e2e_test.go

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ package e2e
44

55
import (
66
"fmt"
7-
"strings"
87
"testing"
98

109
"github.com/coreos/go-semver/semver"
11-
"github.com/ghodss/yaml"
1210
"github.com/stretchr/testify/require"
1311
appsv1 "k8s.io/api/apps/v1"
1412
corev1 "k8s.io/api/core/v1"
@@ -164,28 +162,11 @@ func TestConfigMapUpdateTriggersRegistryPodRollout(t *testing.T) {
164162
require.NoError(t, err)
165163
require.Equal(t, 1, len(initialPods.Items))
166164

167-
// Update raw manifests
168-
manifestsRaw, err := yaml.Marshal(append(mainManifests, dependentManifests...))
169-
require.NoError(t, err)
170-
configMap.Data[registry.ConfigMapPackageName] = string(manifestsRaw)
171-
172-
// Update raw CRDs
173-
var crdsRaw []byte
174-
crdStrings := []string{}
175-
for _, crd := range []apiextensions.CustomResourceDefinition{dependentCRD} {
176-
crdStrings = append(crdStrings, serializeCRD(t, crd))
177-
}
178-
crdsRaw, err = yaml.Marshal(crdStrings)
179-
require.NoError(t, err)
180-
configMap.Data[registry.ConfigMapCRDName] = strings.Replace(string(crdsRaw), "- |\n ", "- ", -1)
181-
182-
// Update raw CSVs
183-
csvsRaw, err := yaml.Marshal([]v1alpha1.ClusterServiceVersion{mainCSV, dependentCSV})
184-
require.NoError(t, err)
185-
configMap.Data[registry.ConfigMapCSVName] = string(csvsRaw)
165+
// Update catalog configmap
166+
updateInternalCatalog(t, c, crc, mainCatalogName, testNamespace, []apiextensions.CustomResourceDefinition{dependentCRD}, []v1alpha1.ClusterServiceVersion{mainCSV, dependentCSV}, append(mainManifests, dependentManifests...))
186167

187-
// Update configmap
188-
updatedConfigMap, err := c.KubernetesInterface().CoreV1().ConfigMaps(testNamespace).Update(configMap)
168+
// Get updated configmap
169+
updatedConfigMap, err := c.KubernetesInterface().CoreV1().ConfigMaps(testNamespace).Get(fetchedInitialCatalog.Spec.ConfigMap, metav1.GetOptions{})
189170
require.NoError(t, err)
190171

191172
fetchedUpdatedCatalog, err := fetchCatalogSource(t, crc, mainCatalogName, testNamespace, func(catalog *v1alpha1.CatalogSource) bool {

test/e2e/subscription_e2e_test.go

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package e2e
33
import (
44
"encoding/json"
55
"fmt"
6+
"strings"
7+
"sync"
68
"testing"
79

810
"github.com/coreos/go-semver/semver"
@@ -196,7 +198,7 @@ var (
196198
Selector: &metav1.LabelSelector{
197199
MatchLabels: map[string]string{"app": "nginx"},
198200
},
199-
Replicas: &doubleInstance,
201+
Replicas: &singleInstance,
200202
Template: corev1.PodTemplateSpec{
201203
ObjectMeta: metav1.ObjectMeta{
202204
Labels: map[string]string{"app": "nginx"},
@@ -612,3 +614,149 @@ func TestSusbcriptionWithStartingCSV(t *testing.T) {
612614
require.NoError(t, err)
613615
}
614616

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

Comments
 (0)