Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions benchmarking/analysis/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@ A failed atelet operation still writes its record, marked with `error.type`
## Reading the report

**Phase percentiles.** Per layer, operation, sandbox class, snapshot kind,
scope and phase: count, p50, p90, p95 and max. A `golden` restore downloads
the golden image and a `latest` one the actor's own, so they are separate
rows, as are gVisor and micro-VM operations. The atelet rows split a
scope and phase: count, p50, p90, p95 and max. A `local` restore reads a
node-local snapshot and a `latest` one a durable snapshot from object
storage, so they are separate rows, as are gVisor and micro-VM operations.
A restore from a template's golden snapshot reports `latest`, like the
actor's own durable snapshot. The atelet rows split a
checkpoint between `sandbox_assets`, `worker_checkpoint`, `persist` and
`cleanup`, and a
restore between `volume_mount`, `manifest_fetch`, `sandbox_assets`,
Expand Down
6 changes: 3 additions & 3 deletions benchmarking/analysis/phase_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,9 @@ def fmt_s(seconds: float) -> str:

def report_phases(breakdowns: list[Breakdown], writer) -> list[dict]:
"""Per (source, op, sandbox class, kind, scope, phase) percentiles. A
golden restore (which downloads the golden image) and a latest restore,
or a gVisor and a micro-VM checkpoint, are different distributions and
must not be pooled. Returns the rows for CSV."""
local restore and a latest one, or a gVisor and a micro-VM checkpoint,
are different distributions and must not be pooled. Returns the rows
for CSV."""
groups: dict[tuple, list[float]] = defaultdict(list)
for b in breakdowns:
if b.failed:
Expand Down
12 changes: 6 additions & 6 deletions benchmarking/analysis/test_phase_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,14 @@ def test_failed_records_are_flagged_and_excluded_from_percentiles(self):
self.assertEqual(downloads[0]["count"], 1) # the failed 30s never entered

def test_percentiles_split_by_sandbox_class_and_kind(self):
golden = dict(ATELET_RESTORE, **{"time": "2026-09-23T09:59:00.000000000Z",
"ate.snapshot.kind": "golden", "ate.sandbox.class": "gvisor",
"ate.actor.restore.duration.download": 9.0,
"ate.actor.restore.duration.total": 10.0})
local = dict(ATELET_RESTORE, **{"time": "2026-09-23T09:59:00.000000000Z",
"ate.snapshot.kind": "local", "ate.sandbox.class": "gvisor",
"ate.actor.restore.duration.download": 9.0,
"ate.actor.restore.duration.total": 10.0})
latest = dict(ATELET_RESTORE, **{"ate.sandbox.class": "gvisor"})
rows = phase_report.report_phases(parse(golden, latest).breakdowns, lambda _: None)
rows = phase_report.report_phases(parse(local, latest).breakdowns, lambda _: None)
downloads = {(r["class"], r["kind"]): r["p50_ms"] for r in rows if r["phase"] == "download"}
self.assertEqual(downloads, {("gvisor", "golden"): 9000.0, ("gvisor", "latest"): 2400.0})
self.assertEqual(downloads, {("gvisor", "local"): 9000.0, ("gvisor", "latest"): 2400.0})

def test_paired_ateworker_record_inherits_the_atelet_kind(self):
out = parse(ATEWORKER_RESTORE, ATELET_RESTORE)
Expand Down
2 changes: 1 addition & 1 deletion cmd/ateapi/internal/apivalidation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1712,7 +1712,7 @@ func TestValidateTagRequestPayloads(t *testing.T) {

func validGoldenSnapshotStatus(mutate ...func(*ateapipb.GoldenSnapshotStatus)) *ateapipb.GoldenSnapshotStatus {
s := &ateapipb.GoldenSnapshotStatus{
GoldenTag: &ateapipb.ObjectRef{Atespace: "ate-golden", Name: "01234567-89ab-cdef-0123-456789abcdef"},
GoldenTag: &ateapipb.ObjectRef{Atespace: "team-a", Name: "01234567-89ab-cdef-0123-456789abcdef"},
SnapshotTime: &timestamppb.Timestamp{Seconds: 867},
}
for _, m := range mutate {
Expand Down
4 changes: 1 addition & 3 deletions cmd/ateapi/internal/authz/interceptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,6 @@ func TestUnaryServerInterceptor_LifecycleEgressWorkerAndTagChecks(t *testing.T)
}
cloneInTeamA := cloneTag("team-a", tag)
cloneInTeamB := cloneTag("team-b", tag)
cloneGolden := cloneTag("team-a", &ateapipb.ObjectRef{Atespace: "ate-golden", Name: "golden-v1"})
createWithoutTag := cloneTag("team-a", nil)

tests := []struct {
Expand Down Expand Up @@ -638,14 +637,13 @@ func TestUnaryServerInterceptor_LifecycleEgressWorkerAndTagChecks(t *testing.T)
{"bootstrap owner deletes tag", "bootstrap-owner", deleteTag, codes.OK},

// Cloning from a tag needs editor on the tag's atespace, whatever its
// scope; golden tags and actors created without a tag are unaffected.
// scope. An actor created without an explicit tag only needs its template.
{"editor clones tag", "editor", cloneInTeamA, codes.OK},
{"viewer cannot clone tag", "viewer", cloneInTeamA, codes.PermissionDenied},
{"editor of another atespace cannot clone tag", "outsider", cloneInTeamB, codes.PermissionDenied},
{"viewer of tag's atespace cannot clone tag into another atespace", "outsider-with-viewer", cloneInTeamB, codes.PermissionDenied},
{"global owner clones tag into another atespace", "global-owner", cloneInTeamB, codes.OK},
{"bootstrap owner clones tag", "bootstrap-owner", cloneInTeamA, codes.OK},
{"editor clones golden tag", "editor", cloneGolden, codes.OK},
{"editor creates actor without a tag", "editor", createWithoutTag, codes.OK},

// Only the egress gateway mints actor credentials; not even owners.
Expand Down
5 changes: 2 additions & 3 deletions cmd/ateapi/internal/authz/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,9 @@ func onTag(relation string, ref resourceRef, fldPath *field.Path) ([]check, fiel
}

// onSourceTag checks can_use_tag on the tag an actor is created from, if the
// request names one. Golden tags are exempt: the handler only accepts one
// built from the actor's own template, which can_use_template already covers.
// request names one.
func onSourceTag(ref *ateapipb.ObjectRef, fldPath *field.Path) ([]check, field.ErrorList) {
if ref == nil || ref.GetAtespace() == resources.GoldenActorAtespace {
if ref == nil {
return nil, nil
}
return onTag(RelationCanUseTag, ref, fldPath)
Expand Down
5 changes: 3 additions & 2 deletions cmd/ateapi/internal/authz/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,17 @@ func TestDefaultRPCPermissions(t *testing.T) {
},
},
{
name: "CreateActor from a golden tag does not check the tag",
name: "CreateActor from a template tag checks the tag",
fullMethod: ateapipb.Control_CreateActor_FullMethodName,
req: &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{
Metadata: actorMeta,
ActorTemplate: sharedTemplate,
SourceTag: &ateapipb.ObjectRef{Atespace: "ate-golden", Name: "0b5c7d4e-golden"},
SourceTag: &ateapipb.ObjectRef{Atespace: "shared", Name: "0b5c7d4e-golden"},
}},
want: []check{
{RelationCanCreateActor, "atespace:team-a"},
{RelationCanUseTemplate, "actor_template:shared/tmpl"},
{RelationCanUseTag, "tag:shared/0b5c7d4e-golden"},
},
},
{
Expand Down
5 changes: 0 additions & 5 deletions cmd/ateapi/internal/controlapi/actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,6 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor)
if err != nil {
return nil, err
}
if inActor.GetSourceTag() == nil {
if err := validateGoldenSnapshotFidelity(sourceTag.GetStatus().GetSnapshot()); err != nil {
return nil, err
}
}
}

atespace := inActor.GetMetadata().GetAtespace()
Expand Down
6 changes: 3 additions & 3 deletions cmd/ateapi/internal/controlapi/actor_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func TestCreateActorTemplateIgnoresServerOwnedFields(t *testing.T) {
// Server-owned status a client must not be able to set.
tmpl.Status = &ateapipb.ActorTemplateStatus{
GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{
GoldenTag: &ateapipb.ObjectRef{Atespace: "ate-golden", Name: "golden-tag"},
GoldenTag: &ateapipb.ObjectRef{Atespace: "ns1", Name: "golden-tag"},
},
}
})
Expand Down Expand Up @@ -152,7 +152,7 @@ func TestDeleteActorTemplate(t *testing.T) {
persistence := newTestPersistence(t)
tmpl := seedSubstrateTemplate(t, ctx, persistence, "tmpl")
templateRef := resources.ActorTemplateRefFromActorTemplate(tmpl)
goldenRef := resources.ActorRef{Atespace: resources.GoldenActorAtespace, Name: tmpl.GetMetadata().GetUid()}
goldenRef := resources.ActorRef{Atespace: "team-a", Name: tmpl.GetMetadata().GetUid()}
actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{
Metadata: &ateapipb.ResourceMetadata{Atespace: goldenRef.Atespace, Name: goldenRef.Name},
ActorTemplate: templateRef.ToObjectRef(),
Expand Down Expand Up @@ -366,7 +366,7 @@ func TestUpdateActorTemplateMetadata(t *testing.T) {
// A server-owned status write passes validation and bumps the version.
updated, err := persistence.UpdateActorTemplate(ctx, ref, store.PreconditionFrom(created), func(tmpl *ateapipb.ActorTemplate) error {
tmpl.Status = &ateapipb.ActorTemplateStatus{GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{
GoldenTag: &ateapipb.ObjectRef{Atespace: "ate-golden", Name: "golden-tag"},
GoldenTag: &ateapipb.ObjectRef{Atespace: "ns1", Name: "golden-tag"},
}}
return nil
})
Expand Down
8 changes: 3 additions & 5 deletions cmd/ateapi/internal/controlapi/actor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -825,16 +825,15 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) {
ctx := t.Context()
persistence := newTestPersistence(t)
storetest.MustCreateAtespace(t, ctx, persistence, "team-a")
storetest.MustCreateAtespace(t, ctx, persistence, resources.GoldenActorAtespace)
tmpl := seedSubstrateTemplate(t, ctx, persistence, "tmpl")
ref := &ateapipb.ObjectRef{Atespace: resources.GoldenActorAtespace, Name: "golden"}
ref := &ateapipb.ObjectRef{Atespace: "team-a", Name: tmpl.GetMetadata().GetUid()}
tag := &ateapipb.Tag{
Metadata: &ateapipb.ResourceMetadata{Atespace: ref.Atespace, Name: ref.Name},
SourceActor: ref,
Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED,
Status: &ateapipb.TagStatus{
ActorTemplateUid: tmpl.GetMetadata().GetUid(),
Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), someActorUID, "gs://bucket/atespaces/ate-golden/tags/"+someActorUID, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED),
Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), someActorUID, "gs://bucket/atespaces/team-a/tags/"+someActorUID, ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED),
},
}
wantCode := codes.OK
Expand All @@ -849,7 +848,6 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) {
wantCode = codes.FailedPrecondition
case "data scope":
tag.Status.Snapshot.Fidelity = ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES
wantCode = codes.FailedPrecondition
}
if scenario != "missing" {
if _, err := persistence.CreateTag(ctx, tag); err != nil {
Expand All @@ -865,7 +863,7 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) {
actor := &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Atespace: "team-a", Name: "actor"}, ActorTemplate: resources.ActorTemplateRefFromActorTemplate(tmpl).ToObjectRef()}
if scenario == "explicit tag" {
tag.Metadata.Name = "explicit"
tag.Status.Snapshot = newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), "explicit", "gs://bucket/atespaces/ate-golden/tags/explicit", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)
tag.Status.Snapshot = newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), "explicit", "gs://bucket/atespaces/team-a/tags/explicit", ateapipb.SnapshotStorageStatus_SNAPSHOT_STORAGE_STATUS_COMPLETED)
if _, err := persistence.CreateTag(ctx, tag); err != nil {
t.Fatal(err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestActorTemplateCRUD(t *testing.T) {
// Server-owned status on the request is ignored.
Status: &ateapipb.ActorTemplateStatus{
GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{
GoldenTag: &ateapipb.ObjectRef{Atespace: "ate-golden", Name: "golden-tag"},
GoldenTag: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "golden-tag"},
},
},
},
Expand Down Expand Up @@ -163,7 +163,7 @@ func TestGoldenTagLifecycle(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !parsed.OwnedBy(resources.TagSnapshotOwner(resources.GoldenActorAtespace, golden.GetMetadata().GetUid())) {
if !parsed.OwnedBy(resources.TagSnapshotOwner(testAtespace, golden.GetMetadata().GetUid())) {
t.Fatalf("golden snapshot %q is not under the golden tag's own prefix", uri)
}
assertSnapshotPresent(t, tc, uri)
Expand Down Expand Up @@ -247,7 +247,7 @@ func TestActorLifecycleWithoutGoldenSnapshot(t *testing.T) {
}
workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1")
controlTemplate := createTemplateWithSelector(t, tc, "golden-control", &ateapipb.Selector{MatchLabels: map[string]string{poolLabelKey: ns}})
goldenRef := &ateapipb.ObjectRef{Atespace: resources.GoldenActorAtespace, Name: tmpl.GetMetadata().GetUid()}
goldenRef := &ateapipb.ObjectRef{Atespace: testAtespace, Name: tmpl.GetMetadata().GetUid()}
assertNoGolden := func(ctx context.Context) error {
if _, err := tc.client.GetActor(ctx, &ateapipb.GetActorRequest{Actor: goldenRef}); status.Code(err) != codes.NotFound {
return fmt.Errorf("disabled template's golden actor: got %v, want NotFound", err)
Expand Down
22 changes: 13 additions & 9 deletions cmd/ateapi/internal/controlapi/functionaltest/actor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3272,13 +3272,12 @@ func createDataFidelityTemplate(t *testing.T, tc *testContext, ns string) *ateap

// Publish the golden snapshot as a tag and point the template at it, as
// createTemplateWithContainersAndVolumes does.
createAtespace(t, tc, resources.GoldenActorAtespace)
tag, err := tc.persistence.CreateTag(context.Background(), &ateapipb.Tag{
Metadata: &ateapipb.ResourceMetadata{Atespace: resources.GoldenActorAtespace, Name: created.GetMetadata().GetUid()},
SourceActor: &ateapipb.ObjectRef{Atespace: resources.GoldenActorAtespace, Name: created.GetMetadata().GetUid()},
Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: created.GetMetadata().GetUid()},
SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: created.GetMetadata().GetUid()},
Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED,
Status: &ateapipb.TagStatus{
Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, created.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)),
Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_VOLUMES, created.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)),
ActorTemplateUid: created.GetMetadata().GetUid(),
},
})
Expand Down Expand Up @@ -3943,10 +3942,15 @@ func TestSuspendActor(t *testing.T) {
// It stopped borrowing without releasing what it had borrowed.
assertSnapshotPresent(t, tc, taggedSnapshotURI)
assertSnapshotPresent(t, tc, cloneSnapshotURI)
// The untagged suspend created no tag.
// The untagged suspend created no tag: only the golden and explicit tag remain.
listed, err = tc.client.ListTags(context.Background(), &ateapipb.ListTagsRequest{Atespace: testAtespace})
if err != nil || len(listed.GetTags()) != 1 {
t.Fatalf("ListTags after clone suspension = (%v, %v), want one", listed, err)
if err != nil || len(listed.GetTags()) != 2 {
t.Fatalf("ListTags after clone suspension = (%v, %v), want golden and explicit tags", listed, err)
}
for _, tag := range listed.GetTags() {
if ref := resources.TagRefFromTag(tag).ToObjectRef(); !proto.Equal(ref, tagRef) && !proto.Equal(ref, tmpl.GetStatus().GetGoldenSnapshotStatus().GetGoldenTag()) {
t.Errorf("unexpected tag after clone suspension: %v", ref)
}
}

getResp, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{
Expand Down Expand Up @@ -6163,8 +6167,8 @@ func TestResumeActor_SandboxRuntimePlacementAndFallback(t *testing.T) {
goldenSnap := newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, tmpl.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t))
goldenSnap.SandboxRuntime = proto.Clone(rtA).(*ateapipb.SandboxRuntime)
stampedGoldenTag, err := tc.persistence.CreateTag(ctx, &ateapipb.Tag{
Metadata: &ateapipb.ResourceMetadata{Atespace: resources.GoldenActorAtespace, Name: "golden-rt-a"},
SourceActor: &ateapipb.ObjectRef{Atespace: resources.GoldenActorAtespace, Name: tmpl.GetMetadata().GetUid()},
Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "golden-rt-a"},
SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: tmpl.GetMetadata().GetUid()},
Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED,
Status: &ateapipb.TagStatus{
Snapshot: goldenSnap,
Expand Down
7 changes: 3 additions & 4 deletions cmd/ateapi/internal/controlapi/functionaltest/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ const goldenSnapshotName = "9c2f7b41-6d05-4e83-a1f7-3b8c0d5e2a94"
// goldenSnapshotURI is the snapshot owned by the test template's golden tag.
func goldenSnapshotURI(t *testing.T) string {
t.Helper()
uri, err := resources.NewTagSnapshotURI(testStorageLocation, resources.GoldenActorAtespace, goldenSnapshotName)
uri, err := resources.NewTagSnapshotURI(testStorageLocation, testAtespace, goldenSnapshotName)
if err != nil {
t.Fatalf("NewTagSnapshotURI: %v", err)
}
Expand Down Expand Up @@ -499,10 +499,9 @@ func createTemplateWithContainersAndVolumes(t *testing.T, tc *testContext, ns st
t.Fatalf("failed to create actor template: %v", err)
}

createAtespace(t, tc, resources.GoldenActorAtespace)
tag, err := tc.persistence.CreateTag(context.Background(), &ateapipb.Tag{
Metadata: &ateapipb.ResourceMetadata{Atespace: resources.GoldenActorAtespace, Name: created.GetMetadata().GetUid()},
SourceActor: &ateapipb.ObjectRef{Atespace: resources.GoldenActorAtespace, Name: created.GetMetadata().GetUid()},
Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: created.GetMetadata().GetUid()},
SourceActor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: created.GetMetadata().GetUid()},
Scope: ateapipb.TagScope_TAG_SCOPE_PUBLISHED,
Status: &ateapipb.TagStatus{
Snapshot: newDurableSnapshot(1, ateapipb.SnapshotOwner_SNAPSHOT_OWNER_TAG, ateapipb.SnapshotFidelity_SNAPSHOT_FIDELITY_MEMORY, created.GetMetadata().GetUid(), goldenSnapshotName, goldenSnapshotURI(t)),
Expand Down
Loading
Loading