feat(e2e): performance harness with incremental checkpoints - #212
feat(e2e): performance harness with incremental checkpoints#212squizzi wants to merge 5 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository YAML (base), Central YAML (inherited) Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
e174d67 to
65f52c7
Compare
Amber reviewStatus: In progress Amber started a review of commit 65f52c7 at 2026-08-27T18:46:49Z. |
818056e to
89739c3
Compare
Amber reviewStatus: Complete VerdictCOMMENT (approve-with-nits). This is a well-structured, well-tested local/manual performance harness plus a partial OpenShift e2e driver and an I reviewed against Findings
Cross-PR coordinationTwo open pull requests require a maintainer decision or a defined merge order relative to this one:
Findings Summary (ordered by severity, highest first)
Convention Checklist
|
jsell-rh
left a comment
There was a problem hiding this comment.
Verdict
COMMENT (approve-with-nits). This is a well-structured, well-tested local/manual performance harness plus a partial OpenShift e2e driver and an E2E_MODE=short|long split; there is no production Go code, long remains the default so existing CI is untouched, and both cluster-free unit suites (tests/e2e/perf/lib_test.sh, tests/e2e/openshift_driver_test.sh) pass locally. My findings are all Minor (worker credential handling, a small JSON-schema default inconsistency, and nondeterministic seed selection); none block merge, but a couple of cross-PR coordination points below need a maintainer decision.
I reviewed against CLAUDE.md, security.spec.md, control-plane/conventions.spec.md, and the review checklists. I paid particular attention to Test Diff Scrutiny: the pre-existing assertions in tests/e2e/e2e-openshell.sh are gated behind if e2e_step long, and because E2E_MODE defaults to long, every previously-unconditional assertion still runs in the default/CI path — no guarantee is silently removed. The CA-extraction assertion that changed for the openshift branch is a new-driver code path, not a weakened contract for the existing kind path.
Findings
-
[Minor] Credentials spliced into
bash -cworker command strings (argv exposure).
Intests/e2e/e2e-performance.sh, both the scale-up workers (export E2E_OIDC_PASSWORD="'"${E2E_OIDC_PASSWORD}"'"and friends) and the teardown workers build abash -c '...'string with the secret values interpolated as literals. Those values then appear in the child process argv (visible viaps//proc/<pid>/cmdline) and the single-quote splice breaks on any value containing a quote or shell metacharacter. These are dev/test credentials so severity is Minor, but the safer pattern is toexportthe variables in the parent shell and let the backgrounded subshell inherit them — which the code already relies on forOPENSHIFT_NAMESPACE/E2E_HS_NAMESPACE. That would also remove the current asymmetry where OIDC vars are forwarded explicitly butOPENSHIFT_NAMESPACE(needed by the openshift driver'sacquire_oidc_token) is only inherited. Confidence: High. -
[Minor]
perf_results_initdefault latency objects omit theavgkey.
tests/e2e/perf/lib.sh:404-405initializePERF_RES_CREATE_JSON/PERF_RES_TTR_JSONto{"p50": null, ...}withoutavg, whereas the module-level defaults (lines 283-284), the documented schema, and completed-run writes all includeavg. A run that is interrupted before scale-up metrics are computed therefore writes a history file whosetime_to_running_secondsobject has noavg. This happens to render as-(matching the spec's "Partial Run Shows Dashes" scenario, so it is harmless in practice), but the two init strings should include"avg": nullfor schema consistency. Confidence: High. -
[Minor] Nondeterministic seed selection.
e2e_discover_seed_ids/e2e_json_first_id(tests/e2e/lib.sh) bind to the first fleet/cluster/release returned by the API. That is correct for the single-seed dev/CI environment the harness targets, but on any environment with more than one fleet/cluster/release the harness silently binds to an arbitrary one determined by API ordering. Consider selecting by a known name or documenting the single-seed assumption at the discovery call site. Confidence: Medium.
Cross-PR coordination
Two open pull requests require a maintainer decision or a defined merge order relative to this one:
-
#194 (adopt upstream OpenShell Helm chart for gateway deployments) changes the gateway deployment mechanism and renames in-namespace gateway resources (e.g.
openshell-ca→openshell-gateway-ca,openshell-server→openshell-gateway-server) while editing the same gateway-verification region oftests/e2e/e2e-openshell.shthat this PR reworks into short/long steps. This PR's new OpenShift driver (discover_gateway_endpoint,wait_for_gateway_route) and the performance harness readiness checks assume the current provisioning path and resource names. The two make incompatible assumptions about how a gateway is deployed and what its in-namespace objects are called; whichever merges second must reconcile the resource names and re-validate the harness/driver readiness probes against the Helm-based deployment. Both PRs also rewrite the sharedskills/RECONCILE.mdcheckpoint state, so the coverage/gap tables will need to be reconciled rather than blindly merged. A merge-order decision is needed. -
#200 (define control plane reconciliation contract) revises the gateway-deletion and managed-namespace-GC contract in the same
specs/platform/e2e-testing.spec.md, restating deletion as finalizer-driven cleanup. This PR adds new normative scenarios and a short-mode "throwaway gateway" GC test premised on the delete-driven GC semantics (accepts204/404and polls the namespace to disappearance). The two edits describe the same behavior from different angles; maintainers should confirm which deletion/GC wording is authoritative and align this PR's new short-mode GC assertions with #200's finalization model, deciding the merge order accordingly.
Findings Summary (ordered by severity, highest first)
- [Minor] Credentials interpolated into
bash -cworker argv - Security (tests/e2e/e2e-performance.sh) - [Minor]
perf_results_initdefault latency objects omitavg- Spec/Schema Consistency (tests/e2e/perf/lib.sh:404-405) - [Minor] Nondeterministic seed fleet/cluster/release selection - Robustness (
tests/e2e/lib.sh)
Convention Checklist
| Convention | Result |
|---|---|
| Conventional commit messages | Pass |
Input validated (E2E_MODE validated, fails fast) |
Pass |
| Reconcile / reuse-or-create pattern (not create-or-skip) | Pass |
Test Diff Scrutiny (default long preserves existing assertions) |
Pass |
| No secrets in logs or command arguments | Fail (Minor - argv splice) |
| Config separate from code (env-driven knobs) | Pass |
| export E2E_OIDC_ISSUER="'"${E2E_OIDC_ISSUER}"'" | ||
| export E2E_OIDC_CLIENT_ID="'"${E2E_OIDC_CLIENT_ID}"'" | ||
| export E2E_OIDC_USERNAME="'"${E2E_OIDC_USERNAME}"'" | ||
| export E2E_OIDC_PASSWORD="'"${E2E_OIDC_PASSWORD}"'" |
There was a problem hiding this comment.
[Minor - Security] The scale-up worker interpolates E2E_OIDC_PASSWORD (and the other OIDC vars) as a literal inside the bash -c '...' string, so the secret ends up in the child process argv (ps//proc/<pid>/cmdline) and the single-quote splice breaks on any value containing a quote/metacharacter. The teardown worker (~line 182) does the same. Prefer export-ing these in the parent shell and letting the backgrounded subshell inherit them — as this code already does for OPENSHIFT_NAMESPACE. That also removes the asymmetry where OPENSHIFT_NAMESPACE (needed by the openshift driver's acquire_oidc_token) is only inherited, not forwarded.
There was a problem hiding this comment.
Addressed in 85c7a8c. Scale-up and teardown workers now inherit API_HOST, OIDC, seed ids, and OPENSHIFT_NAMESPACE from the parent via perf_export_child_env. The bash -c strings no longer interpolate secrets into argv.
| PERF_RES_WALL="null" | ||
| PERF_RES_THROUGHPUT="null" | ||
| PERF_RES_CREATE_JSON='{"p50": null, "p90": null, "p99": null, "max": null}' | ||
| PERF_RES_TTR_JSON='{"p50": null, "p90": null, "p99": null, "max": null}' |
There was a problem hiding this comment.
[Minor - Schema consistency] These init defaults omit the avg key, unlike the module-level defaults (lines 283-284), the documented schema, and completed-run writes, which all include avg. An interrupted run therefore writes time_to_running_seconds with no avg. It renders as - (matching the spec's "Partial Run Shows Dashes" scenario, so harmless), but include "avg": null here for schema consistency.
There was a problem hiding this comment.
Addressed in 85c7a8c. perf_results_init now writes the same {"avg": null, "p50": null, "p90": null, "p99": null, "max": null} objects as the module-level defaults and the schema.
Implements the HYPERSHELL-18 performance-test spec: adds E2E_MODE (short/long) step depth to the e2e suite, an infra-agnostic tests/e2e/e2e-performance.sh harness that scales up a gateway fleet in batches with per-batch short-mode checkpoints, tests/e2e/perf/lib.sh utilities (timing, percentiles, bounded concurrency, JSON results I/O), scripts/perf-report.sh for local reporting, and the make e2e-performance / e2e-performance-report targets. Assisted-by: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Kyle Squizzato <kysquizz@redhat.com>
Assisted-by: Cursor Grok 4.6 Signed-off-by: Kyle Squizzato <kysquizz@redhat.com>
Short-mode throwaway gateways failed every performance run because cluster and release ids were not forwarded and discovery skipped when fleet was already set. Report output now documents the table, prints wall clock as HH:MM:SS, and aligns checkpoint rows. Assisted-by: Cursor Grok 4.6
Export OIDC and API env in the parent so bash -c workers inherit credentials instead of taking them on argv. Include avg in init latency JSON. Kind seed discovery selects default/local-kind/ dev-release by name unless the caller overrides. Assisted-by: Cursor Grok 4.6
347fdcb to
1ca6671
Compare
Assisted-by: Cursor Grok 4.6 Signed-off-by: Kyle Squizzato <kysquizz@redhat.com>
1ca6671 to
8e0a159
Compare
What
Implements the HYPERSHELL-18 performance-test spec: an infra-agnostic e2e performance harness with batched, checkpointed gateway scale-up.
Highlights
E2E_MODE=short|longstep-depth tagging to the e2e suite (tests/e2e/lib.sh,tests/e2e/e2e-openshell.sh); long remains the default so existing CI is unchanged.tests/e2e/e2e-performance.shharness: batched gateway scale-up with bounded concurrency, per-batch short-mode checkpoints, a final long-mode functional gate, optional SLO gating, and EXIT-trap teardown.tests/e2e/perf/lib.shutilities (timing, latency percentiles, bounded concurrency, schema_version=1 JSON results I/O) plustests/e2e/perf/lib_test.shunit tests (no cluster required).scripts/perf-report.shandmake e2e-performance/make e2e-performance-reporttargets to run the harness and tabulate local run history.bash, notpython3/jqas previously stated.Scope
Local/manual performance testing only — not wired into PR CI (too slow/heavy for the 20-minute gate). The OpenShift driver itself remains out of scope (tracked under HYPERSHELL-44).