From 8e85e558269d7191283072b3f3e8b7eae7a62f98 Mon Sep 17 00:00:00 2001 From: Sai Sridhar Date: Mon, 1 Jun 2026 08:35:09 +0530 Subject: [PATCH] fix: lower GetPodClique NotFound log to V(1) during expected cascade-delete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During a normal PodCliqueSet cascade-delete, the PodClique controller receives reconcile requests for already-deleted PodCliques. The helper was logging each at info level, producing one log line per deleted PodClique at scale — significant noise with no actionable signal. Change: when ignoreNotFound=true (the caller has signalled the NotFound is expected), log at V(1) instead of Info. Unexpected missing PodCliques — where ignoreNotFound=false — are still propagated as errors so the owning reconciler can surface them. Add TestGetPodClique_IgnoreNotFoundFalse to cover the error-propagation path (ignoreNotFound=false on a missing object must not silently swallow the error). Closes #622 --- .../internal/controller/utils/reconciler.go | 8 ++++++-- .../controller/utils/reconciler_test.go | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/operator/internal/controller/utils/reconciler.go b/operator/internal/controller/utils/reconciler.go index 47921ea1f..baa141c9d 100644 --- a/operator/internal/controller/utils/reconciler.go +++ b/operator/internal/controller/utils/reconciler.go @@ -45,11 +45,15 @@ func GetPodCliqueSet(ctx context.Context, cl client.Client, logger logr.Logger, return grovectrl.ContinueReconcile() } -// GetPodClique gets the latest PodClique object. It will usually hit the informer cache. If the object is not found, it will log a message and return DoNotRequeue. +// GetPodClique gets the latest PodClique object. It will usually hit the informer cache. +// When ignoreNotFound is true the caller signals that a NotFound response is expected (e.g. +// during a normal cascade-delete of the parent PodCliqueSet). In that case the log is emitted +// at V(1) (verbose/debug) to avoid spamming info logs at scale. Unexpected NotFound responses +// (ignoreNotFound=false) are still propagated as errors so the calling reconciler can surface them. func GetPodClique(ctx context.Context, cl client.Client, logger logr.Logger, objectKey client.ObjectKey, pclq *v1alpha1.PodClique, ignoreNotFound bool) grovectrl.ReconcileStepResult { if err := cl.Get(ctx, objectKey, pclq); err != nil { if ignoreNotFound && apierrors.IsNotFound(err) { - logger.Info("PodClique not found", "objectKey", objectKey) + logger.V(1).Info("PodClique not found (expected during cascade-delete)", "objectKey", objectKey) return grovectrl.DoNotRequeue() } return grovectrl.ReconcileWithErrors("error getting PodClique", err) diff --git a/operator/internal/controller/utils/reconciler_test.go b/operator/internal/controller/utils/reconciler_test.go index 213206b29..92b80ac81 100644 --- a/operator/internal/controller/utils/reconciler_test.go +++ b/operator/internal/controller/utils/reconciler_test.go @@ -192,6 +192,26 @@ func TestGetPodClique(t *testing.T) { } } +// TestGetPodClique_IgnoreNotFoundFalse verifies that when ignoreNotFound is false and the +// PodClique does not exist, GetPodClique propagates the error rather than returning DoNotRequeue. +// This path covers unexpected missing PodCliques (not cascade-delete) and should surface the error. +func TestGetPodClique_IgnoreNotFoundFalse(t *testing.T) { + ctx := context.Background() + logger := logr.Discard() + + scheme := runtime.NewScheme() + require.NoError(t, grovecorev1alpha1.AddToScheme(scheme)) + fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build() + + objectKey := types.NamespacedName{Name: "missing-pclq", Namespace: "default"} + pclq := &grovecorev1alpha1.PodClique{} + result := GetPodClique(ctx, fakeClient, logger, objectKey, pclq, false) + + // Must not silently swallow the error or return DoNotRequeue — the caller + // should be aware the object is missing unexpectedly. + assert.True(t, result.NeedsRequeue() || result.HasErrors(), "expected error or requeue on unexpected NotFound with ignoreNotFound=false") +} + // TestGetPodCliqueScalingGroup tests the GetPodCliqueScalingGroup function func TestGetPodCliqueScalingGroup(t *testing.T) { tests := []struct {