Skip to content

[tests] Stabilize E2E kubernetes tests - #2262

Merged
Kirill Ilin (sircthulhu) merged 20 commits into
mainfrom
fix/e2e-kubernetes-stability
Mar 26, 2026
Merged

Kirill Ilin (sircthulhu) merged 20 commits into
mainfrom
fix/e2e-kubernetes-stability

Conversation

@lexfrei

@lexfrei Aleksei Sviridkin (lexfrei) commented Mar 23, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does

Reduces flakiness in E2E tests by addressing the most common failure modes.

Kubernetes tenant tests (run-kubernetes.sh)

  • Increase node Ready timeout from 2m to 5m — CI runners are shared and resource-constrained
  • Fail fast when nodes are not Ready — saves ~7 minutes per failed attempt by not running LB/NFS tests that will also fail
  • Delete stale Kubernetes resources at test start — retries provision from scratch instead of patching stuck state
  • Wait for port-forward to be ready before using it (fixes race condition)
  • Reduce version check polling interval from 5s to 1s

All app tests (postgres, redis, kafka, clickhouse, mariadb, mongodb, qdrant, foundationdb, openbao, vminstance, bucket)

  • Add pre-cleanup of stale resources from previous failed retries so each attempt starts clean

Test runner (cozytest.sh)

  • Clean up temp directory on test failure (was only cleaned on success, leaking /tmp dirs)

Release note

NONE

Summary by CodeRabbit

  • Tests
    • Improved e2e robustness by deleting stale resources before creation (ignore-if-missing, bounded time) and killing leftover port-forwards.
    • Added an exit cleanup to consistently remove temporary artifacts and teardown port-forwards on any exit.
    • Added readiness polling for forwarded endpoints (curl with timeout); made API/version retries more responsive.
    • Extended node readiness wait (2m → 5m), dump debug info and fail fast if unready.
    • Made load‑balancer reachability checking explicit and more reliable.

Three changes to reduce flakiness in kubernetes E2E tests:

- Increase node Ready timeout from 2m to 5m to accommodate
  resource-constrained CI runners
- Fail fast when nodes are not Ready instead of continuing to
  LB/NFS tests that will also fail, saving ~7 minutes per attempt
- Delete stale Kubernetes resources at test start to ensure
  retries provision from scratch instead of patching stuck state

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@coderabbitai

coderabbitai Bot commented Mar 23, 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
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[tests] Stabilize E2E kubernetes tests' clearly and specifically summarizes the main change: improving the stability of E2E tests, which is confirmed by the substantial changes across test infrastructure files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/e2e-kubernetes-stability

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on improving the reliability of the Kubernetes E2E tests by addressing common timeout issues and ensuring a clean testing environment. The changes include increasing the node Ready timeout, implementing a fast-fail mechanism, and cleaning up stale resources before each test run. These adjustments aim to reduce flakiness and improve the overall efficiency of the testing process.

Highlights

  • Test Stabilization: This PR aims to reduce flakiness in the tenant Kubernetes E2E tests by addressing issues related to nodes not becoming Ready within the allocated timeout.
  • Timeout Increase: The node Ready timeout has been increased from 2 minutes to 5 minutes to accommodate resource-constrained CI runners.
  • Fast Failure: The tests now fail fast if nodes are not Ready, preventing unnecessary execution of LB/NFS tests and saving time.
  • Resource Cleanup: Stale Kubernetes resources are deleted at the start of each test run to ensure provisioning from a clean state.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
hack/e2e-apps/run-kubernetes.sh (1)

78-79: ⚠️ Potential issue | 🟡 Minor

Update the timeout comment to match the command.

Line 78 says “2 minutes”, but Line 79 now uses --timeout=5m. Please align the comment to avoid confusion during CI triage.

Suggested diff
-  # Wait for Kubernetes resources to be ready (timeout after 2 minutes)
+  # Wait for Kubernetes resources to be ready (timeout after 5 minutes)
   kubectl wait tcp -n tenant-test kubernetes-${test_name} --timeout=5m --for=jsonpath='{.status.kubernetesResources.version.status}'=Ready
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hack/e2e-apps/run-kubernetes.sh` around lines 78 - 79, The comment above the
kubectl wait command is inconsistent: update the comment "Wait for Kubernetes
resources to be ready (timeout after 2 minutes)" to match the actual command
using --timeout=5m (e.g., "timeout after 5 minutes") so the comment aligns with
the kubectl wait invocation that targets kubernetes-${test_name}.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@hack/e2e-apps/run-kubernetes.sh`:
- Around line 78-79: The comment above the kubectl wait command is inconsistent:
update the comment "Wait for Kubernetes resources to be ready (timeout after 2
minutes)" to match the actual command using --timeout=5m (e.g., "timeout after 5
minutes") so the comment aligns with the kubectl wait invocation that targets
kubernetes-${test_name}.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7e7463c9-5f9d-460b-9d04-f67e98a6ae87

📥 Commits

Reviewing files that changed from the base of the PR and between 3119be1 and 64b370b.

📒 Files selected for processing (1)
  • hack/e2e-apps/run-kubernetes.sh

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request aims to stabilize E2E Kubernetes tests by increasing timeouts, failing fast on node readiness failures, and cleaning up stale resources. The changes are well-aligned with these goals. I have one suggestion regarding the resource cleanup logic to make it more robust by not masking potential failures.

Comment thread hack/e2e-apps/run-kubernetes.sh Outdated
Comment on lines +8 to +9
kubectl delete kuberneteses.apps.cozystack.io "${test_name}" \
-n tenant-test --ignore-not-found --timeout=2m || true

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.

medium

The use of || true will suppress any non-zero exit code from the kubectl delete command, causing the script to continue even if the deletion fails for reasons other than the resource not being found (e.g., a timeout). This could lead to the test proceeding with stale resources, potentially causing issues later on and masking the root cause of the failure. Since --ignore-not-found already handles the case where the resource doesn't exist, removing || true will ensure the test fails immediately and clearly if the cleanup step is unsuccessful for any other reason.

Suggested change
kubectl delete kuberneteses.apps.cozystack.io "${test_name}" \
-n tenant-test --ignore-not-found --timeout=2m || true
kubectl delete kuberneteses.apps.cozystack.io "${test_name}" \
-n tenant-test --ignore-not-found --timeout=2m

- Add pre-cleanup of stale resources to all app E2E tests so
  retries start fresh instead of patching stuck state
- Wait for port-forward to be ready before using it in
  kubernetes tests (fixes race condition)
- Reduce version check sleep from 5s to 1s for faster retries
- Clean up temp directory on test failure in cozytest.sh

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@dosubot dosubot Bot added size/S This PR changes 10-29 lines, ignoring generated files and removed size/XS This PR changes 0-9 lines, ignoring generated files labels Mar 23, 2026
- Add EXIT trap in run-kubernetes.sh to clean up port-forward
  process and tenantkubeconfig file on any exit path
- Fix LoadBalancer retry loop: success on attempt 20 was falsely
  reported as failure due to $i -eq 20 check after break
- Kill stale port-forward in bucket.bats before retry

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@dosubot dosubot Bot added size/M This PR changes 30-99 lines, ignoring generated files and removed size/S This PR changes 10-29 lines, ignoring generated files labels Mar 23, 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@hack/e2e-apps/run-kubernetes.sh`:
- Around line 7-8: The EXIT trap captures the literal ${port} and ${test_name}
at execution time because it’s wrapped in single quotes; update the trap in
run_kubernetes_test to use double quotes so ${port} and ${test_name} are
expanded when the trap is defined (e.g. change trap '...' EXIT to trap "pkill -f
\"port-forward.*${port}:\" 2>/dev/null || true; rm -f
\"tenantkubeconfig-${test_name}\"" EXIT) so the port and test_name values are
stored for cleanup after the function returns.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e9e0b24e-18b1-4681-b04d-3fdf8bdee1fb

📥 Commits

Reviewing files that changed from the base of the PR and between 18961de and e3acb3a.

📒 Files selected for processing (2)
  • hack/e2e-apps/bucket.bats
  • hack/e2e-apps/run-kubernetes.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • hack/e2e-apps/bucket.bats

Comment thread hack/e2e-apps/run-kubernetes.sh Outdated
…gnore-not-found

- Add pre-cleanup for VMInstance in second vminstance.bats test
- Fix indentation of LB_ADDR block in run-kubernetes.sh
- Add --ignore-not-found to final Kubernetes resource cleanup

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
Expand the EXIT trap in run_kubernetes_test to also delete the
Kubernetes tenant resource. Previously, early exit paths (exit 1
on node readiness failure, LB failure, etc.) would skip the final
kubectl delete, leaving the resource behind.

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
Use a _k8s_test_cleanup helper called at every exit point
instead of a process-scoped EXIT trap. This avoids any
potential trap scope issues and makes cleanup behavior
explicit and visible at each error path.

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
The explicit _k8s_test_cleanup calls cover known error paths, but
set -e can terminate the script at any kubectl/wait command. Add
an EXIT trap to catch these unexpected exits. The function runs
in a cozytest.sh subshell, so the trap is scoped and does not
affect parent traps. Removed 2>/dev/null from kubectl delete in
cleanup to preserve useful error output.

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
On resource-constrained CI runners, HelmReleases may take close
to 15 minutes to reconcile, leaving very little time for CAPI
deployments to start and become available. Increase timeouts:
- CAPI deployment discovery: 60s -> 180s
- CAPI deployment availability: 1m -> 5m

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
Without explicit timeouts, stuck jobs use the GitHub Actions
default of 360 minutes (6 hours). This blocks the concurrency
group and prevents new runs from starting.

Set reasonable limits:
- Build: 30 minutes (normally ~5 min)
- E2E: 120 minutes (normally ~60 min)

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@lexfrei Aleksei Sviridkin (lexfrei) added the debug Debugging in progress label Mar 23, 2026
Signed-off-by: Aleksei Sviridkin <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@lexfrei Aleksei Sviridkin (lexfrei) removed the debug Debugging in progress label Mar 23, 2026
@lexfrei
Aleksei Sviridkin (lexfrei) marked this pull request as draft March 23, 2026 22:29
- Increase NFS PVC Bound timeout from 2m to 5m — RWX via kubevirt
  CSI provisions an NFS server pod which takes time
- Add pod describe and events dump when NFS test pod fails to
  complete, making the root cause visible in CI logs

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
Root cause of NFS test failures: port-forward had `timeout 500s`
(8.3 minutes), but tests after it take up to 26 minutes (node
join 8m + node Ready 5m + LB test 2.5m + NFS 10m). Port-forward
was guaranteed to die mid-test.

Remove the timeout entirely. Cleanup is already handled by:
- EXIT trap (_k8s_test_cleanup does pkill port-forward)
- Explicit cleanup at every exit point
- Job-level timeout-minutes: 120 as backstop

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@lexfrei Aleksei Sviridkin (lexfrei) added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress label Mar 24, 2026
Signed-off-by: Aleksei Sviridkin <[email protected]>
The previous changes increased worst-case E2E time by ~60 minutes
due to blocking cleanup (--timeout=2m × multiple calls) and
generous timeouts on retry.

Changes:
- Use --wait=false in _k8s_test_cleanup (non-blocking fire-and-forget)
- Pre-cleanup: delete --wait=false + wait --for=delete (only blocks once)
- Node Ready timeout: 5m -> 3m (was 2m originally)
- NFS PVC timeout: 5m -> 3m (was 2m originally)
- CAPI discovery: 180s -> 120s, availability: 5m -> 2m (was 1m originally)

Estimated savings: ~40 minutes on worst-case retry path.

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
Root cause: EXIT trap called _k8s_test_cleanup after subshell exit,
but variables ${port} and ${test_name} were not available in that
context. set -u caught the unset variable and exited with error,
marking a successful test as failed. This caused every kubernetes
test to "fail" on attempt 1, then retry 2 more times with real
failures (NFS PVC timeout because the cluster was being deleted).

Fix: remove trap and cleanup function entirely. Pre-cleanup at
test start handles stale resources. Inline cleanup at test end
handles normal path. On failure, resources are cleaned up by
pre-cleanup on the next retry.

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@lexfrei
Aleksei Sviridkin (lexfrei) marked this pull request as ready for review March 25, 2026 08:12
@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Mar 26, 2026
@lexfrei Aleksei Sviridkin (lexfrei) removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress label Mar 26, 2026
@sircthulhu
Kirill Ilin (sircthulhu) merged commit dfe16ed into main Mar 26, 2026
9 checks passed
@sircthulhu
Kirill Ilin (sircthulhu) deleted the fix/e2e-kubernetes-stability branch March 26, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer size/M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants