Files
Agent-Native/runtime/mcp/r2_regression_test.go
T
weichenandCursor 17f2a4ecfa Close the native P1 gaps the audit listed for this batch
Why: token budget let the current tool batch run, compaction could split a tool pair or race an append, writes were not crash-atomic, and several MCP and session edges only existed as comments.
Evidence: GOWORK=off go test -count=1 -race ./runtime/ ./runtime/llm/ ./runtime/session/ ./runtime/tools/ ./runtime/mcp/ ./adapters/native/ ./adapters/intentgate/ passed, including the TestR2* cases for budget, replacement, cancel, compaction, SSE, UTF-8, schema, MCP retry, session terminate, poison reload, and registry reload.
Impact: over-budget tool calls are skipped and paired; Stop.Replacement is appended to the session; the intent gate can follow Registry.Reload.
Refs: N5, N6, N7, N8, N9, N11, N12, N15, N16, N17, N18, N19, N21, I9
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 13:05:58 +00:00

67 lines
1.8 KiB
Go

package mcp
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
type flakyClient struct {
fail bool
calls int
}
func (f *flakyClient) Initialize(context.Context) (initializeResult, error) {
return initializeResult{}, nil
}
func (f *flakyClient) ListTools(context.Context) ([]toolInfo, error) { return nil, nil }
func (f *flakyClient) Close() error { return nil }
func (f *flakyClient) CallTool(context.Context, string, json.RawMessage) (callToolResult, error) {
f.calls++
if f.fail {
return callToolResult{}, fmt.Errorf("down")
}
return callToolResult{Content: []contentBlock{{Type: "text", Text: "back"}}}, nil
}
func TestR2MCPRetriesOnceAfterReconnect(t *testing.T) {
first := &flakyClient{fail: true}
second := &flakyClient{}
tool := &bridgeTool{
client: first,
toolName: "echo",
declName: "mcp__s__echo",
redial: func(context.Context) (Client, error) {
return second, nil
},
}
res, err := tool.Execute(context.Background(), []byte(`{}`))
if err != nil || res.IsError {
t.Fatalf("retry: %+v %v", res, err)
}
if first.calls != 1 || second.calls != 1 || !strings.Contains(res.Content, "back") {
t.Fatalf("calls first=%d second=%d content=%q", first.calls, second.calls, res.Content)
}
}
func TestR2HTTPCloseTerminatesSession(t *testing.T) {
var method, sid string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
method = r.Method
sid = r.Header.Get("Mcp-Session-Id")
w.WriteHeader(http.StatusOK)
}))
defer srv.Close()
c := &httpClient{cfg: ServerConfig{URL: srv.URL}, client: &http.Client{}, sessionID: "sess-1"}
if err := c.Close(); err != nil {
t.Fatal(err)
}
if method != http.MethodDelete || sid != "sess-1" {
t.Fatalf("terminate %s session %q", method, sid)
}
}