Skip to content

Adding E2E and Integration Tests - #25

Open
shekhar316 wants to merge 1 commit into
kruize:mvp_demofrom
shekhar316:integrationTestOptimizer
Open

Adding E2E and Integration Tests#25
shekhar316 wants to merge 1 commit into
kruize:mvp_demofrom
shekhar316:integrationTestOptimizer

Conversation

@shekhar316

@shekhar316 shekhar316 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Add a self-contained end-to-end test framework for Kruize Optimizer, including deployment orchestration and comprehensive workflow and webhook tests.

New Features:

  • Introduce a Python-based E2E test runner that provisions clusters, deploys monitoring, workloads, Kruize, and optimizer, then executes pytest suites and generates HTML reports.
  • Add complete workflow integration tests that validate optimizer pod/service health, profile installation, bulk job execution, webhooks, and health endpoints via live APIs and logs.
  • Provide negative webhook test coverage to ensure robust error handling for malformed and invalid payloads against the optimizer webhook endpoints.

Summary by Sourcery

Introduce a Python-based end-to-end testing framework that provisions the Kruize environment, deploys benchmarks and optimizer components, and validates their health and API behavior against a running cluster.

New Features:

  • Add a session-scoped pytest-based E2E harness that orchestrates cluster setup, Kruize and optimizer deployment, port-forwarding, and teardown via reusable fixtures and CLI options.
  • Introduce utility modules for Kubernetes interactions, Git/Process management, file/YAML patching, HTTP access to Kruize APIs, and benchmark/Prometheus setup to mirror existing demo flows.
  • Add initial E2E smoke and API tests that verify Kruize and optimizer pod health, required profiles and datasources, and auto-created sysbench experiments via live API calls.

Enhancements:

  • Document the new E2E framework usage, configuration, and layout in a dedicated README under tests/e2e.
  • Standardize pytest configuration and markers for E2E, smoke, API, and cluster/install-mode specific test selection.

Tests:

  • Add pytest suites covering Kruize and optimizer pod readiness plus Kruize API validation for metric/metadata profiles, datasources, and optimizer-created experiments.

Signed-off-by: SHEKHAR SAXENA <shekhar.saxena@ibm.com>
@sourcery-ai

sourcery-ai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduce a Python-based pytest E2E framework for kruize-optimizer that orchestrates cluster setup/teardown, installs Kruize, Prometheus, benchmarks, and the optimizer, then validates pod health and core Kruize APIs via Kubernetes and HTTP clients.

File-Level Changes

Change Details Files
Add pytest-based E2E harness that orchestrates full environment lifecycle (cluster, repos, Kruize, optimizer, benchmarks) via fixtures.
  • Define session-scoped pytest fixtures to build a Config from CLI options, create working directories, initialize kubectl and Kubernetes clients, and expose Kruize URL/client to tests
  • Implement a session-scoped setup/teardown fixture that mirrors optimizer_demo.sh: optional terminate-only mode, cluster creation/verification, repo cloning, Prometheus install, benchmark deployment/labeling, Kruize patch/install, optimizer install, port-forwarding, wait-for-experiments, and cleanup
  • Add rich CLI options (cluster type, install mode, env setup, custom images, working dir, wait duration, skip setup/teardown, terminate, verbose-output) and logging configuration with per-run log files and optional console verbosity
tests/e2e/conftest.py
tests/e2e/pytest.ini
tests/e2e/config/__init__.py
tests/e2e/config/settings.py
tests/e2e/README.md
tests/e2e/requirements.txt
Introduce reusable utilities for Kubernetes, HTTP, Git, file manipulation, process execution, waiting, and port-forwarding to replace bash/sed/awk/grep usage.
  • Wrap kubectl/oc invocations in a KubectlClient with helpers for pods, deployments, labels, namespaces, kustomize apply/delete, and basic cluster-info checks
  • Add KruizeAPIClient (requests-based) for list* API calls and health checking, and generic subprocess helpers for commands/scripts and port killing
  • Provide Python implementations for common file/YAML mutations (regex replacement, YAML patching, version extraction, image updates, CR section removal) and Git clone/checkout/delete with SSH/HTTPS fallback
  • Add generic wait utilities for polling pod status and arbitrary conditions plus progress-sleep helpers, and subprocess-based port-forward lifecycle management
tests/e2e/utils/kubectl.py
tests/e2e/utils/http_client.py
tests/e2e/utils/process.py
tests/e2e/utils/file_ops.py
tests/e2e/utils/wait.py
tests/e2e/utils/git_ops.py
tests/e2e/setup/port_forward.py
Implement setup modules to install/uninstall Prometheus, Kruize, kruize-optimizer, benchmarks, and manage clusters/repos, including pre-test and full cleanup flows.
  • Add cluster helpers to validate/access clusters, manage kind lifecycle, and check OpenShift availability
  • Implement Prometheus install and kube-state-metrics enablement via existing autotune scripts, keyed by cluster type
  • Implement Kruize manifest-mode install/uninstall using autotune deploy.sh, including local-mode patching and version-derived image selection
  • Implement kruize-optimizer install/uninstall via cloned repo kustomize overlays, with optional image override and readiness wait
  • Add benchmark installers/uninstallers for sysbench and TechEmpower (TFB), including labeling helpers for autotune integration
  • Add repo cloning/deletion helpers for autotune, benchmarks, kruize-operator, and kruize-optimizer, and cleanup routines that coordinate benchmark removal, Kruize/optimizer teardown, operator cleanup stub, namespace deletion, port-forward kills, kind delete, and repo cleanup
  • Stub out operator-mode setup/cleanup with clear TODOs
tests/e2e/setup/cluster.py
tests/e2e/setup/prometheus.py
tests/e2e/setup/kruize.py
tests/e2e/setup/optimizer.py
tests/e2e/setup/benchmarks.py
tests/e2e/setup/repos.py
tests/e2e/setup/cleanup.py
tests/e2e/setup/operator.py
tests/e2e/setup/__init__.py
Add initial E2E test suite that validates Kruize and optimizer pod health plus key Kruize API surface and optimizer-created experiments.
  • Add smoke tests that verify Kruize and kruize-optimizer pods exist in the target namespace, are Running, and have all containers ready
  • Add API tests that assert presence of required metric and metadata profiles, correct datasource configuration per cluster type, and auto-created sysbench experiments referencing the configured app namespace
tests/e2e/tests/test_kruize_pod.py
tests/e2e/tests/test_optimizer_pod.py
tests/e2e/tests/test_kruize_api.py
tests/e2e/tests/__init__.py
Document and package the E2E framework for standalone use with virtualenv and pytest markers.
  • Add README describing framework goals, setup, CLI options, execution modes, test flow, directory layout, troubleshooting, and extension guidelines
  • Specify minimal Python dependencies for running the framework and ignore generated artifacts via a local .gitignore placeholder
tests/e2e/README.md
tests/e2e/requirements.txt
tests/e2e/.gitignore

Possibly linked issues

  • #(unknown): The PR implements and extends the requested optimizer E2E test by adding a complete E2E framework and tests.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The cluster-type option accepts minikube, but several code paths (e.g., kruize_local_patch, optimizer install/overlays, port forwarding, kruize_url) either treat only kind/openshift or assume kind, so it would be good to either fully implement minikube handling or explicitly reject it.
  • The kruize_client fixture is defined both in conftest.py and test_kruize_api.py, which is redundant and could lead to confusion; consider keeping a single shared fixture in conftest.py.
  • Port-forward subprocesses are only cleaned up in normal teardown, so it would help to add more defensive cleanup (e.g., finalizers or signal/KeyboardInterrupt handling) to avoid leaving orphaned port-forward processes if pytest exits early.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `cluster-type` option accepts `minikube`, but several code paths (e.g., `kruize_local_patch`, optimizer install/overlays, port forwarding, kruize_url) either treat only `kind`/`openshift` or assume `kind`, so it would be good to either fully implement minikube handling or explicitly reject it.
- The `kruize_client` fixture is defined both in `conftest.py` and `test_kruize_api.py`, which is redundant and could lead to confusion; consider keeping a single shared fixture in `conftest.py`.
- Port-forward subprocesses are only cleaned up in normal teardown, so it would help to add more defensive cleanup (e.g., finalizers or signal/KeyboardInterrupt handling) to avoid leaving orphaned port-forward processes if pytest exits early.

## Individual Comments

### Comment 1
<location path="tests/e2e/tests/test_kruize_api.py" line_range="16" />
<code_context>
+
+@pytest.mark.e2e
+@pytest.mark.api
+class TestKruizeAPI:
+    """Test Kruize API endpoints."""
+
</code_context>
<issue_to_address>
**issue (testing):** Add E2E coverage for optimizer webhooks and error handling as described in the PR

This file only exercises the list* endpoints and checks for sysbench experiments, but the PR description calls for end-to-end coverage of optimizer webhooks and their error handling. Please extend the E2E suite to cover:

- Happy-path webhook calls with valid payloads, asserting expected status codes and side effects.
- Negative cases (malformed JSON, missing fields, invalid values, unsupported operations) with precise status codes and error messages.
- Optionally, idempotency / duplicate-submission behavior if that’s part of the contract.

That will better validate webhook-driven workflows rather than just API reachability.
</issue_to_address>

### Comment 2
<location path="tests/e2e/tests/test_kruize_api.py" line_range="79-88" />
<code_context>
+    def test_sysbench_experiment_present(self, kruize_client, config):
</code_context>
<issue_to_address>
**suggestion (testing):** Strengthen sysbench experiment assertions to avoid brittle assumptions and make failures more informative

This test usefully checks that a sysbench experiment is created, but it assumes `kubernetes_objects` is non-empty and only inspects the first element. To make it more robust and avoid IndexError or misleading passes, you could:

- Assert that `sysbench_exp['kubernetes_objects']` is a non-empty list before indexing.
- Select the sysbench workload explicitly (e.g., `next(obj for obj in sysbench_exp['kubernetes_objects'] if obj['name'] == 'sysbench')`) and assert namespace/container on that object.
- Optionally assert other key fields (e.g., `type == 'deployment'`, container name, cluster/datasource consistency) so the test catches regressions in experiment construction, not just presence.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.


@pytest.mark.e2e
@pytest.mark.api
class TestKruizeAPI:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (testing): Add E2E coverage for optimizer webhooks and error handling as described in the PR

This file only exercises the list* endpoints and checks for sysbench experiments, but the PR description calls for end-to-end coverage of optimizer webhooks and their error handling. Please extend the E2E suite to cover:

  • Happy-path webhook calls with valid payloads, asserting expected status codes and side effects.
  • Negative cases (malformed JSON, missing fields, invalid values, unsupported operations) with precise status codes and error messages.
  • Optionally, idempotency / duplicate-submission behavior if that’s part of the contract.

That will better validate webhook-driven workflows rather than just API reachability.

Comment on lines +79 to +88
def test_sysbench_experiment_present(self, kruize_client, config):
"""Test that sysbench experiment was auto-created by optimizer.

After the optimizer starts and waits for OPTIMIZER_WAIT_DURATION,
it should have auto-created experiments for labeled workloads.
"""
experiments = kruize_client.list_experiments()

assert isinstance(experiments, list), "listExperiments should return a list"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (testing): Strengthen sysbench experiment assertions to avoid brittle assumptions and make failures more informative

This test usefully checks that a sysbench experiment is created, but it assumes kubernetes_objects is non-empty and only inspects the first element. To make it more robust and avoid IndexError or misleading passes, you could:

  • Assert that sysbench_exp['kubernetes_objects'] is a non-empty list before indexing.
  • Select the sysbench workload explicitly (e.g., next(obj for obj in sysbench_exp['kubernetes_objects'] if obj['name'] == 'sysbench')) and assert namespace/container on that object.
  • Optionally assert other key fields (e.g., type == 'deployment', container name, cluster/datasource consistency) so the test catches regressions in experiment construction, not just presence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant