test: add upgrade/in-place E2E suite with node pool stability validation - #5725
Conversation
|
Skipping CI for Draft Pull Request. |
|
/label ai-assisted |
|
Patrik Suba (@patriksuba): The label(s) DetailsIn response to this:
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. |
There was a problem hiding this comment.
Pull request overview
Adds a new dedicated E2E suite (upgrade/in-place) to validate HypershiftOperator in-place upgrades end-to-end, including a post-upgrade “no node churn” stability check, and introduces a small framework utility for running make targets with context-aware process-group shutdown.
Changes:
- Introduces an
upgrade/in-placeE2E spec that snapshots node identity/version state and asserts stability for a fixed post-upgrade window. - Adds a reusable
MakeRunnerhelper (plus unit tests) to runmaketargets with SIGTERM→SIGKILL escalation on context cancellation. - Registers the new suite in
aro-hcp-testsand adds a newUpgradeInPlacelabel for suite filtering.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/util/labels/labels.go | Adds UpgradeInPlace label for selecting the new suite. |
| test/util/framework/make_runner.go | Adds MakeRunner for running make targets with process-group cleanup on cancellation. |
| test/util/framework/make_runner_test.go | Unit coverage for MakeRunner success/failure/cancellation/output/env/workdir behavior. |
| test/testdata/zz_fixture_TestMainListSuitesForEachSuite_upgrade_in_placeupgrade_in_place.txt | Updates fixture output for suite listing. |
| test/e2e/hypershiftoperator_upgrade.go | New upgrade/in-place E2E spec that hashes node state and checks stability post-upgrade. |
| test/cmd/aro-hcp-tests/main.go | Registers the upgrade/in-place suite (parallelism 1, 120-minute timeout). |
| test/cmd/aro-hcp-tests/main_test.go | Extends suite-listing test coverage to include upgrade/in-place. |
|
/test images |
1 similar comment
|
/test images |
|
The new test was successfully verified locally against a personal dev environment configured as shown in this PR: openshift/release#80778 |
|
/test images |
- Replace markAndReturn helper with a named-return defer in UpgradeCoordinator.Run so markUpgradeDone fires on every exit path, including readState failure; update test to assert UpgradeDone is written even when all specs aborted (harmless — no waiter is polling) - Inject coordinator logger into the pipeline context via logr.NewContext so runRegionEntrypoint logs are not silently discarded in CI - Fix misleading comment on upgradeCoordinatorLogger: the default is logr.Discard(), not stderr; SetUpgradeCoordinatorLogger enables real output - Switch Consistently from positional (upgradeDoneCtx, pollInterval) to .WithContext().WithPolling() to make the termination signal explicit and avoid the context being misread as a duration - Rename CheckinAndWait → CheckInAndWait for consistency with CheckIn/WaitForUpgrade; update upgrade_barrier.go, AGENTS.md, and region_upgrade_copy.go - Update main.go suite comment to describe the UpgradeCoordinator model instead of the now-removed runner-election model Co-authored-by: Cursor <cursoragent@cursor.com>
|
/test images |
… env vars Co-authored-by: Cursor <cursoragent@cursor.com>
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: deads2k, patriksuba, roivaz The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/test e2e-parallel |
ARO-27693
What
Adds an
upgrade/in-placeE2E suite that exercises the full regional in-place upgrade flow end-to-end. Multiple specs run in parallel — each provisions its own HCP cluster and node pool and captures pre-upgrade baselines — then all specs synchronise at anUpgradeBarrierwhile theUpgradeCoordinator(running in the long-lived parentrun-suiteprocess) invokes the Region entrypoint pipeline once for the whole suite viatemplatize'srun.RunPipeline. After the upgrade every spec validates its own cluster independently.New files
test/e2e/region_upgrade.go— provisions an HCP cluster and node pool, captures three pre-upgrade baselines:k8s-app=kube-apiserver-proxypods)MachineDeploymentDataSecretName (MCO raw-config hash)After
CheckIn, specs perform during-upgrade validation usingConsistently(...).WithContext(upgradeDoneCtx).WithPolling(...)— the observation window runs until the coordinator signals completion, not for a fixed duration. AfterWaitForUpgrade, specs assert all three baselines are unchanged post-upgrade.test/util/framework/upgrade_coordinator.go—UpgradeCoordinatorruns in the parentrun-suiteprocess (guarded byisRunSuiteProcess()inBeforeAll). It initialises the shared state file with the parent PID asrun_id, polls for all specs to check in (waitSettled), then callsrun.RunPipeline(Region entrypoint) in-process. A named-returndefer markUpgradeDone(runErr)ensures the completion signal is written on every exit path — success, failure, env-var misconfiguration, or context cancellation — so no checked-in waiter ever hangs. The coordinator logger is injected into the pipeline context vialogr.NewContextsorunRegionEntrypointlogs are visible in CI'sbuild-log.txt.test/util/framework/upgrade_barrier.go—UpgradeBarriercoordinates parallel worker specs across OS-process boundaries using a YAML state file protected bysyscall.Flockand atomic rename.CheckInatomically incrementschecked_inand returns immediately with anupgradeDoneCtx(cancelled when the coordinator signals completion), allowing specs to start during-upgrade validation without waiting for peers.WaitForUpgradepolls the state file untilUpgradeDoneis set.CheckInAndWaitis a convenience wrapper for specs that skip during-upgrade validation. Per-phase timeouts (settleTimeout=45min,upgradeRunTimeout=50mincoordinator budget,upgradeTimeout=60minspec safety-net) prevent specs from hanging until Prow's hard job kill.Stale-state detection uses
run_id = os.Getppid()(parent PID): all parallel workers in the same suite invocation share the same parent PID; a new invocation gets a different one and resets any leftover state file. The spec count is in-memory only (b.total), populated at runtime bySetUpgradeInPlaceSpecCount— no env var or constant needs updating when specs are added or removed.test/util/framework/upgrade_barrier_test.go— unit tests covering check-in/abort, all-abort early exit, coordinator-driven upgrade signalling, stale state detection, idempotentmarkUpgradeDone, context cancellation, and the all-aborted path writingUpgradeDone(harmless, no waiter polls).Modified files
test/util/labels/labels.go— addedUpgradeInPlacelabel for suite filtering; excluded from all other suites.test/cmd/aro-hcp-tests/main.go— registeredupgrade/in-placesuite (120-minute timeout). CountsUpgradeInPlacespecs from the binary itself at startup and callsframework.SetUpgradeInPlaceSpecCount— suite parallelism and barrier total are always in sync without any constant or env var. ABeforeAllguard starts theUpgradeCoordinatorgoroutine in the parent process only.test/AGENTS.md— documented theUpgradeCoordinator+UpgradeBarrierarchitecture, timing table, stale-state detection, and It-block skeleton for bothCheckInAndWaitand the splitCheckIn+ during-upgrade validation +WaitForUpgradepattern.aro-hcp-test-local-upgrade-commands.sh) — removedUPGRADE_SPEC_COUNTexport; the test binary computes the spec count internally.Why
Upgrade E2E coverage currently stops at cluster provisioning. There is no automated signal that confirms nodes are stable after a full regional upgrade — unexpected node churn (VM replacements, unintended rolling updates triggered by MCO config hash rotation or image substitution) goes undetected until a customer reports an issue.
This PR introduces parallel upgrade validation. Each
upgrade/in-placespec provisions its own baseline cluster, then all specs collectively trigger the Region entrypoint pipeline (upgrading both service and management cluster infrastructure and all services in one idempotent invocation) and independently verify that:node.UIDis included)MachineDeploymentDataSecretName is unchanged (catches MCO raw-config hash rotation that would trigger a node rollout)The upgrade runs in the parent
run-suiteprocess (not inside a worker spec) so its lifetime is independent of any individual spec failure — a spec crashing during provisioning cannot abort the shared upgrade or leave other specs hanging.Testing
Verified locally against a personal dev environment as described in openshift/release#80778.
Special notes for your reviewer
The
UpgradeCoordinatorrelies onisRunSuiteProcess()to distinguish the parentrun-suiteprocess from workerrun-testprocesses. Underopenshift-tests-extension,run-testworkers re-executemain()with a different subcommand, so the guard is:os.Argscontainsrun-suiteand the invocation targets theupgrade/in-placesuite. This is admittedly a convention of the current extension model — a cleaner lifecycle hook in the extension framework would be preferable long-term.PR Checklist