Files
Agent-System/internal/workspace/capability_test.go
T
weichenandCursor 18ddd0f862 feat(workspace): add WorkspaceRef fencing and hide physical paths
Cross-module callers get an opaque ref plus rotating lease tokens so stale writers fail closed, and file I/O is refused inside a unit of work.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 15:59:14 +00:00

120 lines
3.2 KiB
Go

package workspace
import (
"context"
"os"
"path/filepath"
"testing"
"chat-agent-system/internal/app/uow"
)
func issued(t *testing.T, cap *Capability, id string, project int64) WorkspaceRef {
t.Helper()
ref, err := cap.Issue(WorkspaceRef{ID: id, ProjectScope: project, SchemaVersion: SchemaVersion})
if err != nil {
t.Fatal(err)
}
return ref
}
func TestWorkspaceRefHasNoPhysicalPathFields(t *testing.T) {
var ref WorkspaceRef
_ = ref.ID
_ = ref.SchemaVersion
_ = ref.FencingToken
_ = ref.ProjectScope
_ = ref.RunID
_ = ref.Environment
}
func TestCapabilityRejectsBadKeys(t *testing.T) {
cap := NewCapability(t.TempDir(), nil)
ref := issued(t, cap, "ws1", 7)
ctx := context.Background()
for _, key := range []string{"", "../etc/passwd", "/etc/passwd", "..", "a/../b", "a//b", "%2e%2e/secret", "ok/%2fetc"} {
if _, err := cap.ReadArtifact(ctx, ref, key); err == nil {
t.Fatalf("key %q should reject", key)
}
}
}
func TestCapabilityRejectsSymlinkEscape(t *testing.T) {
root := t.TempDir()
cap := NewCapability(root, nil)
ref := issued(t, cap, "ws1", 7)
outside := filepath.Join(t.TempDir(), "secret")
if err := os.WriteFile(outside, []byte("nope"), 0o644); err != nil {
t.Fatal(err)
}
wsDir := filepath.Join(root, "workspaces", "ws1")
if err := os.MkdirAll(wsDir, 0o755); err != nil {
t.Fatal(err)
}
link := filepath.Join(wsDir, "leak")
if err := os.Symlink(outside, link); err != nil {
t.Fatal(err)
}
if _, err := cap.ReadArtifact(context.Background(), ref, "leak"); err != ErrPathEscape {
t.Fatalf("symlink: %v", err)
}
}
func TestStaleFencingRejected(t *testing.T) {
cap := NewCapability(t.TempDir(), nil)
old := issued(t, cap, "ws1", 3)
_ = issued(t, cap, "ws1", 3)
ctx := context.Background()
if err := cap.WriteArtifact(ctx, old, "output.md", []byte("stale")); err != ErrStaleFencing {
t.Fatalf("old writer: %v", err)
}
fresh := issued(t, cap, "ws1", 3)
if err := cap.WriteArtifact(ctx, fresh, "output.md", []byte("ok")); err != nil {
t.Fatal(err)
}
}
func TestUnknownSchemaRejected(t *testing.T) {
cap := NewCapability(t.TempDir(), nil)
_, err := cap.Issue(WorkspaceRef{ID: "ws1", SchemaVersion: 99})
if err != ErrUnknownSchema {
t.Fatalf("got %v", err)
}
}
func TestNoFileIOInsideUnitOfWork(t *testing.T) {
cap := NewCapability(t.TempDir(), nil)
ref := issued(t, cap, "ws1", 1)
ctx := uow.WithScope(context.Background(), stubScope{})
if err := cap.WriteArtifact(ctx, ref, "output.md", []byte("x")); err != ErrIOInTransaction {
t.Fatalf("got %v", err)
}
}
func TestCommitProjectionCompleteMarker(t *testing.T) {
cap := NewCapability(t.TempDir(), nil)
ref := issued(t, cap, "ws1", 1)
ctx := context.Background()
if err := cap.WriteArtifact(ctx, ref, "output.md", []byte("hello")); err != nil {
t.Fatal(err)
}
if err := cap.CommitProjection(ctx, ref, "output.md", ""); err != nil {
t.Fatal(err)
}
got, err := cap.ReadArtifact(ctx, ref, "output.md.complete")
if err != nil {
t.Fatal(err)
}
if !containsComplete(got) {
t.Fatalf("marker %q", got)
}
}
func containsComplete(b []byte) bool {
return string(b) != "" && (string(b)[len(b)-1] == '\n')
}
type stubScope struct{}
func (stubScope) Context() context.Context { return context.Background() }