Skip to content

Commit 0dd2057

Browse files
tmshortclaude
andcommitted
test: Add regression test for OCPBUGS-62942
Add TestClusterExtensionDeletionWithUnavailableCatalog to verify that when a ClusterExtension is being deleted, the reconcile loop does not attempt resolution even if the catalog is unavailable (which would cause a "cache for catalog not found" error). This test ensures that both the RevisionStatesGetter and Resolver are not called during deletion, preventing errors that would block deletion when catalogs are unavailable. The test creates a ClusterExtension with a finalizer, deletes it, and verifies that reconciliation succeeds without calling the resolver or revision states getter, both of which are configured to return errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) via /jira:solve OCPBUGS-62942 origin Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Todd Short <tshort@redhat.com>
1 parent 09ffb5e commit 0dd2057

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

internal/operator-controller/controllers/clusterextension_controller_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,70 @@ func TestClusterExtensionShortCircuitsReconcileDuringDeletion(t *testing.T) {
121121
}
122122
}
123123

124+
// TestClusterExtensionDeletionWithUnavailableCatalog tests the fix for OCPBUGS-62942.
125+
// It verifies that when a ClusterExtension is being deleted, the reconcile loop
126+
// does not attempt resolution even if the catalog is unavailable (which would cause
127+
// a "cache for catalog not found" error).
128+
func TestClusterExtensionDeletionWithUnavailableCatalog(t *testing.T) {
129+
cl, reconciler := newClientAndReconciler(t)
130+
131+
// Set up a resolver that would fail with a catalog error
132+
catalogNotFoundErr := errors.New("error walking catalogs: error getting package from catalog: cache for catalog not found")
133+
reconciler.Resolver = resolve.Func(func(_ context.Context, _ *ocv1.ClusterExtension, _ *ocv1.BundleMetadata) (*declcfg.Bundle, *bsemver.Version, *declcfg.Deprecation, error) {
134+
return nil, nil, nil, catalogNotFoundErr
135+
})
136+
137+
// Set up a revision states getter that would also fail
138+
revisionStatesErr := errors.New("getting installed bundle failed")
139+
reconciler.RevisionStatesGetter = &MockRevisionStatesGetter{
140+
Err: revisionStatesErr,
141+
}
142+
143+
ctx := context.Background()
144+
pkgName := fmt.Sprintf("test-pkg-%s", rand.String(6))
145+
extKey := types.NamespacedName{Name: fmt.Sprintf("cluster-extension-test-%s", rand.String(8))}
146+
147+
t.Log("When a ClusterExtension is being deleted")
148+
t.Log("By creating a cluster extension with a finalizer")
149+
clusterExtension := &ocv1.ClusterExtension{
150+
ObjectMeta: metav1.ObjectMeta{
151+
Name: extKey.Name,
152+
Finalizers: []string{
153+
controllers.ClusterExtensionCleanupUnpackCacheFinalizer,
154+
},
155+
},
156+
Spec: ocv1.ClusterExtensionSpec{
157+
Source: ocv1.SourceConfig{
158+
SourceType: "Catalog",
159+
Catalog: &ocv1.CatalogFilter{
160+
PackageName: pkgName,
161+
},
162+
},
163+
Namespace: "default",
164+
ServiceAccount: ocv1.ServiceAccountReference{
165+
Name: "default",
166+
},
167+
},
168+
}
169+
require.NoError(t, cl.Create(ctx, clusterExtension))
170+
171+
t.Log("And deleting the cluster extension")
172+
require.NoError(t, cl.Delete(ctx, clusterExtension))
173+
174+
t.Log("Then reconcile should succeed without attempting resolution")
175+
t.Log("By running reconcile")
176+
res, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: extKey})
177+
require.Equal(t, ctrl.Result{}, res)
178+
// Should not return the catalog error or revision states error because
179+
// reconcile should short-circuit before calling either the RevisionStatesGetter
180+
// or the Resolver
181+
require.NoError(t, err)
182+
183+
t.Log("And the cluster extension should still exist (waiting for finalizer cleanup)")
184+
require.NoError(t, cl.Get(ctx, extKey, clusterExtension))
185+
require.NotNil(t, clusterExtension.DeletionTimestamp)
186+
}
187+
124188
func TestClusterExtensionResolutionFails(t *testing.T) {
125189
pkgName := fmt.Sprintf("non-existent-%s", rand.String(6))
126190
cl, reconciler := newClientAndReconciler(t)

0 commit comments

Comments
 (0)