@@ -29,167 +29,33 @@ var _ = Describe("Operator Install", func() {
2929 ctx context.Context
3030 pkgName string
3131 operatorName string
32- catalogName string
3332 operator * operatorv1alpha1.Operator
3433 operatorCatalog * catalogd.Catalog
3534 )
3635 When ("An operator is installed from an operator catalog" , func () {
3736 BeforeEach (func () {
3837 ctx = context .Background ()
39- catalogName = fmt .Sprintf ("catalog-%s" , rand .String (8 ))
40- operatorCatalog = & catalogd.Catalog {
41- ObjectMeta : metav1.ObjectMeta {
42- Name : catalogName ,
43- },
44- Spec : catalogd.CatalogSpec {
45- Source : catalogd.CatalogSource {
46- Type : catalogd .SourceTypeImage ,
47- Image : & catalogd.ImageSource {
48- Ref : testCatalogRef ,
49- },
50- },
51- },
52- }
53- })
54- It ("resolves the specified package with correct bundle path" , func () {
55- err := c .Create (ctx , operatorCatalog )
56- Expect (err ).ToNot (HaveOccurred ())
57- Eventually (func (g Gomega ) {
58- err = c .Get (ctx , types.NamespacedName {Name : testCatalogName }, operatorCatalog )
59- g .Expect (err ).ToNot (HaveOccurred ())
60- g .Expect (len (operatorCatalog .Status .Conditions )).To (Equal (1 ))
61- cond := apimeta .FindStatusCondition (operatorCatalog .Status .Conditions , catalogd .TypeUnpacked )
62- g .Expect (cond ).ToNot (BeNil ())
63- g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
64- g .Expect (cond .Reason ).To (Equal (catalogd .ReasonUnpackSuccessful ))
65- g .Expect (cond .Message ).To (ContainSubstring ("successfully unpacked the catalog image" ))
66- }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
67-
68- By ("creating the Operator resource" )
69- err = c .Create (ctx , operator )
38+ var err error
39+ operatorCatalog , err = createTestCatalog (ctx , testCatalogName , testCatalogRef )
7040 Expect (err ).ToNot (HaveOccurred ())
7141
72- By ("eventually reporting a successful resolution and bundle path" )
73- Eventually (func (g Gomega ) {
74- err = c .Get (ctx , types.NamespacedName {Name : operator .Name }, operator )
75- g .Expect (err ).ToNot (HaveOccurred ())
76-
77- cond := apimeta .FindStatusCondition (operator .Status .Conditions , operatorv1alpha1 .TypeResolved )
78- g .Expect (cond ).ToNot (BeNil ())
79- g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
80- g .Expect (cond .Message ).To (ContainSubstring ("successfully unpacked the catalog image" ))
81-
82- // For some reason the above condition check is returning true and the
83- // Operators end up being created before the packages exist. Adding this check
84- // to ensure that there are some packages that exist before actually returning from this
85- // check.
86- pkgList := & catalogd.PackageList {}
87- err = c .List (ctx , pkgList )
88- g .Expect (err ).ToNot (HaveOccurred ())
89- cond := apimeta .FindStatusCondition (operator .Status .Conditions , operatorv1alpha1 .TypeInstalled )
90- g .Expect (cond ).ToNot (BeNil ())
91- g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
92- g .Expect (cond .Reason ).To (Equal (operatorv1alpha1 .ReasonSuccess ))
93- g .Expect (cond .Message ).To (ContainSubstring ("installed from" ))
94- g .Expect (operator .Status .InstalledBundleResource ).ToNot (BeEmpty ())
95- bd := rukpakv1alpha1.BundleDeployment {}
96- err = c .Get (ctx , types.NamespacedName {Name : operatorName }, & bd )
97- g .Expect (err ).ToNot (HaveOccurred ())
98-
99- cond = apimeta .FindStatusCondition (bd .Status .Conditions , rukpakv1alpha1 .TypeHasValidBundle )
100- g .Expect (cond ).ToNot (BeNil ())
101- g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
102- g .Expect (cond .Reason ).To (Equal (rukpakv1alpha1 .ReasonUnpackSuccessful ))
103-
104- cond = apimeta .FindStatusCondition (bd .Status .Conditions , rukpakv1alpha1 .TypeInstalled )
105- g .Expect (cond ).ToNot (BeNil ())
106- g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
107- g .Expect (cond .Reason ).To (Equal (rukpakv1alpha1 .ReasonInstallationSucceeded ))
108- }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
109- })
110- It ("resolves again when a new catalog is available" , func () {
111- Eventually (func (g Gomega ) {
112- // target package should not be present on cluster
113- err := c .Get (ctx , types.NamespacedName {Name : pkgName }, & catalogd.Package {})
114- Expect (errors .IsNotFound (err )).To (BeTrue ())
115- }).WithTimeout (5 * time .Minute ).WithPolling (defaultPoll ).Should (Succeed ())
116-
117- By ("creating the Operator resource" )
118- err := c .Create (ctx , operator )
119- Expect (err ).ToNot (HaveOccurred ())
120-
121- By ("failing to find Operator during resolution" )
122- Eventually (func (g Gomega ) {
123- err = c .Get (ctx , types.NamespacedName {Name : operator .Name }, operator )
124- g .Expect (err ).ToNot (HaveOccurred ())
125- cond := apimeta .FindStatusCondition (operator .Status .Conditions , operatorv1alpha1 .TypeResolved )
126- g .Expect (cond ).ToNot (BeNil ())
127- g .Expect (cond .Status ).To (Equal (metav1 .ConditionFalse ))
128- g .Expect (cond .Reason ).To (Equal (operatorv1alpha1 .ReasonResolutionFailed ))
129- g .Expect (cond .Message ).To (Equal (fmt .Sprintf ("package '%s' not found" , pkgName )))
130- }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
131-
132- By ("creating an Operator catalog with the desired package" )
133- err = c .Create (ctx , operatorCatalog )
134- Expect (err ).ToNot (HaveOccurred ())
13542 Eventually (func (g Gomega ) {
136- err = c .Get (ctx , types.NamespacedName {Name : operatorCatalog .Name }, operatorCatalog )
43+ err : = c .Get (ctx , types.NamespacedName {Name : operatorCatalog .Name }, operatorCatalog )
13744 g .Expect (err ).ToNot (HaveOccurred ())
13845 cond := apimeta .FindStatusCondition (operatorCatalog .Status .Conditions , catalogd .TypeUnpacked )
13946 g .Expect (cond ).ToNot (BeNil ())
14047 g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
14148 g .Expect (cond .Reason ).To (Equal (catalogd .ReasonUnpackSuccessful ))
142- }). WithTimeout ( 5 * time . Minute ). WithPolling ( defaultPoll ). Should ( Succeed ( ))
49+ // g.Expect(cond.Message).To(ContainSubstring("resolved to" ))
14350
144- By ("eventually resolving the package successfully" )
145- Eventually (func (g Gomega ) {
146- err = c .Get (ctx , types.NamespacedName {Name : operator .Name }, operator )
51+ // Ensure some packages exist before continuing so the
52+ // operators don't get stuck in a bad state
53+ pList := & catalogd.PackageList {}
54+ err = c .List (ctx , pList )
14755 g .Expect (err ).ToNot (HaveOccurred ())
148- cond := apimeta .FindStatusCondition (operator .Status .Conditions , operatorv1alpha1 .TypeResolved )
149- g .Expect (cond ).ToNot (BeNil ())
150- g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
151- g .Expect (cond .Reason ).To (Equal (operatorv1alpha1 .ReasonSuccess ))
56+ g .Expect (pList .Items ).To (HaveLen (2 ))
15257 }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
15358 })
154-
155- AfterEach (func () {
156- err := c .Delete (ctx , operator )
157- Expect (err ).ToNot (HaveOccurred ())
158- Eventually (func (g Gomega ) {
159- err = c .Get (ctx , types.NamespacedName {Name : operatorName }, & operatorv1alpha1.Operator {})
160- Expect (errors .IsNotFound (err )).To (BeTrue ())
161- }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
162-
163- err = c .Delete (ctx , operatorCatalog )
164- Expect (err ).ToNot (HaveOccurred ())
165- Eventually (func (g Gomega ) {
166- err = c .Get (ctx , types.NamespacedName {Name : operatorCatalog .Name }, & catalogd.Catalog {})
167- Expect (errors .IsNotFound (err )).To (BeTrue ())
168- }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
169-
170- // speed up delete without waiting for gc
171- err = c .DeleteAllOf (ctx , & catalogd.BundleMetadata {})
172- Expect (err ).ToNot (HaveOccurred ())
173- err = c .DeleteAllOf (ctx , & catalogd.Package {})
174- Expect (err ).ToNot (HaveOccurred ())
175-
176- Eventually (func (g Gomega ) {
177- // ensure resource cleanup
178- packages := & catalogd.PackageList {}
179- err = c .List (ctx , packages )
180- Expect (err ).To (BeNil ())
181- Expect (packages .Items ).To (BeEmpty ())
182-
183- bmd := & catalogd.BundleMetadataList {}
184- err = c .List (ctx , bmd )
185- Expect (err ).To (BeNil ())
186- Expect (bmd .Items ).To (BeEmpty ())
187-
188- err = c .Get (ctx , types.NamespacedName {Name : operatorName }, & rukpakv1alpha1.BundleDeployment {})
189- Expect (errors .IsNotFound (err )).To (BeTrue ())
190- }).WithTimeout (5 * time .Minute ).WithPolling (defaultPoll ).Should (Succeed ())
191- })
192-
19359 When ("the operator bundle format is registry+v1" , func () {
19460 BeforeEach (func () {
19561 pkgName = "prometheus"
@@ -238,7 +104,54 @@ var _ = Describe("Operator Install", func() {
238104 g .Expect (bd .Status .Conditions [0 ].Reason ).To (Equal ("UnpackSuccessful" ))
239105 g .Expect (bd .Status .Conditions [1 ].Reason ).To (Equal ("InstallationSucceeded" ))
240106 }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
107+ })
108+ It ("resolves again when a new catalog is available" , func () {
109+ // Delete the catalog first
110+ err := c .Delete (ctx , operatorCatalog )
111+ Expect (err ).ToNot (HaveOccurred ())
112+
113+ Eventually (func (g Gomega ) {
114+ // target package should not be present on cluster
115+ err := c .Get (ctx , types.NamespacedName {Name : pkgName }, & catalogd.Package {})
116+ g .Expect (errors .IsNotFound (err )).To (BeTrue ())
117+ }).WithTimeout (5 * time .Minute ).WithPolling (defaultPoll ).Should (Succeed ())
118+
119+ By ("creating the Operator resource" )
120+ err = c .Create (ctx , operator )
121+ Expect (err ).ToNot (HaveOccurred ())
122+
123+ By ("failing to find Operator during resolution" )
124+ Eventually (func (g Gomega ) {
125+ err = c .Get (ctx , types.NamespacedName {Name : operator .Name }, operator )
126+ g .Expect (err ).ToNot (HaveOccurred ())
127+ cond := apimeta .FindStatusCondition (operator .Status .Conditions , operatorv1alpha1 .TypeResolved )
128+ g .Expect (cond ).ToNot (BeNil ())
129+ g .Expect (cond .Status ).To (Equal (metav1 .ConditionFalse ))
130+ g .Expect (cond .Reason ).To (Equal (operatorv1alpha1 .ReasonResolutionFailed ))
131+ g .Expect (cond .Message ).To (Equal (fmt .Sprintf ("package '%s' not found" , pkgName )))
132+ }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
241133
134+ By ("creating an Operator catalog with the desired package" )
135+ operatorCatalog , err = createTestCatalog (ctx , testCatalogName , testCatalogRef )
136+ Expect (err ).ToNot (HaveOccurred ())
137+ Eventually (func (g Gomega ) {
138+ err = c .Get (ctx , types.NamespacedName {Name : operatorCatalog .Name }, operatorCatalog )
139+ g .Expect (err ).ToNot (HaveOccurred ())
140+ cond := apimeta .FindStatusCondition (operatorCatalog .Status .Conditions , catalogd .TypeUnpacked )
141+ g .Expect (cond ).ToNot (BeNil ())
142+ g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
143+ g .Expect (cond .Reason ).To (Equal (catalogd .ReasonUnpackSuccessful ))
144+ }).WithTimeout (5 * time .Minute ).WithPolling (defaultPoll ).Should (Succeed ())
145+
146+ By ("eventually resolving the package successfully" )
147+ Eventually (func (g Gomega ) {
148+ err = c .Get (ctx , types.NamespacedName {Name : operator .Name }, operator )
149+ g .Expect (err ).ToNot (HaveOccurred ())
150+ cond := apimeta .FindStatusCondition (operator .Status .Conditions , operatorv1alpha1 .TypeResolved )
151+ g .Expect (cond ).ToNot (BeNil ())
152+ g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
153+ g .Expect (cond .Reason ).To (Equal (operatorv1alpha1 .ReasonSuccess ))
154+ }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
242155 })
243156 AfterEach (func () {
244157 err := c .Delete (ctx , operator )
@@ -294,13 +207,113 @@ var _ = Describe("Operator Install", func() {
294207 g .Expect (bd .Status .Conditions [0 ].Reason ).To (Equal ("UnpackSuccessful" ))
295208 g .Expect (bd .Status .Conditions [1 ].Reason ).To (Equal ("InstallationSucceeded" ))
296209 }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
210+ })
211+ It ("resolves again when a new catalog is available" , func () {
212+ // Delete the catalog first
213+ err := c .Delete (ctx , operatorCatalog )
214+ Expect (err ).ToNot (HaveOccurred ())
215+
216+ Eventually (func (g Gomega ) {
217+ // target package should not be present on cluster
218+ err := c .Get (ctx , types.NamespacedName {Name : pkgName }, & catalogd.Package {})
219+ g .Expect (errors .IsNotFound (err )).To (BeTrue ())
220+ }).WithTimeout (5 * time .Minute ).WithPolling (defaultPoll ).Should (Succeed ())
221+
222+ By ("creating the Operator resource" )
223+ err = c .Create (ctx , operator )
224+ Expect (err ).ToNot (HaveOccurred ())
225+
226+ By ("failing to find Operator during resolution" )
227+ Eventually (func (g Gomega ) {
228+ err = c .Get (ctx , types.NamespacedName {Name : operator .Name }, operator )
229+ g .Expect (err ).ToNot (HaveOccurred ())
230+ cond := apimeta .FindStatusCondition (operator .Status .Conditions , operatorv1alpha1 .TypeResolved )
231+ g .Expect (cond ).ToNot (BeNil ())
232+ g .Expect (cond .Status ).To (Equal (metav1 .ConditionFalse ))
233+ g .Expect (cond .Reason ).To (Equal (operatorv1alpha1 .ReasonResolutionFailed ))
234+ g .Expect (cond .Message ).To (Equal (fmt .Sprintf ("package '%s' not found" , pkgName )))
235+ }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
236+
237+ By ("creating an Operator catalog with the desired package" )
238+ operatorCatalog , err = createTestCatalog (ctx , testCatalogName , testCatalogRef )
239+ Expect (err ).ToNot (HaveOccurred ())
240+ Eventually (func (g Gomega ) {
241+ err = c .Get (ctx , types.NamespacedName {Name : operatorCatalog .Name }, operatorCatalog )
242+ g .Expect (err ).ToNot (HaveOccurred ())
243+ cond := apimeta .FindStatusCondition (operatorCatalog .Status .Conditions , catalogd .TypeUnpacked )
244+ g .Expect (cond ).ToNot (BeNil ())
245+ g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
246+ g .Expect (cond .Reason ).To (Equal (catalogd .ReasonUnpackSuccessful ))
247+ }).WithTimeout (5 * time .Minute ).WithPolling (defaultPoll ).Should (Succeed ())
297248
249+ By ("eventually resolving the package successfully" )
250+ Eventually (func (g Gomega ) {
251+ err = c .Get (ctx , types.NamespacedName {Name : operator .Name }, operator )
252+ g .Expect (err ).ToNot (HaveOccurred ())
253+ cond := apimeta .FindStatusCondition (operator .Status .Conditions , operatorv1alpha1 .TypeResolved )
254+ g .Expect (cond ).ToNot (BeNil ())
255+ g .Expect (cond .Status ).To (Equal (metav1 .ConditionTrue ))
256+ g .Expect (cond .Reason ).To (Equal (operatorv1alpha1 .ReasonSuccess ))
257+ }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
298258 })
299259 AfterEach (func () {
300260 err := c .Delete (ctx , operator )
301261 Expect (err ).ToNot (HaveOccurred ())
302262 })
303263 })
304264
265+ AfterEach (func () {
266+ err := c .Delete (ctx , operatorCatalog )
267+ Expect (err ).ToNot (HaveOccurred ())
268+ Eventually (func (g Gomega ) {
269+ err = c .Get (ctx , types.NamespacedName {Name : operatorCatalog .Name }, & catalogd.Catalog {})
270+ Expect (errors .IsNotFound (err )).To (BeTrue ())
271+ }).WithTimeout (defaultTimeout ).WithPolling (defaultPoll ).Should (Succeed ())
272+
273+ // speed up delete without waiting for gc
274+ err = c .DeleteAllOf (ctx , & catalogd.BundleMetadata {})
275+ Expect (err ).ToNot (HaveOccurred ())
276+ err = c .DeleteAllOf (ctx , & catalogd.Package {})
277+ Expect (err ).ToNot (HaveOccurred ())
278+
279+ Eventually (func (g Gomega ) {
280+ // ensure resource cleanup
281+ packages := & catalogd.PackageList {}
282+ err = c .List (ctx , packages )
283+ Expect (err ).To (BeNil ())
284+ Expect (packages .Items ).To (BeEmpty ())
285+
286+ bmd := & catalogd.BundleMetadataList {}
287+ err = c .List (ctx , bmd )
288+ Expect (err ).To (BeNil ())
289+ Expect (bmd .Items ).To (BeEmpty ())
290+
291+ err = c .Get (ctx , types.NamespacedName {Name : operatorName }, & rukpakv1alpha1.BundleDeployment {})
292+ Expect (errors .IsNotFound (err )).To (BeTrue ())
293+ }).WithTimeout (5 * time .Minute ).WithPolling (defaultPoll ).Should (Succeed ())
294+ })
295+
305296 })
306297})
298+
299+ // createTestCatalog will create a new catalog on the test cluster, provided
300+ // the context, catalog name, and the image reference. It returns the created catalog
301+ // or an error if any errors occurred while creating the catalog.
302+ func createTestCatalog (ctx context.Context , name string , imageRef string ) (* catalogd.Catalog , error ) {
303+ catalog := & catalogd.Catalog {
304+ ObjectMeta : metav1.ObjectMeta {
305+ Name : name ,
306+ },
307+ Spec : catalogd.CatalogSpec {
308+ Source : catalogd.CatalogSource {
309+ Type : catalogd .SourceTypeImage ,
310+ Image : & catalogd.ImageSource {
311+ Ref : imageRef ,
312+ },
313+ },
314+ },
315+ }
316+
317+ err := c .Create (ctx , catalog )
318+ return catalog , err
319+ }
0 commit comments