You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a k3d functional test that proves the full rad startup → reconcile → rad app delete loop unblocks a stuck non-terminal resource, exactly as described in specs/006-state-restoration/plan.md §Phase 2.
Unit tests on the dynamic-rp reality-check handler (gone → Failed, settled → Succeeded, cloud output → skipped, terminal → empty).
Unit tests on the corerp orchestrator (fan-out, terminal skip, dispatch failure recorded).
An httptest-backed integration test that exercises the real HTTP dispatch path against a fake UCP + downstream RP.
Unit tests on the new ReconcileHydratedState stage in rad startup.
What Phase 2 adds is confidence that the full loop works against a real k3d cluster + real Kubernetes + real OCI state archive — not new correctness coverage, but a regression fence that catches drift as the surrounding code evolves.
Installs Radius with the OCI state backend enabled (reuses installRadius + startLocalRegistry already in that package).
Deploys a minimal Radius.Compute/containers application.
rad shutdown — produces an OCI archive.
Poisons the archive — opens it via pkg/statearchive/factory, rewrites the container's provisioningState to "Updating", re-saves.
rad uninstall --purge → rad install — fresh cluster.
rad startup — restores the poisoned state, then the new ReconcileHydratedState stage fires, dynamic-rp GETs the container's outputResources (the k8s Deployment doesn't exist), aggregates to Failed, PATCHes provisioningState.
Asserts the container's provisioningState is Failed via rad resource show.
rad app delete <name> --yes --preview succeeds without a 409 loop.
Unknown to resolve first
The step-4 "poison the archive" primitive doesn't exist yet as a test helper. Options depending on the archive Session interface's ergonomics:
A: use pkg/statearchive/factory to open the archive, iterate keys, find the dynamic-rp row for the container, mutate JSON, save. ~150 LOC helper.
B: if the OCI backend is write-once, unpack the archive manually (OCI descriptor → tarball → JSON files), edit, repack. ~300 LOC helper.
C: (rejected in PR [Spec] Reconcile hydrated state against reality on rad startup #12871 planning) add a test-only POST /debug/force-provisioning-state route on dynamic-rp gated by RADIUS_ENABLE_TEST_ENDPOINTS=true. Smaller test code, adds a test-only surface to the production RP.
Pick a direction after a short spike on the archive Session API.
Summary
Add a k3d functional test that proves the full
rad startup→ reconcile →rad app deleteloop unblocks a stuck non-terminal resource, exactly as described inspecs/006-state-restoration/plan.md§Phase 2.Context
Phase 1 (PR #12871) shipped:
gone → Failed,settled → Succeeded, cloud output →skipped, terminal → empty).httptest-backed integration test that exercises the real HTTP dispatch path against a fake UCP + downstream RP.ReconcileHydratedStatestage inrad startup.What Phase 2 adds is confidence that the full loop works against a real k3d cluster + real Kubernetes + real OCI state archive — not new correctness coverage, but a regression fence that catches drift as the surrounding code evolves.
Acceptance
An E2E test in
test/functional-portable/statestore/noncloud/that:installRadius+startLocalRegistryalready in that package).Radius.Compute/containersapplication.rad shutdown— produces an OCI archive.pkg/statearchive/factory, rewrites the container'sprovisioningStateto"Updating", re-saves.rad uninstall --purge→rad install— fresh cluster.rad startup— restores the poisoned state, then the newReconcileHydratedStatestage fires, dynamic-rp GETs the container'soutputResources(the k8s Deployment doesn't exist), aggregates toFailed, PATCHes provisioningState.Failedviarad resource show.rad app delete <name> --yes --previewsucceeds without a 409 loop.Unknown to resolve first
The step-4 "poison the archive" primitive doesn't exist yet as a test helper. Options depending on the archive
Sessioninterface's ergonomics:pkg/statearchive/factoryto open the archive, iterate keys, find the dynamic-rp row for the container, mutate JSON, save. ~150 LOC helper.rad startup#12871 planning) add a test-onlyPOST /debug/force-provisioning-stateroute on dynamic-rp gated byRADIUS_ENABLE_TEST_ENDPOINTS=true. Smaller test code, adds a test-only surface to the production RP.Pick a direction after a short spike on the archive
SessionAPI.Related
rad startup#12871 — the Phase 0 + Phase 1 implementation this follows up on.rad app deleteis idempotent under concurrent invocations against the same application #12870 — separate follow-up on concurrentrad app deletebehavior.