diff --git a/integration/agentcompat/internal/scenario/transfer.go b/integration/agentcompat/internal/scenario/transfer.go index bc787762..5e9345c2 100644 --- a/integration/agentcompat/internal/scenario/transfer.go +++ b/integration/agentcompat/internal/scenario/transfer.go @@ -97,6 +97,7 @@ func (Transfer) RunWithEvidence(ctx context.Context, input TransferInput) (resul result, runErr = transferFinish(assertions, err) return result, transferEvidence, runErr } + defer sentinels.close() execution := transferExecution{ client: dashboardInstance.Clients().MCP, serverID: serverID, diff --git a/integration/agentcompat/internal/scenario/transfer_sentinels.go b/integration/agentcompat/internal/scenario/transfer_sentinels.go index 89832fdb..c196e75c 100644 --- a/integration/agentcompat/internal/scenario/transfer_sentinels.go +++ b/integration/agentcompat/internal/scenario/transfer_sentinels.go @@ -15,23 +15,31 @@ import ( var transferSentinelContent = []byte("outside-transfer-root-sentinel") type transferSentinels struct { - paths []string + root *os.Root + names []string } -func newTransferSentinels(root fixture.AgentRoot, workspaceRoot string) (transferSentinels, error) { - directPath := filepath.Join(workspaceRoot, "outside-transfer-sentinel") - symlinkDirectory := filepath.Join(workspaceRoot, "outside-transfer-directory") - symlinkTarget := filepath.Join(symlinkDirectory, "target-sentinel") - if err := os.Mkdir(symlinkDirectory, 0o700); err != nil { +func newTransferSentinels(root fixture.AgentRoot, workspaceRoot string) (result transferSentinels, err error) { + workspace, err := os.OpenRoot(workspaceRoot) + if err != nil { + return transferSentinels{}, fmt.Errorf("open transfer sentinel root: %w", err) + } + defer func() { + if err != nil { + err = errors.Join(err, workspace.Close()) + } + }() + result = transferSentinels{root: workspace, names: []string{"outside-transfer-sentinel", "outside-transfer-directory/target-sentinel"}} + if err := workspace.Mkdir("outside-transfer-directory", 0o700); err != nil { return transferSentinels{}, fmt.Errorf("create transfer sentinel directory: %w", err) } - for _, path := range []string{directPath, symlinkTarget} { - if err := os.WriteFile(path, transferSentinelContent, 0o600); err != nil { + for _, name := range result.names { + if err := workspace.WriteFile(name, transferSentinelContent, 0o600); err != nil { return transferSentinels{}, fmt.Errorf("write transfer sentinel: %w", err) } } symlinkPath := filepath.Join(root.Absolute(), "linked") - if err := os.Symlink(symlinkDirectory, symlinkPath); err != nil { + if err := os.Symlink(filepath.Join(workspaceRoot, "outside-transfer-directory"), symlinkPath); err != nil { return transferSentinels{}, fmt.Errorf("create transfer sentinel symlink: %w", err) } if _, err := root.Path("../outside-transfer-sentinel"); err == nil { @@ -40,12 +48,12 @@ func newTransferSentinels(root fixture.AgentRoot, workspaceRoot string) (transfe if _, err := root.Path("linked/target-sentinel"); err == nil { return transferSentinels{}, errors.New("transfer AgentPath accepted symlink parent") } - return transferSentinels{paths: []string{directPath, symlinkTarget}}, nil + return result, nil } func (sentinels transferSentinels) unchanged() (bool, error) { - for _, path := range sentinels.paths { - content, err := os.ReadFile(path) + for _, name := range sentinels.names { + content, err := sentinels.root.ReadFile(name) if err != nil { return false, fmt.Errorf("read transfer sentinel: %w", err) } @@ -55,3 +63,5 @@ func (sentinels transferSentinels) unchanged() (bool, error) { } return true, nil } + +func (sentinels transferSentinels) close() error { return sentinels.root.Close() }