返回 DeepSeek-Reasonix
probe_test.go
根目录 / tools / pathidentityprobe / probe_test.go
1 package main
2
3 import (
4 "context"
5 "encoding/json"
6 "os"
7 "os/user"
8 "path/filepath"
9 "strings"
10 "syscall"
11 "testing"
12 "time"
13
14 "reasonix/internal/pathidentity"
15 )
16
17 func TestInspectDoesNotReadContentOrCreateMissingTail(t *testing.T) {
18 dir := t.TempDir()
19 path := filepath.Join(dir, "existing.lock")
20 const secret = "sentinel-credential-must-not-appear"
21 if err := os.WriteFile(path, []byte(secret), 0o600); err != nil {
22 t.Fatal(err)
23 }
24 before, err := os.Stat(path)
25 if err != nil {
26 t.Fatal(err)
27 }
28 got := inspect(path)
29 if !got.Lstat.OK || !got.Eval.OK || !got.Resolve.OK {
30 t.Fatalf("ordinary file failed: %+v", got)
31 }
32 raw, err := json.Marshal(got)
33 if err != nil || strings.Contains(string(raw), secret) {
34 t.Fatalf("invalid or content-bearing report: %s, %v", raw, err)
35 }
36 after, err := os.Stat(path)
37 if err != nil || !after.ModTime().Equal(before.ModTime()) || after.Size() != before.Size() {
38 t.Fatalf("file metadata changed: %v", err)
39 }
40 content, err := os.ReadFile(path)
41 if err != nil || string(content) != secret {
42 t.Fatalf("file changed: %v", err)
43 }
44 missing := filepath.Join(dir, "absent", "child.lock")
45 result := inspect(missing)
46 if result.Lstat.OK || result.Eval.OK || !result.Resolve.OK {
47 t.Fatalf("missing-tail behavior: %+v", result)
48 }
49 if _, err := os.Lstat(filepath.Dir(missing)); !os.IsNotExist(err) {
50 t.Fatalf("probe created missing parent: %v", err)
51 }
52 }
53
54 func TestFailureRetainsStagePathAndSystemCode(t *testing.T) {
55 err := &pathidentity.Error{Stage: "physical", Path: "missing.lock", Kind: pathidentity.ErrorUnavailable,
56 Err: &os.PathError{Op: "readlink", Path: "junction", Err: syscall.Errno(3)}}
57 got := failureOutcome(err)
58 if got.OK || len(got.Errors) != 3 || got.Errors[0].Stage != "physical" ||
59 got.Errors[0].Path != "missing.lock" || got.Errors[1].Path != "junction" || got.Errors[2].Code != 3 {
60 t.Fatalf("lost structured failure: %+v", got)
61 }
62 }
63
64 func TestCollectionRedactsNestedErrorsAndDoesNotCreateLocks(t *testing.T) {
65 home := filepath.Join(t.TempDir(), "probe-private-user")
66 current := &user.User{HomeDir: home, Uid: "S-1-5-21-private-fixture", Username: "probe-private-user"}
67 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
68 defer cancel()
69 r := collect(ctx, current, nil)
70 if r.TimedOut || len(r.Paths) == 0 {
71 t.Fatalf("no collection: %+v", r)
72 }
73 r.Notes = append(r.Notes, current.Uid)
74 r.Paths[0].Resolve = failureOutcome(&pathidentity.Error{Stage: "physical", Path: home,
75 Err: &os.PathError{Op: "open", Path: filepath.Join(home, "secret.lock"), Err: syscall.Errno(3)}})
76 raw, err := encodeRedacted(r, current)
77 if err != nil || !json.Valid(raw) {
78 t.Fatalf("invalid report: %v", err)
79 }
80 if strings.Contains(string(raw), "probe-private-user") || strings.Contains(string(raw), current.Uid) {
81 t.Fatal("identity was not redacted in nested report")
82 }
83 if _, err := os.Lstat(home); !os.IsNotExist(err) {
84 t.Fatalf("collection created home/locks: %v", err)
85 }
86 }
87
88 func TestRunRefusesExistingReport(t *testing.T) {
89 path := filepath.Join(t.TempDir(), "report.json")
90 if err := os.WriteFile(path, []byte("preserve"), 0o600); err != nil {
91 t.Fatal(err)
92 }
93 if err := run(path, time.Second, nil); err == nil {
94 t.Fatal("overwrote existing report")
95 }
96 raw, err := os.ReadFile(path)
97 if err != nil || string(raw) != "preserve" {
98 t.Fatalf("changed report: %v", err)
99 }
100 }
101
101 lines GO