From b76b5fbaaa39a3db50d6b3b408be043729c16e6c Mon Sep 17 00:00:00 2001 From: Troy Chiu Date: Fri, 24 Jul 2026 04:27:29 +0000 Subject: [PATCH] stamp OpenTelemetry span attributes in UpdateActor --- .../internal/controlapi/update_actor.go | 2 + .../internal/controlapi/update_actor_test.go | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 cmd/ateapi/internal/controlapi/update_actor_test.go diff --git a/cmd/ateapi/internal/controlapi/update_actor.go b/cmd/ateapi/internal/controlapi/update_actor.go index db3384121..5444f61ab 100644 --- a/cmd/ateapi/internal/controlapi/update_actor.go +++ b/cmd/ateapi/internal/controlapi/update_actor.go @@ -31,6 +31,7 @@ func (s *Service) UpdateActor(ctx context.Context, req *ateapipb.UpdateActorRequ if err := validateUpdateActorRequest(req); err != nil { return nil, err } + setSpanActorRefAttributes(ctx, req.GetActor().GetAtespace(), req.GetActor().GetName()) actor, err := s.persistence.GetActor(ctx, req.GetActor().GetAtespace(), req.GetActor().GetName()) if err != nil { @@ -49,6 +50,7 @@ func (s *Service) UpdateActor(ctx context.Context, req *ateapipb.UpdateActorRequ return nil, fmt.Errorf("while updating actor: %w", err) } + setSpanActorAttributes(ctx, updated) return &ateapipb.UpdateActorResponse{Actor: updated}, nil } diff --git a/cmd/ateapi/internal/controlapi/update_actor_test.go b/cmd/ateapi/internal/controlapi/update_actor_test.go new file mode 100644 index 000000000..639df967e --- /dev/null +++ b/cmd/ateapi/internal/controlapi/update_actor_test.go @@ -0,0 +1,64 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controlapi + +import ( + "context" + "testing" + + "go.opentelemetry.io/otel/attribute" + + "github.com/agent-substrate/substrate/internal/ateattr" + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" +) + +func TestUpdateActor_StampsFullSpanIdentity(t *testing.T) { + ns := namespaceForTest("ns-span-update") + tc := setupTest(t, ns) + defer tc.cleanup() + createTemplate(t, tc, ns) + + if _, err := tc.service.CreateActor(context.Background(), &ateapipb.CreateActorRequest{ + Actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID}, + ActorTemplateNamespace: ns, + ActorTemplateName: "tmpl1", + }, + }); err != nil { + t.Fatalf("seed CreateActor: %v", err) + } + + attrs := recordRootSpanAttrs(t, func(ctx context.Context) { + if _, err := tc.service.UpdateActor(ctx, &ateapipb.UpdateActorRequest{ + Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: testActorID}, + WorkerSelector: &ateapipb.Selector{ + MatchLabels: map[string]string{"env": "prod"}, + }, + }); err != nil { + t.Fatalf("UpdateActor: %v", err) + } + }) + + assertSpanStr(t, attrs, ateattr.AtespaceKey, testAtespace) + assertSpanStr(t, attrs, ateattr.ActorNameKey, testActorID) + assertSpanStr(t, attrs, ateattr.TemplateNameKey, "tmpl1") + assertSpanStr(t, attrs, ateattr.TemplateNamespaceKey, ns) + if v, ok := attrs[ateattr.ActorUIDKey]; !ok || v.Type() != attribute.STRING || v.AsString() == "" { + t.Errorf("%s = %v, want non-empty server-assigned uid", ateattr.ActorUIDKey, v.Emit()) + } + if v, ok := attrs[ateattr.ActorVersionKey]; !ok || v.Type() != attribute.INT64 || v.AsInt64() != 2 { + t.Errorf("%s = %v, want int64 2 (updated version)", ateattr.ActorVersionKey, v.Emit()) + } +}