Skip to content

OCPBUGS-98462: add jitter to AWS endpoint service requeue delay#8996

Open
jparrill wants to merge 1 commit into
openshift:mainfrom
jparrill:OCPBUGS-98462
Open

OCPBUGS-98462: add jitter to AWS endpoint service requeue delay#8996
jparrill wants to merge 1 commit into
openshift:mainfrom
jparrill:OCPBUGS-98462

Conversation

@jparrill

@jparrill jparrill commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace fixed 20s requeue delay with 15s base + random 1-10s jitter in the AWS endpoint service controller

Fixes

Root Cause

When 14+ HostedClusters are created in parallel (as in e2e-aws-ovn), their AWS endpoint service controllers all call Route53 ChangeResourceRecordSets simultaneously. On failure (typically NLB not yet active), all controllers requeued after a fixed 20s — retrying at the exact same instant and sustaining Route53 API throttling (Throttling: Rate exceeded).

Frequency

Searched 40 builds of periodic-ci-openshift-hypershift-release-5.0-periodics-e2e-aws-ovn (29 failures total):

  • 1/29 failures (3.4%) had Route53 throttling as the root cause
  • The single affected run (2075226710403452928, Jul 9) had 4 HCs stuck with AWSEndpointAvailable=False and 9 test failures
  • Low frequency but the fix is safe, minimal, and consistent with AWS best practices for throttle mitigation

Existing throttle handling

The CPO-side awsprivatelink controller already handles throttling with a 2min backoff (throttleRequeueDelay, line 61 of control-plane-operator/controllers/awsprivatelink/awsprivatelink_controller.go). This fix targets the HO-side endpoint service controller where the fixed 20s delay caused synchronized retries across all HCs.

Changes

Before After
lbNotActiveRequeueDuration = 20s (fixed, all controllers retry simultaneously) lbNotActiveRequeueBase = 15s + rand(1-10s) jitter (16-25s range, desynchronized)
log.Info("retrying in 20s") log.Info("retrying with jitter", "requeueAfter", requeueAfter)

Test plan

  • go build passes
  • Observe e2e-aws-ovn periodic — Route53 throttling should no longer cascade across HCs

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved retry timing when an AWS load balancer isn’t active yet by replacing the fixed requeue interval with a jittered, randomized backoff to avoid repeated retries at the same cadence.
    • Adjusted retry logs and scheduling to match the new randomized delay.
  • Tests
    • Added unit coverage to verify the retry delay remains within the expected jitter-bounded range and that the reconciler uses that delay correctly.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The AWS endpoint controller replaces the fixed 20-second retry interval for inactive network load balancers with a bounded randomized delay. New base and jitter constants define the calculation, retry logs report the computed duration, and tests validate both the helper and reconciliation result bounds.

Suggested reviewers: ironcladlou, sdminonne

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding jitter to the AWS endpoint service requeue delay.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All added test titles are static strings; no dynamic values, generated IDs, dates, or other unstable data appear in titles.
Test Structure And Quality ✅ Passed No Ginkgo tests were added; the new unit test is self-contained, uses fake clients, has no cleanup/timeouts to manage, and follows existing table-driven patterns.
Topology-Aware Scheduling Compatibility ✅ Passed Only AWS endpoint-service requeue timing and tests changed; no pod scheduling, replicas, affinity, nodeSelector, or topology logic was added.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Only controller logic and a Go unit test changed; no Ginkgo e2e test, IPv4-only assumptions, or external connectivity were added.
No-Weak-Crypto ✅ Passed Changed files only add math/rand-based retry jitter; no weak ciphers, custom crypto, or secret comparisons found.
Container-Privileges ✅ Passed PR only changes controller/test Go code; the diff touches no container manifests and adds no privileged, host*, CAP_SYS_ADMIN, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed New log output only includes the retry error and delay; no passwords, tokens, PII, session IDs, or customer data were added.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@jparrill jparrill changed the title fix(OCPBUGS-98462): add jitter to AWS endpoint service requeue delay OCPBUGS-98462: add jitter to AWS endpoint service requeue delay Jul 14, 2026
@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels Jul 14, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-98462, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Summary

  • Replace fixed 20s requeue delay with 15s base + random 1-10s jitter in the AWS endpoint service controller

Fixes

Root Cause

When 14+ HostedClusters are created in parallel (as in e2e-aws-ovn), their AWS endpoint service controllers all call Route53 ChangeResourceRecordSets simultaneously. On failure (typically NLB not yet active), all controllers requeued after a fixed 20s — retrying at the exact same instant and sustaining Route53 API throttling (Throttling: Rate exceeded).

Evidence from build 2075226710403452928 (Jul 9): 4 HCs hit AWSEndpointAvailable=False with Route53 throttling, causing DNS resolution failures and node readiness timeouts. 1/40 builds affected.

Changes

Before After
RequeueAfter: 20s (fixed, all controllers retry simultaneously) RequeueAfter: 15s + rand(1-10s) (16-25s range, desynchronized)

The existing throttle-specific handler in the CPO awsprivatelink controller (2min backoff, line 537) is unchanged — this fix targets the HO-side endpoint service controller where the fixed 20s delay caused synchronized retries.

Test plan

  • go build passes
  • Observe e2e-aws-ovn periodic — Route53 throttling should no longer cascade across HCs

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci

openshift-ci Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jparrill

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci
openshift-ci Bot requested review from ironcladlou and sdminonne July 14, 2026 10:14
@openshift-ci-robot

Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-98462, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

Summary

  • Replace fixed 20s requeue delay with 15s base + random 1-10s jitter in the AWS endpoint service controller

Fixes

Root Cause

When 14+ HostedClusters are created in parallel (as in e2e-aws-ovn), their AWS endpoint service controllers all call Route53 ChangeResourceRecordSets simultaneously. On failure (typically NLB not yet active), all controllers requeued after a fixed 20s — retrying at the exact same instant and sustaining Route53 API throttling (Throttling: Rate exceeded).

Evidence from build 2075226710403452928 (Jul 9): 4 HCs hit AWSEndpointAvailable=False with Route53 throttling, causing DNS resolution failures and node readiness timeouts. 1/40 builds affected.

Changes

Before After
RequeueAfter: 20s (fixed, all controllers retry simultaneously) RequeueAfter: 15s + rand(1-10s) (16-25s range, desynchronized)

The existing throttle-specific handler in the CPO awsprivatelink controller (2min backoff, line 537) is unchanged — this fix targets the HO-side endpoint service controller where the fixed 20s delay caused synchronized retries.

Test plan

  • go build passes
  • Observe e2e-aws-ovn periodic — Route53 throttling should no longer cascade across HCs

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
  • Improved retry timing while waiting for AWS network load balancers to become active.
  • Added randomized retry delays to reduce repeated retry collisions and improve reconciliation behavior.
  • Retry logs now include the next scheduled retry duration.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release approved Indicates a PR has been approved by an approver from all required OWNERS files. area/platform/aws PR/issue for AWS (AWSPlatform) platform and removed do-not-merge/needs-area labels Jul 14, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
hypershift-operator/controllers/platform/aws/controller.go (1)

359-361: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a bounded retry-jitter test.

Please add or extend the controller tests to exercise this error path and assert that RequeueAfter remains within the documented 16–25 second range, without asserting one exact random value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hypershift-operator/controllers/platform/aws/controller.go` around lines 359
- 361, Add a controller test covering the reconciliation error path that logs
“reconciliation failed, retrying with jitter” and returns RequeueAfter. Execute
the path and assert the result stays within the documented 16–25 second
inclusive range, checking bounds rather than an exact random value; reuse
existing test fixtures and symbols for the AWS controller reconciliation flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@hypershift-operator/controllers/platform/aws/controller.go`:
- Around line 359-361: Add a controller test covering the reconciliation error
path that logs “reconciliation failed, retrying with jitter” and returns
RequeueAfter. Execute the path and assert the result stays within the documented
16–25 second inclusive range, checking bounds rather than an exact random value;
reuse existing test fixtures and symbols for the AWS controller reconciliation
flow.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: c7817516-3d1d-4792-b165-a4ef1d77f5cf

📥 Commits

Reviewing files that changed from the base of the PR and between d241190 and aa06faa.

📒 Files selected for processing (1)
  • hypershift-operator/controllers/platform/aws/controller.go

@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 44.29%. Comparing base (d241190) to head (c6add26).
⚠️ Report is 75 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8996      +/-   ##
==========================================
+ Coverage   43.80%   44.29%   +0.48%     
==========================================
  Files         772      781       +9     
  Lines       96100    98556    +2456     
==========================================
+ Hits        42097    43654    +1557     
- Misses      51084    51837     +753     
- Partials     2919     3065     +146     
Files with missing lines Coverage Δ
...ft-operator/controllers/platform/aws/controller.go 50.15% <100.00%> (+8.77%) ⬆️

... and 64 files with indirect coverage changes

Flag Coverage Δ
cmd-support 38.32% <ø> (+0.86%) ⬆️
cpo-hostedcontrolplane 46.78% <ø> (+0.88%) ⬆️
cpo-other 45.22% <ø> (+0.08%) ⬆️
hypershift-operator 54.36% <100.00%> (+0.29%) ⬆️
other 33.59% <ø> (+1.47%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jparrill

Copy link
Copy Markdown
Contributor Author

/label acknowledge-critical-fixes-only

@openshift-ci openshift-ci Bot added the acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. label Jul 14, 2026
@ironcladlou

Copy link
Copy Markdown
Contributor

Nice, thanks

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 14, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks-4-22
/test e2e-aws-4-22
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-azure-v2-self-managed
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws
/test e2e-v2-gke

@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

All three agents have completed. Now I have the complete picture. Let me compile the final report:

Test Failure Analysis Complete

Job Information

  • Prow Job: pull-ci-openshift-hypershift-main-e2e-aws / pull-ci-openshift-hypershift-main-e2e-aws-4-22 / codecov/patch
  • Build IDs: 2077041516299161600 (e2e-aws), 2077041517976883200 (e2e-aws-4-22)
  • PR: OCPBUGS-98462: add jitter to AWS endpoint service requeue delay #8996 — OCPBUGS-98462: add jitter to AWS endpoint service requeue delay
  • Changed file: hypershift-operator/controllers/platform/aws/controller.go (6 additions, 3 deletions)
  • Verdict: All three failures are unrelated to the PR's code changes

Test Failure Analysis

Error

=== e2e-aws (TestCreateCluster/Main/EnsureGlobalPullSecret) ===
failed to wait for DaemonSet kubelet-config-verifier to be ready: context deadline exceeded
  → DaemonSet stuck at 2/3 pods ready for ~20 minutes

=== e2e-aws-4-22 (TestNodePool/HostedCluster0) ===
operation error EC2: CreateVpcEndpoint, exceeded maximum number of attempts, 11,
StatusCode: 503, api error RequestLimitExceeded: Request limit exceeded.
Account 820196288204 has been throttled on ec2:CreateVpcEndpoint

=== codecov/patch ===
0.00% of diff hit (target 43.80%) — new jitter lines in Reconcile() lack unit test coverage

Summary

All three failures are infrastructure flakes or pre-existing gaps, not regressions introduced by this PR. The PR makes a minimal 3-line change adding jitter (15s base + 1–10s random) to the AWS endpoint service requeue delay in AWSEndpointServiceReconciler.Reconcile(). The e2e-aws failure is a kubelet-config-verifier DaemonSet readiness timeout on one guest cluster node (2/3 pods ready). The e2e-aws-4-22 failure is AWS API throttling (RequestLimitExceeded) on ec2:CreateVpcEndpoint due to heavy concurrent account usage. The codecov/patch failure reflects that the Reconcile() method had zero unit test coverage before this PR — a pre-existing gap, not a regression. A /retest should clear the e2e failures.

Root Cause

e2e-aws — TestCreateCluster/Main/EnsureGlobalPullSecret: The test patches the management-cluster pull secret, then creates a kubelet-config-verifier DaemonSet on the 3-node guest cluster to verify propagation. The DaemonSet got stuck at 2/3 pods ready — one node never brought its pod to ready state within the ~20-minute timeout. The other three DaemonSets (ovnkube-node, global-pull-secret-syncer, konnectivity-agent) all reached 3/3 immediately. This is a transient infrastructure issue on one specific guest cluster node (likely image pull delay or node-level resource pressure after the pull secret modification). A cascading failure then hit Check_if_the_config.json_is_correct_in_all_of_the_nodes which tried to create the same DaemonSet and got 409 AlreadyExists because cleanup didn't run after the timeout.

e2e-aws-4-22 — TestNodePool/HostedCluster0: AWS account 820196288204 was rate-limited on ec2:CreateVpcEndpoint. After 11 retry attempts, the test received HTTP 503 RequestLimitExceeded. Additional evidence of account saturation: KeyPairLimitExceeded (5000 keypairs reached) errors appeared in teardown logs. This is a pure AWS infrastructure throttling issue from too many concurrent CI jobs on the shared account. All other tests (TestCreateCluster, TestKarpenter, TestAutoscaling, etc.) passed — 555 of 557 tests succeeded.

codecov/patch: The 3 new executable lines (jitter calculation, log statement, return) sit inside the Reconcile() method's error-handling path. The existing controller_test.go (1263 lines) tests helper methods (TestReconcileAWSEndpointServiceStatus, TestDeleteAWSEndpointService, etc.) but has no test for the top-level Reconcile() method. This is pre-existing — the codecov/project check passed (43.80% overall coverage at target).

Recommendations
  1. Retest (/retest): Both e2e failures are transient infrastructure flakes unrelated to the PR. A rerun should pass.
  2. codecov/patch: This can be safely ignored or overridden — the Reconcile() method was already untested before this PR, and the codecov/project check passes. Adding a unit test for the full Reconcile() method would require mocking the entire controller-runtime reconciler, AWS EC2/ELB clients, and is disproportionate for this 3-line jitter change.
  3. Pre-existing test bug (informational): The EnsureGlobalPullSecret test has a cleanup gap — when the kubelet-config-verifier DaemonSet readiness times out, it's not deleted, causing the next subtest to fail with AlreadyExists. This is worth a separate fix but unrelated to this PR.
Evidence
Evidence Detail
PR scope Only hypershift-operator/controllers/platform/aws/controller.go — 3 lines changed (jitter to requeue delay)
e2e-aws leaf failure TestCreateCluster/Main/EnsureGlobalPullSecret/When_management-cluster_hostedCluster.Spec.PullSecret_is_updated_in-place... (1205.12s timeout)
e2e-aws error failed to wait for DaemonSet kubelet-config-verifier to be ready: context deadline exceeded (2/3 pods ready)
e2e-aws cascade Check_if_the_config.json_is_correct_in_all_of_the_nodes409 AlreadyExists (DaemonSet not cleaned up)
e2e-aws pass rate 618/623 tests passed, 30 skipped, 5 failures (all in one subtest tree)
e2e-aws-4-22 failure TestNodePool/HostedCluster0RequestLimitExceeded on ec2:CreateVpcEndpoint (HTTP 503)
e2e-aws-4-22 AWS account Account 820196288204 throttled; also hit KeyPairLimitExceeded (5000 keypairs)
e2e-aws-4-22 pass rate 555/557 tests passed, 23 skipped, 2 failures (parent + child)
codecov/patch 0.00% patch coverage — Reconcile() method has zero unit tests (pre-existing)
codecov/project Passed at 43.80% (no overall coverage regression)
Relationship to PR None — PR changes AWS endpoint service retry timing; failures are in unrelated test paths

@jparrill

Copy link
Copy Markdown
Contributor Author

/retest-required

@jparrill

Copy link
Copy Markdown
Contributor Author

E2E failure analysis

Both failures are pre-existing issues unrelated to this PR's Route53 jitter change:

e2e-aws: EnsureGlobalPullSecret propagation timeout (1205s) + DaemonSet kubelet-config-verifier stuck at 2/3 ready. The BaseSHA (a84834f) does not include #8990 (DaemonSet stale cleanup fix, merged Jul 14 15:39). The retest will pick up a newer BaseSHA that includes it. Tracked as OCPBUGS-98465 (diagnostic PR #8991 on hold).

e2e-aws-4-22: ec2:CreateVpcEndpoint RequestLimitExceeded — AWS account 820196288204 throttled on EC2 API due to 14+ parallel cluster creations. Different API from Route53 (this PR). Filing as new bug under CNTRLPLANE-3832.

@cwbotbot

Copy link
Copy Markdown

Test Results

e2e-aws

Failed Tests

Total failed tests: 7

  • TestCreateCluster
  • TestCreateCluster/Main
  • TestCreateCluster/Main/EnsureGlobalPullSecret
  • TestCreateCluster/Main/EnsureGlobalPullSecret/When_management-cluster_hostedCluster.Spec.PullSecret_is_updated_in-place_it_should_propagate_to_guest_without_rollout
  • TestCreateClusterHABreakGlassCredentials

... and 2 more failed tests

@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Jul 15, 2026
@openshift-ci

openshift-ci Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

New changes are detected. LGTM label has been removed.

@jparrill
jparrill force-pushed the OCPBUGS-98462 branch 2 times, most recently from 3717e3f to 3facf0e Compare July 15, 2026 14:04
@openshift-ci

openshift-ci Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

@jparrill: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-4-22 3c86439 link true /test e2e-aws-4-22
ci/prow/e2e-aws 3c86439 link true /test e2e-aws

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@csrwng csrwng left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean fix — jitter is the right approach for desynchronizing parallel controllers hitting the same API. One minor nit on the test structure.

min := lbNotActiveRequeueBase + 1*time.Second
max := lbNotActiveRequeueBase + time.Duration(lbNotActiveJitterMax)*time.Second

if tt.name == "When called directly it should return a delay within the jitter range" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the table-driven pattern with string-matching dispatch (if tt.name == "...") is unusual — consider splitting into two separate test functions or using a run func(...) field in the table struct so the test logic lives in the test case, not in a branch.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — replaced the string-matching dispatch with a validate func(t *testing.T, g Gomega) field in the table struct. Each test case now carries its own logic.

},
{
name: "When reconcileAWSEndpointServiceStatus fails it should requeue with jitter",
validate: func(t *testing.T, g Gomega) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that you have these as separate validation functions, it's very clear that these are completely separate tests. One is testing the lbNotActiveRequeueDelay() function, the other is testing the Reconcile function. They should be separate test functions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — split into two separate test functions: TestLbNotActiveRequeueDelay (tests the function directly) and TestReconcileRequeuesWithJitter (tests the Reconcile path). No more table struct.

@celebdor celebdor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some gomega usage suggestions

Comment on lines +1275 to +1276
g.Expect(d).To(BeNumerically(">=", min))
g.Expect(d).To(BeNumerically("<=", max))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
g.Expect(d).To(BeNumerically(">=", min))
g.Expect(d).To(BeNumerically("<=", max))
g.Expect(d).To(And(
BeNumerically(">=", min),
BeNumerically("<=", max),
), "iteration %d returned %s", i, d)

I don't think we need to do two assertions here. A single gomega expression should do (I added also a suggestion on the iterations for debuggability, but feel free to leave that part out

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — combined into a single And() matcher with iteration context for debugging.


g.Expect(err).ToNot(HaveOccurred())
g.Expect(result.RequeueAfter).To(BeNumerically(">=", min))
g.Expect(result.RequeueAfter).To(BeNumerically("<=", max))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
g.Expect(result.RequeueAfter).To(BeNumerically("<=", max))
g.Expect(result.RequeueAfter).To(And(
BeNumerically(">=", min),
BeNumerically("<=", max),
))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — combined into And().

NamespacedName: client.ObjectKeyFromObject(awsES),
})

g.Expect(err).ToNot(HaveOccurred())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
g.Expect(err).ToNot(HaveOccurred())
g.Expect(err).NotTo(HaveOccurred())

We use NotTo instead of ToNot in the rest of the file. Let's keep it consistent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — changed to NotTo for consistency.

Replace the fixed 20s requeue delay in AWSEndpointServiceReconciler with
a 15s base + random 1-10s jitter. When 14+ HostedClusters are created in
parallel, all controllers retry Route53 ChangeResourceRecordSets at the
same interval, causing API throttling cascades. The jitter desynchronizes
retries across controllers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. approved Indicates a PR has been approved by an approver from all required OWNERS files. area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/aws PR/issue for AWS (AWSPlatform) platform jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants