Skip to content

Commit 4bb317b

Browse files
committed
test/e2e: Refactor the Operator e2e tests to clean up testing resources
Update test/e2e/operator_test.go and attempt to refactor the current e2e specs to reduce the number of testing artifacts that are left behind when individual tests pass/fail. Signed-off-by: timflannagan <[email protected]>
1 parent 623572b commit 4bb317b

File tree

1 file changed

+126
-168
lines changed

1 file changed

+126
-168
lines changed

test/e2e/operator_test.go

Lines changed: 126 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ var _ = Describe("Operator API", func() {
3939
)
4040

4141
BeforeEach(func() {
42-
// Setup common utilities
4342
clientCtx = context.Background()
4443
scheme = ctx.Ctx().Scheme()
4544
listOpts = metav1.ListOptions{}
@@ -51,191 +50,147 @@ var _ = Describe("Operator API", func() {
5150
Expect(err).ToNot(HaveOccurred())
5251
})
5352

54-
// Ensures that an Operator resource can select its components by label and surface them correctly in its status.
55-
//
56-
// Steps:
57-
// 1. Create an Operator resource, o
58-
// 2. Ensure o's status eventually contains its component label selector
59-
// 3. Create namespaces ns-a and ns-b
60-
// 4. Label ns-a with o's component label
61-
// 5. Ensure o's status.components.refs field eventually contains a reference to ns-a
62-
// 6. Create ServiceAccounts sa-a and sa-b in namespaces ns-a and ns-b respectively
63-
// 7. Label sa-a and sa-b with o's component label
64-
// 8. Ensure o's status.components.refs field eventually contains references to sa-a and sa-b
65-
// 9. Remove the component label from sa-b
66-
// 10. Ensure the reference to sa-b is eventually removed from o's status.components.refs field
67-
// 11. Delete o
68-
// 12. Ensure o is re-created
69-
// 13. Delete ns-a
70-
// 14. Ensure the reference to ns-a is eventually removed from o's status.components.refs field
71-
// 15. Delete o
72-
// 16. Ensure o is not re-created
73-
It("should surface components in its status", func() {
74-
o := &operatorsv1.Operator{}
75-
o.SetName(genName("o-"))
76-
77-
Consistently(o).ShouldNot(ContainCopiedCSVReferences())
78-
53+
AfterEach(func() {
7954
Eventually(func() error {
80-
return client.Create(clientCtx, o)
55+
return operatorClient.DeleteCollection(clientCtx, metav1.DeleteOptions{}, listOpts)
8156
}).Should(Succeed())
57+
})
8258

83-
defer func() {
84-
Eventually(func() error {
85-
err := client.Delete(clientCtx, o)
86-
if apierrors.IsNotFound(err) {
87-
return nil
88-
}
59+
Context("when an Operator resource can select its components by label", func() {
60+
var (
61+
o *operatorsv1.Operator
62+
)
63+
BeforeEach(func() {
64+
o = &operatorsv1.Operator{}
65+
o.SetName(genName("o-"))
8966

90-
return err
67+
Eventually(func() error {
68+
return client.Create(clientCtx, o)
9169
}).Should(Succeed())
92-
}()
70+
})
71+
AfterEach(func() {
72+
Eventually(func() error {
73+
return controllerclient.IgnoreNotFound(client.Delete(clientCtx, o))
74+
}).Should(Succeed())
75+
})
9376

94-
By("eventually having a status that contains its component label selector")
95-
w, err := operatorClient.Watch(clientCtx, listOpts)
96-
Expect(err).ToNot(HaveOccurred())
97-
defer w.Stop()
77+
It("should not contain copied csv status references", func() {
78+
Consistently(o).ShouldNot(ContainCopiedCSVReferences())
79+
})
9880

99-
deadline, cancel := context.WithTimeout(clientCtx, 1*time.Minute)
100-
defer cancel()
81+
It("should surface referenced components in its status", func() {
82+
By("eventually having a status that contains its component label selector")
83+
w, err := operatorClient.Watch(clientCtx, listOpts)
84+
Expect(err).To(BeNil())
85+
defer w.Stop()
10186

102-
expectedKey := "operators.coreos.com/" + o.GetName()
103-
awaitPredicates(deadline, w, operatorPredicate(func(op *operatorsv1.Operator) bool {
104-
if op.Status.Components == nil || op.Status.Components.LabelSelector == nil {
105-
return false
106-
}
87+
deadline, cancel := context.WithTimeout(clientCtx, 1*time.Minute)
88+
defer cancel()
10789

108-
for _, requirement := range op.Status.Components.LabelSelector.MatchExpressions {
109-
if requirement.Key == expectedKey && requirement.Operator == metav1.LabelSelectorOpExists {
110-
return true
90+
expectedKey := "operators.coreos.com/" + o.GetName()
91+
awaitPredicates(deadline, w, operatorPredicate(func(op *operatorsv1.Operator) bool {
92+
if op.Status.Components == nil || op.Status.Components.LabelSelector == nil {
93+
return false
11194
}
112-
}
11395

114-
return false
115-
}))
116-
defer w.Stop()
96+
for _, requirement := range op.Status.Components.LabelSelector.MatchExpressions {
97+
if requirement.Key == expectedKey && requirement.Operator == metav1.LabelSelectorOpExists {
98+
return true
99+
}
100+
}
117101

118-
// Create namespaces ns-a and ns-b
119-
nsA := &corev1.Namespace{}
120-
nsA.SetName(genName("ns-a-"))
121-
nsB := &corev1.Namespace{}
122-
nsB.SetName(genName("ns-b-"))
102+
return false
103+
}))
104+
defer w.Stop()
123105

124-
for _, ns := range []*corev1.Namespace{nsA, nsB} {
125-
Eventually(func() error {
126-
return client.Create(clientCtx, ns)
127-
}).Should(Succeed())
106+
nsA := &corev1.Namespace{}
107+
nsA.SetName(genName("ns-a-"))
108+
nsB := &corev1.Namespace{}
109+
nsB.SetName(genName("ns-b-"))
128110

129-
defer func(n *corev1.Namespace) {
111+
for _, ns := range []*corev1.Namespace{nsA, nsB} {
130112
Eventually(func() error {
131-
err := client.Delete(clientCtx, n)
132-
if apierrors.IsNotFound(err) {
133-
return nil
134-
}
135-
return err
113+
return client.Create(clientCtx, ns)
136114
}).Should(Succeed())
137-
}(ns)
138-
}
139115

140-
// Label ns-a with o's component label
141-
setComponentLabel := func(m metav1.Object) error {
142-
m.SetLabels(map[string]string{expectedKey: ""})
143-
return nil
144-
}
145-
Eventually(Apply(nsA, setComponentLabel)).Should(Succeed())
116+
defer func(n *corev1.Namespace) {
117+
Eventually(func() error {
118+
err := client.Delete(clientCtx, n)
119+
if apierrors.IsNotFound(err) {
120+
return nil
121+
}
122+
return err
123+
}).Should(Succeed())
124+
}(ns)
125+
}
146126

147-
// Ensure o's status.components.refs field eventually contains a reference to ns-a
148-
By("eventually listing a single component reference")
149-
componentRefEventuallyExists(w, true, getReference(scheme, nsA))
127+
setComponentLabel := func(m metav1.Object) error {
128+
m.SetLabels(map[string]string{expectedKey: ""})
129+
return nil
130+
}
131+
Eventually(Apply(nsA, setComponentLabel)).Should(Succeed())
150132

151-
// Create ServiceAccounts sa-a and sa-b in namespaces ns-a and ns-b respectively
152-
saA := &corev1.ServiceAccount{}
153-
saA.SetName(genName("sa-a-"))
154-
saA.SetNamespace(nsA.GetName())
155-
saB := &corev1.ServiceAccount{}
156-
saB.SetName(genName("sa-b-"))
157-
saB.SetNamespace(nsB.GetName())
133+
By("eventually listing a single component reference")
134+
componentRefEventuallyExists(w, true, getReference(scheme, nsA))
158135

159-
for _, sa := range []*corev1.ServiceAccount{saA, saB} {
160-
Eventually(func() error {
161-
return client.Create(clientCtx, sa)
162-
}).Should(Succeed())
163-
defer func(sa *corev1.ServiceAccount) {
136+
saA := &corev1.ServiceAccount{}
137+
saA.SetName(genName("sa-a-"))
138+
saA.SetNamespace(nsA.GetName())
139+
saB := &corev1.ServiceAccount{}
140+
saB.SetName(genName("sa-b-"))
141+
saB.SetNamespace(nsB.GetName())
142+
143+
for _, sa := range []*corev1.ServiceAccount{saA, saB} {
164144
Eventually(func() error {
165-
err := client.Delete(clientCtx, sa)
166-
if apierrors.IsNotFound(err) {
167-
return nil
168-
}
169-
return err
145+
return client.Create(clientCtx, sa)
170146
}).Should(Succeed())
171-
}(sa)
172-
}
147+
defer func(sa *corev1.ServiceAccount) {
148+
Eventually(func() error {
149+
return controllerclient.IgnoreNotFound(client.Delete(clientCtx, sa))
150+
}).Should(Succeed())
151+
}(sa)
152+
}
173153

174-
// Label sa-a and sa-b with o's component label
175-
Eventually(Apply(saA, setComponentLabel)).Should(Succeed())
176-
Eventually(Apply(saB, setComponentLabel)).Should(Succeed())
154+
Eventually(Apply(saA, setComponentLabel)).Should(Succeed())
155+
Eventually(Apply(saB, setComponentLabel)).Should(Succeed())
177156

178-
// Ensure o's status.components.refs field eventually contains references to sa-a and sa-b
179-
By("eventually listing multiple component references")
180-
componentRefEventuallyExists(w, true, getReference(scheme, saA))
181-
componentRefEventuallyExists(w, true, getReference(scheme, saB))
157+
By("eventually listing multiple component references")
158+
componentRefEventuallyExists(w, true, getReference(scheme, saA))
159+
componentRefEventuallyExists(w, true, getReference(scheme, saB))
182160

183-
// Remove the component label from sa-b
184-
Eventually(Apply(saB, func(m metav1.Object) error {
185-
m.SetLabels(nil)
186-
return nil
187-
})).Should(Succeed())
161+
Eventually(Apply(saB, func(m metav1.Object) error {
162+
m.SetLabels(nil)
163+
return nil
164+
})).Should(Succeed())
188165

189-
// Ensure the reference to sa-b is eventually removed from o's status.components.refs field
190-
By("removing a component's reference when it no longer bears the component label")
191-
componentRefEventuallyExists(w, false, getReference(scheme, saB))
166+
By("removing a component's reference when it no longer bears the component label")
167+
componentRefEventuallyExists(w, false, getReference(scheme, saB))
192168

193-
// Delete o
194-
Eventually(func() error {
195-
err := client.Delete(clientCtx, o)
196-
if err != nil && !apierrors.IsNotFound(err) {
197-
return err
198-
}
199-
return nil
200-
}).Should(Succeed())
169+
Eventually(func() error {
170+
return controllerclient.IgnoreNotFound(client.Delete(clientCtx, o))
171+
}).Should(Succeed())
201172

202-
// Ensure that o is eventually recreated (because some of its components still exist).
203-
By("recreating the Operator when any components still exist")
204-
Eventually(func() error {
205-
return client.Get(clientCtx, types.NamespacedName{Name: o.GetName()}, o)
206-
}).Should(Succeed())
173+
By("recreating the Operator when any components still exist")
174+
Eventually(func() error {
175+
return client.Get(clientCtx, types.NamespacedName{Name: o.GetName()}, o)
176+
}).Should(Succeed())
207177

208-
// Delete ns-a
209-
Eventually(func() error {
210-
err := client.Delete(clientCtx, nsA)
211-
if apierrors.IsNotFound(err) {
212-
return nil
213-
}
214-
return err
215-
}).Should(Succeed())
178+
Eventually(func() error {
179+
return controllerclient.IgnoreNotFound(client.Delete(clientCtx, nsA))
180+
}).Should(Succeed())
216181

217-
// Ensure the reference to ns-a is eventually removed from o's status.components.refs field
218-
By("removing a component's reference when it no longer exists")
219-
componentRefEventuallyExists(w, false, getReference(scheme, nsA))
182+
By("removing a component's reference when it no longer exists")
183+
componentRefEventuallyExists(w, false, getReference(scheme, nsA))
220184

221-
// Delete o
222-
Eventually(func() error {
223-
err := client.Delete(clientCtx, o)
224-
if apierrors.IsNotFound(err) {
225-
return nil
226-
}
227-
return err
228-
}).Should(Succeed())
185+
Eventually(func() error {
186+
return controllerclient.IgnoreNotFound(client.Delete(clientCtx, o))
187+
}).Should(Succeed())
229188

230-
// Ensure that o is consistently not found
231-
By("verifying the Operator is permanently deleted if it has no components")
232-
Consistently(func() error {
233-
err := client.Get(clientCtx, types.NamespacedName{Name: o.GetName()}, o)
234-
if apierrors.IsNotFound(err) {
235-
return nil
236-
}
237-
return err
238-
}).Should(Succeed())
189+
By("verifying the Operator is permanently deleted if it has no components")
190+
Consistently(func() error {
191+
return controllerclient.IgnoreNotFound(client.Get(clientCtx, types.NamespacedName{Name: o.GetName()}, o))
192+
}).Should(Succeed())
193+
})
239194
})
240195

241196
Context("when a subscription to a package exists", func() {
@@ -247,14 +202,12 @@ var _ = Describe("Operator API", func() {
247202
)
248203

249204
BeforeEach(func() {
250-
// Subscribe to a package and await a successful install
251205
ns = &corev1.Namespace{}
252206
ns.SetName(genName("ns-"))
253207
Eventually(func() error {
254208
return client.Create(clientCtx, ns)
255209
}).Should(Succeed())
256210

257-
// Default to AllNamespaces
258211
og := &operatorsv1.OperatorGroup{}
259212
og.SetNamespace(ns.GetName())
260213
og.SetName(genName("og-"))
@@ -274,7 +227,6 @@ var _ = Describe("Operator API", func() {
274227
return client.Create(clientCtx, cs)
275228
}).Should(Succeed())
276229

277-
// Wait for the CatalogSource to be ready
278230
_, err := fetchCatalogSourceOnStatus(newCRClient(), cs.GetName(), cs.GetNamespace(), catalogSourceRegistryPodSynced)
279231
Expect(err).ToNot(HaveOccurred())
280232

@@ -323,12 +275,21 @@ var _ = Describe("Operator API", func() {
323275
})
324276

325277
AfterEach(func() {
278+
By("Deleting the testing namespace")
326279
Eventually(func() error {
327-
err := client.Delete(clientCtx, ns)
328-
if apierrors.IsNotFound(err) {
329-
return nil
330-
}
331-
return err
280+
return controllerclient.IgnoreNotFound(client.Delete(clientCtx, ns))
281+
}).Should(Succeed())
282+
283+
By("Deleting the kiali-related CRDs")
284+
Eventually(func() error {
285+
return client.DeleteAllOf(clientCtx, &apiextensionsv1.CustomResourceDefinition{}, controllerclient.MatchingLabels{
286+
fmt.Sprintf("operators.coreos.com/%s", operatorName.Name): "",
287+
})
288+
}).Should(Succeed())
289+
290+
By("Deleting the test Operator resource")
291+
Eventually(func() error {
292+
return operatorClient.Delete(clientCtx, operatorName.Name, metav1.DeleteOptions{})
332293
}).Should(Succeed())
333294
})
334295

@@ -363,7 +324,7 @@ var _ = Describe("Operator API", func() {
363324
var newNs *corev1.Namespace
364325

365326
BeforeEach(func() {
366-
// Subscribe to a package and await a successful install
327+
By("Subscribe to a package and await a successful install")
367328
newNs = &corev1.Namespace{}
368329
newNs.SetName(genName("ns-"))
369330
Eventually(func() error {
@@ -372,11 +333,7 @@ var _ = Describe("Operator API", func() {
372333
})
373334
AfterEach(func() {
374335
Eventually(func() error {
375-
err := client.Delete(clientCtx, newNs)
376-
if apierrors.IsNotFound(err) {
377-
return nil
378-
}
379-
return err
336+
return controllerclient.IgnoreNotFound(client.Delete(clientCtx, newNs))
380337
}).Should(Succeed())
381338
})
382339
It("should not adopt copied csvs", func() {
@@ -514,6 +471,7 @@ func ReferenceComponents(refs []*corev1.ObjectReference) gomegatypes.GomegaMatch
514471

515472
for _, ref := range refs {
516473
if _, ok := actual[*ref]; !ok {
474+
ctx.Ctx().Logf("reference missing: %v - %v - %v", ref.GetObjectKind(), ref.Name, ref.Namespace)
517475
return false, nil
518476
}
519477
}

0 commit comments

Comments
 (0)