71 lines
1.9 KiB
Go
71 lines
1.9 KiB
Go
package mcpclient
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/modelcontextprotocol/go-sdk/mcp"
|
|
)
|
|
|
|
func TestAgentToolSessionsNamespacingDisableAndLeaseCancellation(t *testing.T) {
|
|
var calls atomic.Int32
|
|
server := newTestMCPServer(&calls)
|
|
remote := httptest.NewServer(mcp.NewStreamableHTTPHandler(func(*http.Request) *mcp.Server { return server }, nil))
|
|
defer remote.Close()
|
|
service, _ := testService(t)
|
|
var ids []string
|
|
for _, name := range []string{"phone", "files"} {
|
|
view, err := service.SaveServer(ServerInput{Config: ServerConfig{Name: name, Transport: "http", URL: remote.URL, Enabled: true, TimeoutSeconds: 3}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ids = append(ids, view.Config.ID)
|
|
}
|
|
first, err := OpenTools(context.Background(), service, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer first.Close()
|
|
if len(first.Tools()) != 4 {
|
|
t.Fatalf("tools: %d", len(first.Tools()))
|
|
}
|
|
unique := map[string]bool{}
|
|
for _, tool := range first.Tools() {
|
|
if unique[tool.Name] {
|
|
t.Fatal("duplicate tool name")
|
|
}
|
|
unique[tool.Name] = true
|
|
}
|
|
name := first.Tools()[0].Name
|
|
if _, err := first.Call(context.Background(), name, `{}`); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
second, err := OpenTools(context.Background(), service, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer second.Close()
|
|
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
|
|
defer cancel()
|
|
if _, err := second.Call(ctx, second.Tools()[0].Name, `{}`); !errors.Is(err, context.DeadlineExceeded) {
|
|
t.Fatalf("waiting lease did not cancel: %v", err)
|
|
}
|
|
if calls.Load() != 1 {
|
|
t.Fatal("parallel action bypassed sequence lease")
|
|
}
|
|
if err := service.SetEnabled(ids[0], false); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := first.Call(context.Background(), name, `{}`); err == nil {
|
|
t.Fatal("disabled service still executed")
|
|
}
|
|
if calls.Load() != 1 {
|
|
t.Fatal("disabled service was invoked")
|
|
}
|
|
}
|