@@ -18,6 +18,8 @@ import (
18
18
"net/http/httptest"
19
19
"net/http/httputil"
20
20
"net/url"
21
+ "os"
22
+ "runtime"
21
23
"sort"
22
24
"strings"
23
25
"sync"
@@ -91,7 +93,7 @@ func TestStreamableTransports(t *testing.T) {
91
93
headerMu sync.Mutex
92
94
lastHeader http.Header
93
95
)
94
- httpServer := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
96
+ httpServer := httptest .NewServer (mustNotPanic ( t , http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
95
97
headerMu .Lock ()
96
98
lastHeader = r .Header
97
99
headerMu .Unlock ()
@@ -102,7 +104,7 @@ func TestStreamableTransports(t *testing.T) {
102
104
t .Errorf ("got cookie %q, want %q" , cookie .Value , "test-value" )
103
105
}
104
106
handler .ServeHTTP (w , r )
105
- }))
107
+ })))
106
108
defer httpServer .Close ()
107
109
108
110
// Create a client and connect it to the server using our StreamableClientTransport.
@@ -315,7 +317,7 @@ func testClientReplay(t *testing.T, test clientReplayTest) {
315
317
return new (CallToolResult ), nil , nil
316
318
})
317
319
318
- realServer := httptest .NewServer (NewStreamableHTTPHandler (func (* http.Request ) * Server { return server }, nil ))
320
+ realServer := httptest .NewServer (mustNotPanic ( t , NewStreamableHTTPHandler (func (* http.Request ) * Server { return server }, nil ) ))
319
321
defer realServer .Close ()
320
322
realServerURL , err := url .Parse (realServer .URL )
321
323
if err != nil {
@@ -324,6 +326,7 @@ func testClientReplay(t *testing.T, test clientReplayTest) {
324
326
325
327
// Configure a proxy that sits between the client and the real server.
326
328
proxyHandler := httputil .NewSingleHostReverseProxy (realServerURL )
329
+ // note: don't use mustNotPanic here as the proxy WILL panic when killed.
327
330
proxy := httptest .NewServer (proxyHandler )
328
331
proxyAddr := proxy .Listener .Addr ().String () // Get the address to restart it later.
329
332
@@ -434,7 +437,7 @@ func TestServerTransportCleanup(t *testing.T) {
434
437
chans [sessionID ] <- struct {}{}
435
438
}
436
439
437
- httpServer := httptest .NewServer (handler )
440
+ httpServer := httptest .NewServer (mustNotPanic ( t , handler ) )
438
441
defer httpServer .Close ()
439
442
440
443
ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
@@ -484,7 +487,7 @@ func TestServerInitiatedSSE(t *testing.T) {
484
487
notifications := make (chan string )
485
488
server := NewServer (testImpl , nil )
486
489
487
- httpServer := httptest .NewServer (NewStreamableHTTPHandler (func (* http.Request ) * Server { return server }, nil ))
490
+ httpServer := httptest .NewServer (mustNotPanic ( t , NewStreamableHTTPHandler (func (* http.Request ) * Server { return server }, nil ) ))
488
491
defer httpServer .Close ()
489
492
490
493
ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
@@ -857,7 +860,7 @@ func TestStreamableServerTransport(t *testing.T) {
857
860
}
858
861
859
862
func testStreamableHandler (t * testing.T , handler http.Handler , requests []streamableRequest ) {
860
- httpServer := httptest .NewServer (handler )
863
+ httpServer := httptest .NewServer (mustNotPanic ( t , handler ) )
861
864
defer httpServer .Close ()
862
865
863
866
// blocks records request blocks by jsonrpc. ID.
@@ -1247,7 +1250,7 @@ func TestStreamableStateless(t *testing.T) {
1247
1250
1248
1251
testClientCompatibility := func (t * testing.T , handler http.Handler ) {
1249
1252
ctx := context .Background ()
1250
- httpServer := httptest .NewServer (handler )
1253
+ httpServer := httptest .NewServer (mustNotPanic ( t , handler ) )
1251
1254
defer httpServer .Close ()
1252
1255
cs , err := NewClient (testImpl , nil ).Connect (ctx , & StreamableClientTransport {Endpoint : httpServer .URL }, nil )
1253
1256
if err != nil {
@@ -1332,7 +1335,7 @@ func TestTokenInfo(t *testing.T) {
1332
1335
}, nil
1333
1336
}
1334
1337
handler := auth .RequireBearerToken (verifier , nil )(streamHandler )
1335
- httpServer := httptest .NewServer (handler )
1338
+ httpServer := httptest .NewServer (mustNotPanic ( t , handler ) )
1336
1339
defer httpServer .Close ()
1337
1340
1338
1341
transport := & StreamableClientTransport {Endpoint : httpServer .URL }
@@ -1366,7 +1369,7 @@ func TestStreamableGET(t *testing.T) {
1366
1369
server := NewServer (testImpl , nil )
1367
1370
1368
1371
handler := NewStreamableHTTPHandler (func (req * http.Request ) * Server { return server }, nil )
1369
- httpServer := httptest .NewServer (handler )
1372
+ httpServer := httptest .NewServer (mustNotPanic ( t , handler ) )
1370
1373
defer httpServer .Close ()
1371
1374
1372
1375
ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
@@ -1442,7 +1445,7 @@ func TestStreamableClientContextPropagation(t *testing.T) {
1442
1445
defer cancel ()
1443
1446
ctx2 := context .WithValue (ctx , testKey , testValue )
1444
1447
1445
- server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
1448
+ server := httptest .NewServer (mustNotPanic ( t , http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
1446
1449
switch req .Method {
1447
1450
case "POST" :
1448
1451
w .Header ().Set ("Content-Type" , "application/json" )
@@ -1455,7 +1458,7 @@ func TestStreamableClientContextPropagation(t *testing.T) {
1455
1458
case "DELETE" :
1456
1459
w .WriteHeader (http .StatusNoContent )
1457
1460
}
1458
- }))
1461
+ })))
1459
1462
defer server .Close ()
1460
1463
1461
1464
transport := & StreamableClientTransport {Endpoint : server .URL }
@@ -1486,3 +1489,19 @@ func TestStreamableClientContextPropagation(t *testing.T) {
1486
1489
}
1487
1490
1488
1491
}
1492
+
1493
+ // mustNotPanic is a helper to enforce that test handlers do not panic (see
1494
+ // issue #556).
1495
+ func mustNotPanic (t * testing.T , h http.Handler ) http.Handler {
1496
+ return http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
1497
+ defer func () {
1498
+ if r := recover (); r != nil {
1499
+ buf := make ([]byte , 1 << 20 )
1500
+ n := runtime .Stack (buf , false )
1501
+ fmt .Fprintf (os .Stderr , "handler panic: %v\n \n %s" , r , buf [:n ])
1502
+ t .Errorf ("handler panicked: %v" , r )
1503
+ }
1504
+ }()
1505
+ h .ServeHTTP (w , req )
1506
+ })
1507
+ }
0 commit comments