返回 DeepSeek-Reasonix
attachment_atomicity_test.go
根目录 / internal / control / attachment_atomicity_test.go
1 package control
2
3 import (
4 "encoding/base64"
5 "os"
6 "path/filepath"
7 "testing"
8
9 "reasonix/internal/agent"
10 "reasonix/internal/event"
11 "reasonix/internal/provider"
12 "reasonix/internal/tool"
13 )
14
15 func TestMixedDraftAndOrdinaryWorkspaceImageAreBothPrepared(t *testing.T) {
16 root := t.TempDir()
17 c := newOwnedTestController(t, Options{WorkspaceRoot: root})
18 draft, err := c.StageImage(t.Context(), "draft.png", "image/png", "data:image/png;base64,"+tinyPNG)
19 if err != nil {
20 t.Fatal(err)
21 }
22 raw, err := base64.StdEncoding.DecodeString(tinyPNG)
23 if err != nil {
24 t.Fatal(err)
25 }
26 if err := os.WriteFile(filepath.Join(root, "ordinary.png"), raw, 0600); err != nil {
27 t.Fatal(err)
28 }
29 prepared, err := c.PrepareSubmission(t.Context(), SubmissionRequest{Input: "inspect @ordinary.png", Attachments: []SubmissionAttachment{{ClientAttachmentID: "draft", DraftID: draft.ID}}})
30 if err != nil {
31 t.Fatal(err)
32 }
33 if len(prepared.images.inputs) != 2 {
34 t.Fatalf("mixed image count = %d", len(prepared.images.inputs))
35 }
36 }
37
38 func TestInvalidImageBatchNeverStartsEndpointOrGoal(t *testing.T) {
39 for _, endpoint := range []string{"normal", "http", "edit", "goal", "run"} {
40 t.Run(endpoint, func(t *testing.T) {
41 root := t.TempDir()
42 p := &reviewImageProvider{requests: make(chan provider.Request, 4)}
43 ag := agent.New(p, tool.NewRegistry(), agent.NewSession("sys"), agent.Options{}, event.Discard)
44 c := newOwnedTestController(t, Options{WorkspaceRoot: root, SessionPath: filepath.Join(root, "session.jsonl"), Runner: ag, Executor: ag})
45 good, err := SaveImageDataURLInRoot(root, "data:image/png;base64,"+tinyPNG)
46 if err != nil {
47 t.Fatal(err)
48 }
49 input := "inspect @" + good + " @.reasonix/attachments/missing.png"
50 setupCalled := false
51 switch endpoint {
52 case "run":
53 err = c.RunTurn(t.Context(), input)
54 default:
55 req := SubmissionRequest{ID: "reject-batch", Input: input, HTTP: endpoint == "http"}
56 if endpoint == "edit" {
57 req.Original = "original"
58 }
59 _, err = c.SubmitIdentifiedWithSetupContext(t.Context(), req, func() error { setupCalled = true; return nil })
60 }
61 if err == nil || setupCalled || c.Running() {
62 t.Fatalf("partial admission: err=%v setup=%v running=%v", err, setupCalled, c.Running())
63 }
64 if len(p.requests) != 0 {
65 t.Fatal("invalid batch reached provider")
66 }
67 for _, msg := range ag.Session().Snapshot() {
68 if msg.Role == provider.RoleUser {
69 t.Fatal("rejected batch appended a user message")
70 }
71 }
72 })
73 }
74 }
75
75 lines GO