diff --git a/operator/internal/controller/podcliqueset/components/podcliquesetreplica/gangterminate.go b/operator/internal/controller/podcliqueset/components/podcliquesetreplica/gangterminate.go index 23379906b..7dafd2f99 100644 --- a/operator/internal/controller/podcliqueset/components/podcliquesetreplica/gangterminate.go +++ b/operator/internal/controller/podcliqueset/components/podcliquesetreplica/gangterminate.go @@ -81,7 +81,7 @@ func (r _resource) getPCSReplicaDeletionWork(ctx context.Context, logger logr.Lo if err != nil { return nil, err } - breachedPCLQNames, minPCLQWaitFor, skipPCSReplicaIndex, err := r.getMinAvailableBreachedPCLQsNotInPCSG(ctx, pcs, pcsReplicaIndex, now) + breachedPCLQNames, minPCLQWaitFor, skipPCSReplicaIndex, err := r.getMinAvailableBreachedPCLQsNotInPCSG(ctx, logger, pcs, pcsReplicaIndex, now) if err != nil { return nil, err } @@ -124,7 +124,7 @@ func (r _resource) getMinAvailableBreachedPCSGs(ctx context.Context, pcsObjKey c } // getMinAvailableBreachedPCLQsNotInPCSG retrieves standalone PCLQs that have breached MinAvailable. -func (r _resource) getMinAvailableBreachedPCLQsNotInPCSG(ctx context.Context, pcs *grovecorev1alpha1.PodCliqueSet, pcsReplicaIndex int, since time.Time) (breachedPCLQNames []string, minWaitFor time.Duration, skipPCSReplica bool, err error) { +func (r _resource) getMinAvailableBreachedPCLQsNotInPCSG(ctx context.Context, logger logr.Logger, pcs *grovecorev1alpha1.PodCliqueSet, pcsReplicaIndex int, since time.Time) (breachedPCLQNames []string, minWaitFor time.Duration, skipPCSReplica bool, err error) { pclqFQNsNotInPCSG := make([]string, 0, len(pcs.Spec.Template.Cliques)) for _, pclqTemplateSpec := range pcs.Spec.Template.Cliques { if !isPCLQInPCSG(pclqTemplateSpec.Name, pcs.Spec.Template.PodCliqueScalingGroupConfigs) { @@ -140,6 +140,7 @@ func (r _resource) getMinAvailableBreachedPCLQsNotInPCSG(ctx context.Context, pc return } if len(notFoundPCLQFQNs) > 0 { + logger.Info("PodClique(s) expected by PodCliqueSet replica not yet present; skipping MinAvailable evaluation for this replica index", "pcsName", pcs.Name, "replicaIndex", pcsReplicaIndex, "missingPodCliques", notFoundPCLQFQNs) skipPCSReplica = true return } diff --git a/operator/internal/controller/utils/reconciler.go b/operator/internal/controller/utils/reconciler.go index 47921ea1f..787a94a94 100644 --- a/operator/internal/controller/utils/reconciler.go +++ b/operator/internal/controller/utils/reconciler.go @@ -49,7 +49,7 @@ func GetPodCliqueSet(ctx context.Context, cl client.Client, logger logr.Logger, 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", "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..53676a0fa 100644 --- a/operator/internal/controller/utils/reconciler_test.go +++ b/operator/internal/controller/utils/reconciler_test.go @@ -153,15 +153,15 @@ func TestGetPodClique(t *testing.T) { expectedNeedsRequeue: false, }, { - // Tests when PodClique is not found - name: "not_found", + // Tests when PodClique is not found and ignoreNotFound is true — logs at debug level and returns DoNotRequeue + name: "not_found_ignore", namespacedName: types.NamespacedName{ Name: "test-pclq", Namespace: "default", }, existingPCLQ: nil, notFound: true, - expectedNeedsRequeue: false, // When ignoreNotFound is true and not found, returns DoNotRequeue() + expectedNeedsRequeue: false, }, } @@ -192,6 +192,22 @@ func TestGetPodClique(t *testing.T) { } } +// TestGetPodCliqueIgnoreNotFoundFalse tests that GetPodClique propagates the error when ignoreNotFound is false. +func TestGetPodCliqueIgnoreNotFoundFalse(t *testing.T) { + ctx := context.Background() + logger := logr.Discard() + + scheme := runtime.NewScheme() + require.NoError(t, grovecorev1alpha1.AddToScheme(scheme)) + fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build() + + pclq := &grovecorev1alpha1.PodClique{} + result := GetPodClique(ctx, fakeClient, logger, types.NamespacedName{Name: "missing", Namespace: "default"}, pclq, false) + + assert.True(t, result.NeedsRequeue(), "should requeue on error when ignoreNotFound is false") + assert.NotEmpty(t, result.GetErrors(), "should carry error when ignoreNotFound is false") +} + // TestGetPodCliqueScalingGroup tests the GetPodCliqueScalingGroup function func TestGetPodCliqueScalingGroup(t *testing.T) { tests := []struct {