返回 DeepSeek-Reasonix
bash_permission_preset_test.go
根目录 / internal / tool / builtin / bash_permission_preset_test.go
1 //go:build !windows
2
3 package builtin
4
5 import (
6 "context"
7 "os"
8 "os/exec"
9 "path/filepath"
10 "strings"
11 "testing"
12
13 "reasonix/internal/sandbox"
14 )
15
16 func TestWorkspaceWriteRunsPipeInlineScriptAndCommandSubstitution(t *testing.T) {
17 if !sandbox.Available() {
18 t.Skip("native sandbox unavailable")
19 }
20 python, err := exec.LookPath("python3")
21 if err != nil {
22 t.Skip("python3 unavailable")
23 }
24 work := t.TempDir()
25 command := "printf 'ok\\n' | " + shellQuote(python) + " -c 'import sys; print(sys.stdin.read().strip().upper())' > result.txt; value=$(cat result.txt); printf '%s' \"$value\""
26 ctx := sandbox.WithPermissionPreset(context.Background(), "workspace-write")
27 out, err := (bash{workDir: work}).Execute(ctx, argsJSON(t, map[string]any{"command": command}))
28 if err != nil {
29 t.Fatalf("workspace command failed: %v (out=%q)", err, out)
30 }
31 if !strings.Contains(out, "OK") {
32 t.Fatalf("workspace command output = %q, want OK", out)
33 }
34 body, err := os.ReadFile(filepath.Join(work, "result.txt"))
35 if err != nil || strings.TrimSpace(string(body)) != "OK" {
36 t.Fatalf("workspace output file = %q, %v", body, err)
37 }
38 }
39
40 func TestReadOnlyPresetBlocksWorkspaceWrite(t *testing.T) {
41 if !sandbox.Available() {
42 t.Skip("native sandbox unavailable")
43 }
44 work := t.TempDir()
45 ctx := sandbox.WithPermissionPreset(context.Background(), "read-only")
46 out, err := (bash{workDir: work}).Execute(ctx, argsJSON(t, map[string]any{"command": "printf blocked > denied.txt"}))
47 if err == nil {
48 t.Fatalf("read-only write unexpectedly succeeded: %q", out)
49 }
50 if _, statErr := os.Stat(filepath.Join(work, "denied.txt")); !os.IsNotExist(statErr) {
51 t.Fatalf("read-only command created denied.txt: %v", statErr)
52 }
53 }
54
54 lines GO