@@ -149,3 +149,127 @@ Feature: Recover cluster extension from errors that might occur during its lifet
149149 Then ClusterExtension is available
150150 And ClusterExtension reports Progressing as True with Reason Succeeded
151151 And ClusterExtension reports Installed as True
152+
153+ # CATALOG DELETION RESILIENCE SCENARIOS
154+
155+ Scenario : Extension continues running after catalog deletion
156+ Given ServiceAccount "olm-sa" with needed permissions is available in ${TEST_NAMESPACE}
157+ And ClusterExtension is applied
158+ """
159+ apiVersion: olm.operatorframework.io/v1
160+ kind: ClusterExtension
161+ metadata:
162+ name: ${NAME}
163+ spec:
164+ namespace: ${TEST_NAMESPACE}
165+ serviceAccount:
166+ name: olm-sa
167+ source:
168+ sourceType: Catalog
169+ catalog:
170+ packageName: test
171+ selector:
172+ matchLabels:
173+ "olm.operatorframework.io/metadata.name": test-catalog
174+ """
175+ And ClusterExtension is rolled out
176+ And ClusterExtension is available
177+ And resource "deployment/test-operator" is available
178+ And resource "configmap/test-configmap" is available
179+ When ClusterCatalog "test" is deleted
180+ # Verify controller still maintains resources after catalog deletion by removing and restoring a resource.
181+ # This approach avoids race conditions because:
182+ # - We don't rely on status flags that might be unchanged (e.g., Installed=True before and after)
183+ # - Resource restoration is an observable event that PROVES the controller reconciled after deletion
184+ # - The controller must actively apply manifests to restore the removed resource
185+ And resource "configmap/test-configmap" is removed
186+ Then resource "configmap/test-configmap" is eventually restored
187+ And resource "deployment/test-operator" is available
188+
189+ Scenario : Config changes are allowed even when the catalog does not exist anymore
190+ Given ServiceAccount "olm-sa" with needed permissions is available in ${TEST_NAMESPACE}
191+ And ClusterExtension is applied
192+ """
193+ apiVersion: olm.operatorframework.io/v1
194+ kind: ClusterExtension
195+ metadata:
196+ name: ${NAME}
197+ spec:
198+ namespace: ${TEST_NAMESPACE}
199+ serviceAccount:
200+ name: olm-sa
201+ source:
202+ sourceType: Catalog
203+ catalog:
204+ packageName: test
205+ selector:
206+ matchLabels:
207+ "olm.operatorframework.io/metadata.name": test-catalog
208+ """
209+ And ClusterExtension is rolled out
210+ And ClusterExtension is available
211+ And ClusterCatalog "test" is deleted
212+ When ClusterExtension is updated to add preflight config
213+ """
214+ apiVersion: olm.operatorframework.io/v1
215+ kind: ClusterExtension
216+ metadata:
217+ name: ${NAME}
218+ spec:
219+ namespace: ${TEST_NAMESPACE}
220+ serviceAccount:
221+ name: olm-sa
222+ install:
223+ preflight:
224+ crdUpgradeSafety:
225+ enforcement: None
226+ source:
227+ sourceType: Catalog
228+ catalog:
229+ packageName: test
230+ selector:
231+ matchLabels:
232+ "olm.operatorframework.io/metadata.name": test-catalog
233+ """
234+ # Wait for reconciliation of the updated spec (config change should succeed without catalog)
235+ # First ensure the controller has reconciled the new generation (spec update)
236+ And ClusterExtension latest generation has been reconciled
237+ # Config-only changes don't trigger resolution failure because the bundle version hasn't changed.
238+ # The controller falls back to the installed bundle (via handleResolutionError), which allows
239+ # Apply to run and successfully maintain resources. This results in Progressing=Succeeded.
240+ And ClusterExtension reports Progressing as True with Reason Succeeded
241+ Then ClusterExtension is available
242+ And ClusterExtension reports Installed as True
243+
244+ Scenario : Version upgrade does not proceed when catalog does not exist
245+ Given ServiceAccount "olm-sa" with needed permissions is available in ${TEST_NAMESPACE}
246+ And ClusterExtension is applied
247+ """
248+ apiVersion: olm.operatorframework.io/v1
249+ kind: ClusterExtension
250+ metadata:
251+ name: ${NAME}
252+ spec:
253+ namespace: ${TEST_NAMESPACE}
254+ serviceAccount:
255+ name: olm-sa
256+ source:
257+ sourceType: Catalog
258+ catalog:
259+ packageName: test
260+ version: "1.0.0"
261+ selector:
262+ matchLabels:
263+ "olm.operatorframework.io/metadata.name": test-catalog
264+ """
265+ And ClusterExtension is rolled out
266+ And ClusterExtension is available
267+ And bundle "test-operator.1.0.0" is installed in version "1.0.0"
268+ When ClusterCatalog "test" is deleted
269+ And ClusterExtension is updated to version "1.0.1"
270+ # Wait for reconciliation after the version change request
271+ # Note: Retrying status means controller will auto-upgrade when catalog becomes available
272+ Then ClusterExtension reports Progressing as True with Reason Retrying
273+ # Verify upgrade did not proceed: version remains at 1.0.0 (not 1.0.1)
274+ And bundle "test-operator.1.0.0" is installed in version "1.0.0"
275+ And ClusterExtension reports Installed as True
0 commit comments