Skip to content

Commit 048cdb4

Browse files
committed
Cleanup e2e tests and add case for invalid bundle image
1 parent 27ced41 commit 048cdb4

File tree

3 files changed

+125
-92
lines changed

3 files changed

+125
-92
lines changed

cmd/catalog/main.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,8 @@ var (
7070
profiling = flag.Bool(
7171
"profiling", false, "serve profiling data (on port 8080)")
7272

73-
installPlanTimeout = flag.Duration("install-plan-retry-timeout", 1*time.Minute, "time since first attempt at which plan execution errors are considered fatal")
74-
// TODO(haseeb): Change to a more realistic timeout for bundle unpack jobs
75-
bundleUnpackTimeout = flag.Duration("bundle-unpack-timeout", 60*time.Second, "The time duration after which the bundle unpack Job for an installplan will be aborted and the installplan will be Failed. 0 is considered as having no timeout.")
73+
installPlanTimeout = flag.Duration("install-plan-retry-timeout", 1*time.Minute, "time since first attempt at which plan execution errors are considered fatal")
74+
bundleUnpackTimeout = flag.Duration("bundle-unpack-timeout", catalog.DefaultBundleUnpackTimeout, "The time duration after which the bundle unpack Job for an installplan will be aborted and the installplan will be Failed. 0 is considered as having no timeout.")
7675
)
7776

7877
func init() {

pkg/controller/operators/catalog/operator.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ const (
7777
maxInstallPlanCount = 5
7878
maxDeletesPerSweep = 5
7979
RegistryFieldManager = "olm.registry"
80+
// TODO(haseeb): Change to a more realistic timeout for bundle unpack jobs
81+
DefaultBundleUnpackTimeout = 2 * time.Minute
8082
)
8183

8284
// Operator represents a Kubernetes operator that executes InstallPlans by

test/e2e/installplan_e2e_test.go

Lines changed: 121 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,108 +2999,140 @@ var _ = Describe("Install Plan", func() {
29992999
ctx.Ctx().Logf(fmt.Sprintf("Install plan %s fetched with conditions %+v", fetchedInstallPlan.GetName(), fetchedInstallPlan.Status.Conditions))
30003000
})
30013001

3002-
It("should fail an InstallPlan when an InstallPlan has a bundle unpack job timeout", func() {
3003-
ns := &corev1.Namespace{}
3004-
ns.SetName(genName("ns-"))
3002+
When("waiting on the bundle unpacking job", func() {
3003+
var (
3004+
ns *corev1.Namespace
3005+
catsrcName string
3006+
crc versioned.Interface
3007+
ip *operatorsv1alpha1.InstallPlan
3008+
)
3009+
BeforeEach(func() {
3010+
crc = newCRClient()
3011+
ns = &corev1.Namespace{}
3012+
ns.SetName(genName("ns-"))
3013+
Expect(ctx.Ctx().Client().Create(context.Background(), ns)).To(Succeed())
30053014

3006-
c := newKubeClient()
3007-
crc := newCRClient()
3008-
now := metav1.Now()
3015+
// Create the single (kiali) bundle catalog source
3016+
catsrc := &operatorsv1alpha1.CatalogSource{
3017+
ObjectMeta: metav1.ObjectMeta{
3018+
Name: genName("kiali-"),
3019+
Namespace: ns.GetName(),
3020+
Labels: map[string]string{"olm.catalogSource": "kaili-catalog"},
3021+
},
3022+
Spec: operatorsv1alpha1.CatalogSourceSpec{
3023+
Image: "quay.io/olmtest/single-bundle-index:1.0.0",
3024+
SourceType: operatorsv1alpha1.SourceTypeGrpc,
3025+
},
3026+
}
3027+
Expect(ctx.Ctx().Client().Create(context.Background(), catsrc)).To(Succeed())
30093028

3010-
// Create a namespace
3011-
ns, err := c.KubernetesInterface().CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
3012-
Expect(err).NotTo(HaveOccurred())
3013-
deleteOpts := &metav1.DeleteOptions{}
3014-
defer func() {
3015-
err = c.KubernetesInterface().CoreV1().Namespaces().Delete(context.TODO(), ns.GetName(), *deleteOpts)
3029+
// Wait for the CatalogSource to be ready
3030+
catsrc, err := fetchCatalogSourceOnStatus(crc, catsrc.GetName(), catsrc.GetNamespace(), catalogSourceRegistryPodSynced)
30163031
Expect(err).ToNot(HaveOccurred())
3017-
}()
3018-
3019-
// Create the single (kiali) bundle catalog source
3020-
catsrc := &operatorsv1alpha1.CatalogSource{
3021-
ObjectMeta: metav1.ObjectMeta{
3022-
Name: genName("kiali-"),
3023-
Namespace: ns.GetName(),
3024-
Labels: map[string]string{"olm.catalogSource": "kaili-catalog"},
3025-
},
3026-
Spec: operatorsv1alpha1.CatalogSourceSpec{
3027-
Image: "quay.io/olmtest/single-bundle-index:1.0.0",
3028-
SourceType: operatorsv1alpha1.SourceTypeGrpc,
3029-
},
3030-
}
3031-
catsrc, err = crc.OperatorsV1alpha1().CatalogSources(catsrc.GetNamespace()).Create(context.TODO(), catsrc, metav1.CreateOptions{})
3032-
Expect(err).ToNot(HaveOccurred())
30333032

3034-
// Wait for the CatalogSource to be ready
3035-
catsrc, err = fetchCatalogSourceOnStatus(crc, catsrc.GetName(), catsrc.GetNamespace(), catalogSourceRegistryPodSynced)
3036-
Expect(err).ToNot(HaveOccurred())
3033+
catsrcName = catsrc.GetName()
30373034

3038-
// Create the OperatorGroup
3039-
og := &operatorsv1.OperatorGroup{
3040-
ObjectMeta: metav1.ObjectMeta{
3041-
Name: "og",
3042-
},
3043-
Spec: operatorsv1.OperatorGroupSpec{
3044-
TargetNamespaces: []string{ns.GetName()},
3045-
},
3046-
}
3047-
_, err = crc.OperatorsV1().OperatorGroups(ns.GetName()).Create(context.TODO(), og, metav1.CreateOptions{})
3048-
Expect(err).ToNot(HaveOccurred())
3035+
// Create the OperatorGroup
3036+
og := &operatorsv1.OperatorGroup{
3037+
ObjectMeta: metav1.ObjectMeta{
3038+
Name: "og",
3039+
Namespace: ns.GetName(),
3040+
},
3041+
Spec: operatorsv1.OperatorGroupSpec{
3042+
TargetNamespaces: []string{ns.GetName()},
3043+
},
3044+
}
3045+
Expect(ctx.Ctx().Client().Create(context.Background(), og)).To(Succeed())
30493046

3050-
// Create an InstallPlan in the Planning phase with status.bundleLookups specified for a non-existing bundle
3051-
ip := &operatorsv1alpha1.InstallPlan{
3052-
ObjectMeta: metav1.ObjectMeta{
3053-
Name: "ip",
3054-
Namespace: ns.GetName(),
3055-
},
3056-
Spec: operatorsv1alpha1.InstallPlanSpec{
3057-
ClusterServiceVersionNames: []string{"foobar"},
3058-
Approval: v1alpha1.ApprovalAutomatic,
3059-
Approved: true,
3060-
Generation: 1,
3061-
},
3062-
Status: operatorsv1alpha1.InstallPlanStatus{
3063-
Phase: operatorsv1alpha1.InstallPlanPhasePlanning,
3064-
CatalogSources: []string{},
3065-
BundleLookups: []operatorsv1alpha1.BundleLookup{
3066-
{
3067-
Path: "quay.io/foo/bar:v0.0.1",
3068-
Identifier: "foobar.v0.0.1",
3069-
CatalogSourceRef: &corev1.ObjectReference{
3070-
Namespace: ns.GetName(),
3071-
Name: catsrc.GetName(),
3072-
},
3073-
Conditions: []operatorsv1alpha1.BundleLookupCondition{
3074-
{
3075-
Type: operatorsv1alpha1.BundleLookupPending,
3076-
Status: corev1.ConditionTrue,
3077-
Reason: "JobIncomplete",
3078-
Message: "unpack job not completed",
3079-
LastTransitionTime: &now,
3047+
now := metav1.Now()
3048+
ip = &operatorsv1alpha1.InstallPlan{
3049+
ObjectMeta: metav1.ObjectMeta{
3050+
Name: "ip",
3051+
Namespace: ns.GetName(),
3052+
},
3053+
Spec: operatorsv1alpha1.InstallPlanSpec{
3054+
ClusterServiceVersionNames: []string{"foobar"},
3055+
Approval: v1alpha1.ApprovalAutomatic,
3056+
Approved: true,
3057+
},
3058+
Status: operatorsv1alpha1.InstallPlanStatus{
3059+
Phase: operatorsv1alpha1.InstallPlanPhasePlanning,
3060+
CatalogSources: []string{},
3061+
BundleLookups: []operatorsv1alpha1.BundleLookup{
3062+
{
3063+
Identifier: "foobar.v0.0.1",
3064+
CatalogSourceRef: &corev1.ObjectReference{
3065+
Namespace: ns.GetName(),
3066+
Name: catsrcName,
3067+
},
3068+
Conditions: []operatorsv1alpha1.BundleLookupCondition{
3069+
{
3070+
Type: operatorsv1alpha1.BundleLookupPending,
3071+
Status: corev1.ConditionTrue,
3072+
Reason: "JobIncomplete",
3073+
Message: "unpack job not completed",
3074+
LastTransitionTime: &now,
3075+
},
30803076
},
30813077
},
30823078
},
30833079
},
3084-
},
3085-
}
3080+
}
3081+
})
30863082

3087-
outIP, err := crc.OperatorsV1alpha1().InstallPlans(ns.GetName()).Create(context.TODO(), ip, metav1.CreateOptions{})
3088-
Expect(err).NotTo(HaveOccurred())
3089-
Expect(outIP).NotTo(BeNil())
3083+
AfterEach(func() {
3084+
Expect(ctx.Ctx().Client().Delete(context.Background(), ns)).To(Succeed())
3085+
})
30903086

3091-
// The status gets ignored on create so we need to update it else the InstallPlan sync ignores
3092-
// InstallPlans without any steps or bundle lookups
3093-
outIP.Status = ip.Status
3094-
_, err = crc.OperatorsV1alpha1().InstallPlans(ns.GetName()).UpdateStatus(context.TODO(), outIP, metav1.UpdateOptions{})
3095-
Expect(err).NotTo(HaveOccurred())
3087+
It("should timeout and fail the InstallPlan for a non-existent bundle image", func() {
3088+
// Create an InstallPlan status.bundleLookups.Path specified for a non-existent bundle image
3089+
ip.Status.BundleLookups[0].Path = "quay.io/foo/bar:v0.0.1"
30963090

3097-
// The InstallPlan should be Failed due to the bundle unpack job timeout
3098-
// TODO(haseeb): Use Eventually() to set a Duration just over the default bundle-unpack-timeout duration. Else this could poll for a long time.
3099-
fetchedInstallPlan, err := fetchInstallPlanWithNamespace(GinkgoT(), crc, ip.Name, ns.GetName(), buildInstallPlanPhaseCheckFunc(operatorsv1alpha1.InstallPlanPhaseFailed))
3100-
Expect(err).NotTo(HaveOccurred())
3101-
Expect(fetchedInstallPlan).NotTo(BeNil())
3102-
ctx.Ctx().Logf(fmt.Sprintf("Install plan %s fetched with phase %s", fetchedInstallPlan.GetName(), fetchedInstallPlan.Status.Phase))
3103-
ctx.Ctx().Logf(fmt.Sprintf("Install plan %s fetched with conditions %+v", fetchedInstallPlan.GetName(), fetchedInstallPlan.Status.Conditions))
3091+
outIP := ip.DeepCopy()
3092+
3093+
Expect(ctx.Ctx().Client().Create(context.Background(), outIP)).To(Succeed())
3094+
3095+
// The status gets ignored on create so we need to update it else the InstallPlan sync ignores
3096+
// InstallPlans without any steps or bundle lookups
3097+
outIP.Status = ip.Status
3098+
Expect(ctx.Ctx().Client().Status().Update(context.Background(), outIP)).To(Succeed())
3099+
3100+
// The InstallPlan should be Failed due to the bundle unpack job timeout
3101+
// We wait for some time over the bundle unpack Job's timeout (i.e ActiveDeadlineSeconds) so that the Job can fail
3102+
waitFor := catalog.DefaultBundleUnpackTimeout + 30*time.Second
3103+
Eventually(
3104+
func() (*operatorsv1alpha1.InstallPlan, error) {
3105+
err := ctx.Ctx().Client().Get(context.Background(), client.ObjectKeyFromObject(outIP), outIP)
3106+
return outIP, err
3107+
},
3108+
waitFor,
3109+
).Should(HavePhase(operatorsv1alpha1.InstallPlanPhaseFailed))
3110+
})
3111+
3112+
It("should timeout and fail the InstallPlan for an invalid bundle image", func() {
3113+
// Create an InstallPlan status.bundleLookups.Path specified for an invalid bundle image
3114+
ip.Status.BundleLookups[0].Path = "alpine:3.13"
3115+
3116+
outIP := ip.DeepCopy()
3117+
3118+
Expect(ctx.Ctx().Client().Create(context.Background(), outIP)).To(Succeed())
3119+
3120+
// The status gets ignored on create so we need to update it else the InstallPlan sync ignores
3121+
// InstallPlans without any steps or bundle lookups
3122+
outIP.Status = ip.Status
3123+
Expect(ctx.Ctx().Client().Status().Update(context.Background(), outIP)).To(Succeed())
3124+
3125+
// The InstallPlan should be Failed due to the bundle unpack job timeout
3126+
// We wait for some time over the bundle unpack Job's timeout (i.e ActiveDeadlineSeconds) so that the Job can fail
3127+
waitFor := catalog.DefaultBundleUnpackTimeout + 30*time.Second
3128+
Eventually(
3129+
func() (*operatorsv1alpha1.InstallPlan, error) {
3130+
err := ctx.Ctx().Client().Get(context.Background(), client.ObjectKeyFromObject(outIP), outIP)
3131+
return outIP, err
3132+
},
3133+
waitFor,
3134+
).Should(HavePhase(operatorsv1alpha1.InstallPlanPhaseFailed))
3135+
})
31043136

31053137
})
31063138

0 commit comments

Comments
 (0)