返回 DeepSeek-Reasonix
provider_diagnostics_test.go
根目录 / internal / control / provider_diagnostics_test.go
1 package control
2
3 import (
4 "context"
5 "encoding/json"
6 "io"
7 "net/http"
8 "net/http/httptest"
9 "testing"
10
11 "reasonix/internal/event"
12 "reasonix/internal/provider"
13 )
14
15 type diagnosticRequestRunner struct {
16 client *http.Client
17 url string
18 }
19
20 func (r diagnosticRequestRunner) Run(ctx context.Context, _ string) error {
21 resp, err := provider.SendWithRetry(ctx, r.client, provider.SendOptions{}, func(ctx context.Context) (*http.Request, error) {
22 return http.NewRequestWithContext(ctx, http.MethodGet, r.url, nil)
23 })
24 if err != nil {
25 return err
26 }
27 defer resp.Body.Close()
28 _, err = io.Copy(io.Discard, resp.Body)
29 return err
30 }
31
32 func TestModelTurnRecordsProviderTransportEvidence(t *testing.T) {
33 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = io.WriteString(w, ": ping\n\n") }))
34 defer server.Close()
35 c := newOwnedTestController(t, Options{Runner: diagnosticRequestRunner{server.Client(), server.URL}, Sink: event.Discard, SessionDir: t.TempDir()})
36 if err := c.RunTurn(t.Context(), "observe transport"); err != nil {
37 t.Fatal(err)
38 }
39 data, err := json.Marshal(c.providerDiagnosticSnapshot())
40 if err != nil {
41 t.Fatal(err)
42 }
43 var snapshot struct{ Requests []providerDiagnostic }
44 if err := json.Unmarshal(data, &snapshot); err != nil {
45 t.Fatal(err)
46 }
47 if len(snapshot.Requests) != 1 {
48 t.Fatalf("missing observer wiring: %s", data)
49 }
50 r := snapshot.Requests[0]
51 if r.TurnID == "" || r.Phase != "body_eof" || r.HeadersAt.IsZero() || r.BodyBytes != 8 {
52 t.Fatalf("incomplete transport evidence: %+v", r)
53 }
54 }
55
56 func TestProviderDiagnosticsBoundRequestsNotHeartbeatEvents(t *testing.T) {
57 c := &Controller{}
58 for id := uint64(1); id <= 130; id++ {
59 c.recordProviderRequest("turn", provider.RequestObservation{ID: id, Phase: "request_started"})
60 for i := 1; i <= 300; i++ {
61 c.recordProviderRequest("turn", provider.RequestObservation{ID: id, Phase: "body_received", BodyBytes: int64(i)})
62 }
63 }
64 c.recordProviderRequest("old", provider.RequestObservation{ID: 1, Phase: "body_closed"})
65 var snapshot struct {
66 Requests []providerDiagnostic
67 Dropped uint64
68 }
69 data, err := json.Marshal(c.providerDiagnosticSnapshot())
70 if err != nil {
71 t.Fatal(err)
72 }
73 if err := json.Unmarshal(data, &snapshot); err != nil {
74 t.Fatal(err)
75 }
76 if len(snapshot.Requests) != 128 || snapshot.Dropped != 2 || snapshot.Requests[0].ID != 3 {
77 t.Fatalf("bounded snapshot: %s", data)
78 }
79 last := snapshot.Requests[127]
80 if last.TurnID != "turn" || last.BodyBytes != 300 {
81 t.Fatalf("latest observation: %+v", last)
82 }
83 c.recordProviderRequest("turn", provider.RequestObservation{ID: 130, Phase: "body_closed"})
84 if last.Phase != "body_received" {
85 t.Fatal("snapshot was mutated")
86 }
87 }
88
88 lines GO