Skip to content

Commit c5ef8b4

Browse files
committed
e2e: Add support for updating MagicCatalogs
Signed-off-by: timflannagan <[email protected]>
1 parent 1bdf969 commit c5ef8b4

File tree

6 files changed

+209
-33
lines changed

6 files changed

+209
-33
lines changed

test/e2e/catalog_e2e_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ var _ = Describe("Starting CatalogSource e2e tests", func() {
12171217
if err != nil {
12181218
return err
12191219
}
1220-
if catsrc.Status.Reason != "" || (catsrc.Spec.UpdateStrategy.Interval != &metav1.Duration{expectedTime}) {
1220+
if catsrc.Status.Reason != "" || (catsrc.Spec.UpdateStrategy.Interval != &metav1.Duration{Duration: expectedTime}) {
12211221
return err
12221222
}
12231223
return nil

test/e2e/magic_catalog.go

+72-25
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
k8serror "k8s.io/apimachinery/pkg/api/errors"
1010
"k8s.io/apimachinery/pkg/api/resource"
1111
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
utilerrors "k8s.io/apimachinery/pkg/util/errors"
1213
"k8s.io/apimachinery/pkg/util/intstr"
1314
k8scontrollerclient "sigs.k8s.io/controller-runtime/pkg/client"
1415
)
@@ -22,6 +23,7 @@ const (
2223

2324
type MagicCatalog interface {
2425
DeployCatalog(ctx context.Context) error
26+
UpdateCatalog(ctx context.Context, provider FileBasedCatalogProvider) error
2527
UndeployCatalog(ctx context.Context) []error
2628
}
2729

@@ -50,74 +52,119 @@ func NewMagicCatalog(kubeClient k8scontrollerclient.Client, namespace string, ca
5052
}
5153

5254
func (c *magicCatalog) DeployCatalog(ctx context.Context) error {
53-
5455
catalogSource := c.makeCatalogSource()
5556
resourcesInOrderOfDeployment := []k8scontrollerclient.Object{
5657
c.makeConfigMap(),
5758
c.makeCatalogSourcePod(),
5859
c.makeCatalogService(),
5960
catalogSource,
6061
}
62+
if err := c.deployCatalog(ctx, resourcesInOrderOfDeployment); err != nil {
63+
return err
64+
}
65+
if err := catalogSourceIsReady(ctx, c.kubeClient, catalogSource); err != nil {
66+
return c.cleanUpAfter(ctx, err)
67+
}
68+
69+
return nil
70+
}
71+
72+
func catalogSourceIsReady(ctx context.Context, c k8scontrollerclient.Client, cs *operatorsv1alpha1.CatalogSource) error {
73+
// wait for catalog source to become ready
74+
return waitFor(func() (bool, error) {
75+
err := c.Get(ctx, k8scontrollerclient.ObjectKey{
76+
Name: cs.GetName(),
77+
Namespace: cs.GetNamespace(),
78+
}, cs)
79+
if err != nil || cs.Status.GRPCConnectionState == nil {
80+
return false, err
81+
}
82+
state := cs.Status.GRPCConnectionState.LastObservedState
83+
if state != catalogReadyState {
84+
return false, nil
85+
}
86+
return true, nil
87+
})
88+
}
6189

62-
for _, res := range resourcesInOrderOfDeployment {
90+
func (c *magicCatalog) deployCatalog(ctx context.Context, resources []k8scontrollerclient.Object) error {
91+
for _, res := range resources {
6392
err := c.kubeClient.Create(ctx, res)
6493
if err != nil {
6594
return c.cleanUpAfter(ctx, err)
6695
}
6796
}
97+
return nil
98+
}
6899

69-
// wait for catalog source to become ready
100+
func (c *magicCatalog) UpdateCatalog(ctx context.Context, provider FileBasedCatalogProvider) error {
101+
resourcesInOrderOfDeletion := []k8scontrollerclient.Object{
102+
c.makeCatalogSourcePod(),
103+
c.makeConfigMap(),
104+
}
105+
errors := c.undeployCatalog(ctx, resourcesInOrderOfDeletion)
106+
if len(errors) != 0 {
107+
return utilerrors.NewAggregate(errors)
108+
}
109+
110+
// TODO(tflannag): Create a pod watcher struct and setup an underlying watch
111+
// and block until ctx.Done()?
70112
err := waitFor(func() (bool, error) {
113+
pod := &corev1.Pod{}
71114
err := c.kubeClient.Get(ctx, k8scontrollerclient.ObjectKey{
72-
Name: catalogSource.GetName(),
73-
Namespace: catalogSource.GetNamespace(),
74-
}, catalogSource)
75-
76-
if err != nil || catalogSource.Status.GRPCConnectionState == nil {
77-
return false, err
78-
}
79-
80-
state := catalogSource.Status.GRPCConnectionState.LastObservedState
81-
82-
if state != catalogReadyState {
83-
return false, nil
84-
} else {
115+
Name: c.podName,
116+
Namespace: c.namespace,
117+
}, pod)
118+
if k8serror.IsNotFound(err) {
85119
return true, nil
86120
}
121+
return false, err
87122
})
88-
89123
if err != nil {
124+
return fmt.Errorf("failed to successfully update the catalog deployment: %v", err)
125+
}
126+
127+
c.fileBasedCatalog = provider
128+
resourcesInOrderOfCreation := []k8scontrollerclient.Object{
129+
c.makeConfigMap(),
130+
c.makeCatalogSourcePod(),
131+
}
132+
if err := c.deployCatalog(ctx, resourcesInOrderOfCreation); err != nil {
133+
return err
134+
}
135+
if err := catalogSourceIsReady(ctx, c.kubeClient, c.makeCatalogSource()); err != nil {
90136
return c.cleanUpAfter(ctx, err)
91137
}
92138

93139
return nil
94140
}
95141

96142
func (c *magicCatalog) UndeployCatalog(ctx context.Context) []error {
97-
var errs []error = nil
98-
99143
resourcesInOrderOfDeletion := []k8scontrollerclient.Object{
100144
c.makeCatalogSource(),
101145
c.makeCatalogService(),
102146
c.makeCatalogSourcePod(),
103147
c.makeConfigMap(),
104148
}
149+
return c.undeployCatalog(ctx, resourcesInOrderOfDeletion)
150+
}
105151

152+
func (c *magicCatalog) undeployCatalog(ctx context.Context, resources []k8scontrollerclient.Object) []error {
153+
var errors []error
106154
// try to delete all resourcesInOrderOfDeletion even if errors are
107155
// encountered through deletion.
108-
for _, res := range resourcesInOrderOfDeletion {
156+
for _, res := range resources {
109157
err := c.kubeClient.Delete(ctx, res)
110158

111159
// ignore not found errors
112160
if err != nil && !k8serror.IsNotFound(err) {
113-
if errs == nil {
114-
errs = make([]error, 0)
161+
if errors == nil {
162+
errors = make([]error, 0)
115163
}
116-
errs = append(errs, err)
164+
errors = append(errors, err)
117165
}
118166
}
119-
120-
return errs
167+
return errors
121168
}
122169

123170
func (c *magicCatalog) cleanUpAfter(ctx context.Context, err error) error {

test/e2e/magic_catalog_test.go

+85-7
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,26 @@ package e2e
22

33
import (
44
"context"
5+
"fmt"
56
"path/filepath"
67

78
. "github.com/onsi/ginkgo"
89
. "github.com/onsi/gomega"
910
"github.com/operator-framework/operator-lifecycle-manager/test/e2e/ctx"
1011
corev1 "k8s.io/api/core/v1"
12+
"k8s.io/apimachinery/pkg/types"
13+
"sigs.k8s.io/controller-runtime/pkg/client"
1114
)
1215

1316
var _ = Describe("MagicCatalog", func() {
1417
var (
1518
generatedNamespace corev1.Namespace
19+
c client.Client
1620
)
17-
1821
BeforeEach(func() {
22+
c = ctx.Ctx().Client()
1923
generatedNamespace = SetupGeneratedTestNamespace(genName("magic-catalog-e2e-"))
2024
})
21-
2225
AfterEach(func() {
2326
TeardownNamespace(generatedNamespace.GetName())
2427
})
@@ -27,15 +30,90 @@ var _ = Describe("MagicCatalog", func() {
2730
// create dependencies
2831
const catalogName = "test"
2932
namespace := generatedNamespace.GetName()
30-
kubeClient := ctx.Ctx().Client()
31-
provider, err := NewFileBasedFiledBasedCatalogProvider(filepath.Join(testdataDir, "fbc_catalog.json"))
33+
provider, err := NewFileBasedFiledBasedCatalogProvider(filepath.Join(testdataDir, "magiccatalog/fbc_catalog.json"))
3234
Expect(err).To(BeNil())
3335

3436
// create and deploy and undeploy the magic catalog
35-
magicCatalog := NewMagicCatalog(kubeClient, namespace, catalogName, provider)
37+
magicCatalog := NewMagicCatalog(c, namespace, catalogName, provider)
3638

3739
// deployment blocks until the catalog source has reached a READY status
38-
Expect(magicCatalog.DeployCatalog(context.TODO())).To(BeNil())
39-
Expect(magicCatalog.UndeployCatalog(context.TODO())).To(BeNil())
40+
Expect(magicCatalog.DeployCatalog(context.Background())).To(BeNil())
41+
Expect(magicCatalog.UndeployCatalog(context.Background())).To(BeNil())
42+
})
43+
When("an existing magic catalog exists", func() {
44+
var (
45+
mc MagicCatalog
46+
catalogName string
47+
)
48+
BeforeEach(func() {
49+
provider, err := NewFileBasedFiledBasedCatalogProvider(filepath.Join(testdataDir, "magiccatalog/fbc_initial.yaml"))
50+
Expect(err).To(BeNil())
51+
52+
catalogName = genName("mc-e2e-catalog-")
53+
54+
mc = NewMagicCatalog(c, generatedNamespace.GetName(), catalogName, provider)
55+
Expect(mc.DeployCatalog(context.Background())).To(BeNil())
56+
})
57+
AfterEach(func() {
58+
Expect(mc.UndeployCatalog(context.Background())).To(BeNil())
59+
})
60+
61+
It("should succeed when the magic catalog is updated", func() {
62+
updatedProvider, err := NewFileBasedFiledBasedCatalogProvider(filepath.Join(testdataDir, "magiccatalog/fbc_updated.yaml"))
63+
Expect(err).To(BeNil())
64+
65+
updatedMC := NewMagicCatalog(c, generatedNamespace.GetName(), catalogName, updatedProvider)
66+
Expect(updatedMC.UpdateCatalog(context.Background(), updatedProvider)).To(BeNil())
67+
68+
Eventually(func() (*corev1.ConfigMap, error) {
69+
cm := &corev1.ConfigMap{}
70+
err := c.Get(context.Background(), types.NamespacedName{
71+
Name: fmt.Sprintf("%s-configmap", catalogName),
72+
Namespace: generatedNamespace.GetName(),
73+
}, cm)
74+
if err != nil {
75+
return nil, err
76+
}
77+
return cm, nil
78+
}).Should(And(
79+
Not(BeNil()),
80+
WithTransform(func(c *corev1.ConfigMap) string {
81+
data, ok := c.Data["catalog.json"]
82+
if !ok {
83+
return ""
84+
}
85+
return data
86+
}, ContainSubstring(`---
87+
schema: olm.package
88+
name: packageA
89+
defaultChannel: stable
90+
---
91+
schema: olm.channel
92+
package: packageA
93+
name: stable
94+
entries:
95+
- name: busybox.v2.0.0
96+
replaces: busybox.v1.0.0
97+
---
98+
schema: olm.bundle
99+
name: busybox.v2.0.0
100+
package: packageA
101+
image: quay.io/olmtest/busybox-bundle:2.0.0
102+
properties:
103+
- type: olm.gvk
104+
value:
105+
group: example.com
106+
kind: TestA
107+
version: v1alpha1
108+
- type: olm.package
109+
value:
110+
packageName: packageA
111+
version: 1.0.0
112+
`)),
113+
))
114+
})
115+
It("should fail when the magic catalog is re-created", func() {
116+
Expect(mc.DeployCatalog(context.Background())).ToNot(BeNil())
117+
})
40118
})
41119
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
schema: olm.package
3+
name: packageA
4+
defaultChannel: stable
5+
---
6+
schema: olm.channel
7+
package: packageA
8+
name: stable
9+
entries:
10+
- name: busybox.v1.0.0
11+
---
12+
schema: olm.bundle
13+
name: busybox.v1.0.0
14+
package: packageA
15+
image: quay.io/olmtest/busybox-bundle:1.0.0
16+
properties:
17+
- type: olm.gvk
18+
value:
19+
group: example.com
20+
kind: TestA
21+
version: v1alpha1
22+
- type: olm.package
23+
value:
24+
packageName: packageA
25+
version: 1.0.0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
schema: olm.package
3+
name: packageA
4+
defaultChannel: stable
5+
---
6+
schema: olm.channel
7+
package: packageA
8+
name: stable
9+
entries:
10+
- name: busybox.v2.0.0
11+
replaces: busybox.v1.0.0
12+
---
13+
schema: olm.bundle
14+
name: busybox.v2.0.0
15+
package: packageA
16+
image: quay.io/olmtest/busybox-bundle:2.0.0
17+
properties:
18+
- type: olm.gvk
19+
value:
20+
group: example.com
21+
kind: TestA
22+
version: v1alpha1
23+
- type: olm.package
24+
value:
25+
packageName: packageA
26+
version: 1.0.0

0 commit comments

Comments
 (0)