Skip to content

e2e: resume fidelity after SandboxConfig version edits - #3147

Merged
Zoe Zhao (zoez7) merged 5 commits into
agent-substrate:mainfrom
shrutiyam-glitch:compat-tests
Nov 2, 2026
Merged

Zoe Zhao (zoez7) merged 5 commits into
agent-substrate:mainfrom
shrutiyam-glitch:compat-tests

Conversation

@shrutiyam-glitch

@shrutiyam-glitch Shrutiya Mohan (shrutiyam-glitch) commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Split out of the original version of this PR per the review comment: one area per PR, table-driven where the set-up is shared.

Covers what a suspended actor's v1-stamped MEMORY snapshot restores at after its pool's SandboxConfig changes, on both lanes:

Edit Restores at Next snapshot stamped
default moves to v2, v1 still Enabled MEMORY on v1 via restorable_runtimes v1
v1 Disabled ROOTFS on v2 v2
v1 Disabled, actor moved to another template with UpdateActor VOLUMES on v2 (template replacement takes precedence) v2
version names swapped (bundles unchanged, with duplicate aliases) MEMORY; worker lists the hash once v1
assets edited under the same version name ROOTFS new hash
Tag clone after v1 Disabled ROOTFS on v2 v2

The fixture (setupSuspendedV1Actor, updateVersions, waitForWorker, resumeAndCheck) is what the follow-up PRs build on: paused actor across version changes, scheduler preferring the compatible pool, WorkerPool configRef changes and bad asset SHA256.

The controlapi unit test change seeds a worker with a different default so the snapshot-stamp assertion actually discriminates.

AI-assisted, I reviewed and tested it.

  • Tests pass
  • Docs updated

@shrutiyam-glitch Shrutiya Mohan (shrutiyam-glitch) changed the title Compat tests e2e: cover SandboxConfig runtime upgrades, fallbacks, and placement Oct 23, 2026
@shrutiyam-glitch
Shrutiya Mohan (shrutiyam-glitch) marked this pull request as ready for review October 23, 2026 18:24
@shrutiyam-glitch
Shrutiya Mohan (shrutiyam-glitch) marked this pull request as draft October 23, 2026 23:49
@shrutiyam-glitch
Shrutiya Mohan (shrutiyam-glitch) marked this pull request as ready for review October 26, 2026 15:00
@bowei Bowei Du (bowei) added area/node area/scheduling area/tests Enhancing / fixing test coverage. kind/feature An enhancement / feature request or implementation labels Oct 27, 2026
@shrutiyam-glitch
Shrutiya Mohan (shrutiyam-glitch) force-pushed the compat-tests branch 3 times, most recently from 9c0ba11 to cda6847 Compare October 28, 2026 03:36
Krzysztof Siedlecki (krzysied) pushed a commit to krzysied/substrate that referenced this pull request Oct 28, 2026
…gent-substrate#3338)

Verify that RevertActor returns an actor to its most recent completed
durable snapshot from RUNNING, paused SUSPENDED after background upload,
and CRASHED states, and reverts to the template golden snapshot when the
actor has no snapshot of its own.

Fixes part of agent-substrate#3147

AI use: 
AI-assisted, I reviewed and tested it.

No breaking change

- [x] Tests pass
- [x] Docs updated

Signed-off-by: Nayana Bidari <[email protected]>
@zoez7

Copy link
Copy Markdown
Collaborator

Thanks for the thorough test coverage! internal/e2e/suites/demo/sandboxruntime_test.go and internal/e2e/suites/demo/sandboxconfig_test.go combined are 2000 lines of diff and is hard to review. Can we split this into smaller PRs, each with one area of test coverage? This will help the reviewer to understand which CUJs are covered. Another idea is to organize the tests that share similar set up steps into table-driven tests?

One idea is:

func TestSandboxConfigEdit(t *testing.T) {
	t.Parallel()
	tests := []struct {
		name string
		// edit returns the defaultVersion and versions to apply to a config
		// that starts with v1 alone.
		edit func(v1, v2 atev1.SandboxVersionConfig) (string, []atev1.SandboxVersionConfig)
		// wantResume is the fidelity a v1-stamped actor restores at after the edit.
		wantResume ateapi.SnapshotFidelity
		// wantOnV1 says the resumed assignment keeps v1's runtime.
		wantOnV1 bool
	}{{
		name: "new default keeps old version restorable",
		edit: func(v1, v2 atev1.SandboxVersionConfig) (string, []atev1.SandboxVersionConfig) {
			return v2.Name, []atev1.SandboxVersionConfig{v1, v2}
		},
		wantResume: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY,
		wantOnV1:   true,
	}, {
		name: "disabled version falls back to ROOTFS",
		edit: func(v1, v2 atev1.SandboxVersionConfig) (string, []atev1.SandboxVersionConfig) {
			return v2.Name, []atev1.SandboxVersionConfig{withState(v1, atev1.SandboxVersionStateDisabled), v2}
		},
		wantResume: ateapi.SnapshotFidelity_SNAPSHOT_FIDELITY_ROOTFS,
	}}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			t.Parallel()
			f := newRuntimeFixture(t, runtimeFixtureOptions{Golden: false})
			f.runTwiceAndSuspend(t)
			def, versions := tt.edit(f.v1, f.v2)
			f.updateVersions(t, def, versions) // retry.RetryOnConflict inside
			// The default must move off v1 first; before the edit the
			// worker matches v1 as its default.
			f.waitForWorker(t, func(st *ateapi.WorkerStatus) bool {
				def := runtimeAttribute(hardware.ColdBootRuntime(st), hardware.AttrSandboxBundleHash)
				return def != f.v1Hash && hardware.WorkerMatches(st, f.v1Runtime) == tt.wantOnV1
			})
			f.resumeAndCheck(t, tt.wantResume, tt.wantOnV1)
		})
	}
}

@shrutiyam-glitch Shrutiya Mohan (shrutiyam-glitch) changed the title e2e: cover SandboxConfig runtime upgrades, fallbacks, and placement e2e: resume fidelity after SandboxConfig version edits Oct 30, 2026
@shrutiyam-glitch
Shrutiya Mohan (shrutiyam-glitch) force-pushed the compat-tests branch 5 times, most recently from 431d67c to 2309183 Compare October 30, 2026 22:16
The SandboxConfig runtime tests need a pool on a per-test SandboxConfig
instead of the class default, so a test can edit versions without
touching the shared install.

Signed-off-by: Shrutiya <[email protected]>
setupSuspendedV1Actor builds a SandboxConfig with one version copied from
the class default, a one-worker pool pinned to it, and an actor suspended
on it with a v1-stamped MEMORY snapshot. The fixture's updateVersions and
waitForWorker let a test edit the config and wait for the worker to
re-register. resume, call, and suspend drive the actor and track its
counters and snapshot generation, so a test states what a restore keeps
rather than the counter values; resumeAndCheck composes them.

Signed-off-by: Shrutiya <[email protected]>
Each case edits the versions of a config that started with v1 alone and
checks what a v1-stamped MEMORY snapshot restores at. A new default with v1
still Enabled restores MEMORY on v1 through restorable_runtimes; disabling
v1 drops to ROOTFS on the new default, or to VOLUMES when the actor was
also moved to another template, since the template replacement takes
precedence. Swapping the names of two versions keeps the bundle restorable
and the worker lists each hash once, since compatibility keys on
sandbox_bundle_hash; changing a version's assets under its old name drops
to ROOTFS. In every case the next suspend stamps the snapshot with the
runtime the actor resumed under.

Signed-off-by: Shrutiya <[email protected]>
… worker default

TestSuspendActor_MarkedSuspending_SnapshotURI seeded no worker, so it could
not tell whether the snapshot stamp came from WorkerAssignment.sandbox_runtime
or from the worker's registration. Seed the worker with a different
default_runtime so it does.

Signed-off-by: Shrutiya <[email protected]>
A Tag keeps the sandbox_runtime stamp of the snapshot it was created from,
and an actor created from the Tag borrows that snapshot. Once the version
is disabled, the clone drops to ROOTFS on the new default like the actor
the Tag came from would.

Signed-off-by: Shrutiya <[email protected]>
@zoez7
Zoe Zhao (zoez7) added this pull request to the merge queue Nov 2, 2026
Merged via the queue into agent-substrate:main with commit 24482d5 Nov 2, 2026
5 checks passed
Dmitry Berkovich (dberkov) pushed a commit that referenced this pull request Nov 3, 2026
Bring `release-1.0` up to `main` at
5a5b192 with the 19 changes merged
since the previous batch in #3536. The final tree matches that commit
exactly.

**Please use Rebase and merge to preserve the individual commits and
author attribution.** All 19 applied cleanly in upstream order. Original
authors, author dates, co-author and sign-off trailers, and `-x` source
references are retained.

Upgrade notes:

- #3533: old gVisor MEMORY snapshots, including goldens, no longer
restore. Recreate them after upgrading. MicroVM MEMORY snapshots still
resume with their old mounts until recreated. `/tmp` is now always
tmpfs; ROOTFS snapshots no longer preserve its contents, and
image-provided files there are hidden. MicroVM `/tmp` counts against
actor memory and is capped at half the guest's memory. gVisor `/dev/shm`
is now a 64 MiB tmpfs. Mount a `durableDir` at either path when
persistence or more space is needed. `/run` now comes from the image
rootfs.
- #3447: remove `--actor-jwt-jwks-file` from custom credential-exchange
sidecar configs. Set `--actor-jwt-issuer-ca-file` only when the issuer
uses a private CA other than the service DNS CA.

- #3450: do not reuse a deleted atespace name. See the updated atespace
name-reuse guidance.

Includes #3505, which overlaps the open backport in #3547. GKE
provisioning and teardown now live in
[substrate-gke](https://github.com/ai-on-gke/substrate-gke) rather than
this repository.

<details>
<summary>Included PRs, in cherry-pick order</summary>

1. #3500: demos/{sandbox,jupyter,multi-template}: fix tutorial
prerequisites, walkthroughs, and counter volume
2. #3498: demos/counter: inline gVisor walkthrough and fix setup
commands
3. #3511: e2e tests: Extend the existing tests to cover tag actor.
4. #2775: Generate API reference documentation and publish it on
Substrate website
5. #3119: Document how people, pods and CI jobs should authenticate to
ate-api
6. #3505: tools: remove setup-gcp and hack/teardown.sh
7. #3147: e2e: resume fidelity after SandboxConfig version edits
8. #3370: ate-setup: reconcile ate-api-server ConfigMaps and roll out on
config changes
9. #1607: hack: reject breaking proto changes across each proto package
10. #3415: docs: update and add security diagrams
11. #3485: Resuming a microVM actor on the same node no longer reads its
rootfs upper back from disk
12. #3447: Verify actor JWTs in the credential exchange through OIDC
discovery
13. #3533: ocispec: mount tmpfs at /dev/shm, and /tmp on both runtimes
14. #3450: docs: Document that atespace names must not be reused
15. #3410: Document using more than one egress credential provider
16. #3486: atelet: register the device plugin on a new socket each time
17. #3553: ate-setup: wait for the demo namespace in delete demo
18. #3560: Fix multiple issues in claude-code-multiplex demo
19. #3517: docs: remove inaccurate early-stage architecture
documentation

</details>

Validation: every intermediate tree matches its upstream source commit,
all 19 authorship records and original attribution trailers are
preserved, and `git diff --check` passes. The original 18 backport
commits are unchanged.

AI use: AI-assisted cherry-picking, attribution checks, and review.

- [ ] Tests pass
- [x] Docs updated

---------

Signed-off-by: Mofi Rahman <[email protected]>
Signed-off-by: Eitan Yarmush <[email protected]>
Signed-off-by: Nayana Bidari <[email protected]>
Signed-off-by: Julian Gutierrez Oschmann <[email protected]>
Signed-off-by: Max Thompson <[email protected]>
Signed-off-by: Steven Shriver <[email protected]>
Signed-off-by: Grant McCloskey <[email protected]>
Signed-off-by: Shrutiya <[email protected]>
Signed-off-by: Haiyan Meng <[email protected]>
Signed-off-by: Greg Castle <[email protected]>
Signed-off-by: Benjamin Elder <[email protected]>
Signed-off-by: Anish Ramasekar <[email protected]>
Signed-off-by: Shruti Nair <[email protected]>
Signed-off-by: Haven Xia <[email protected]>
Co-authored-by: Mofi Rahman <[email protected]>
Co-authored-by: nybidari <[email protected]>
Co-authored-by: Julian Gutierrez Oschmann <[email protected]>
Co-authored-by: Max Thompson <[email protected]>
Co-authored-by: Grant McCloskey <[email protected]>
Co-authored-by: Steven Shriver <[email protected]>
Co-authored-by: shrutiyam-glitch <[email protected]>
Co-authored-by: haiyanmeng <[email protected]>
Co-authored-by: Greg Castle <[email protected]>
Co-authored-by: Benjamin Elder <[email protected]>
Co-authored-by: Anish Ramasekar <[email protected]>
Co-authored-by: Shruti Nair <[email protected]>
Co-authored-by: Haven Xia <[email protected]>
Co-authored-by: Adam Wathieu <[email protected]>
Dmitry Berkovich (dberkov) pushed a commit that referenced this pull request Nov 3, 2026
Split out of the original version of this PR per the review comment: one
area per PR, table-driven where the set-up is shared.

Covers what a suspended actor's v1-stamped MEMORY snapshot restores at
after its pool's SandboxConfig changes, on both lanes:

| Edit | Restores at | Next snapshot stamped |
|---|---|---|
| default moves to v2, v1 still Enabled | MEMORY on v1 via
restorable_runtimes | v1 |
| v1 Disabled | ROOTFS on v2 | v2 |
| v1 Disabled, actor moved to another template with UpdateActor |
VOLUMES on v2 (template replacement takes precedence) | v2 |
| version names swapped (bundles unchanged, with duplicate aliases) |
MEMORY; worker lists the hash once | v1 |
| assets edited under the same version name | ROOTFS | new hash |
| Tag clone after v1 Disabled | ROOTFS on v2 | v2 |

The fixture (`setupSuspendedV1Actor`, `updateVersions`, `waitForWorker`,
`resumeAndCheck`) is what the follow-up PRs build on: paused actor
across version changes, scheduler preferring the compatible pool,
WorkerPool configRef changes and bad asset SHA256.

The controlapi unit test change seeds a worker with a different default
so the snapshot-stamp assertion actually discriminates.

AI-assisted, I reviewed and tested it.

- [x] Tests pass
- [x] Docs updated

---------

Signed-off-by: Shrutiya <[email protected]>
(cherry picked from commit 24482d5)
Signed-off-by: Eitan Yarmush <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/node area/scheduling area/tests Enhancing / fixing test coverage. kind/feature An enhancement / feature request or implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants