Files
bifrost/core/internal/mcptests/stdio_timeout_test.go
Beyhan Oğur 880f412e2c first commit
2026-04-26 21:52:23 +03:00

79 lines
2.7 KiB
Go

package mcptests
import (
"testing"
"time"
"github.com/maximhq/bifrost/core/schemas"
)
// TestSTDIO_InitTimeout verifies that STDIO initialization fails gracefully
// when the subprocess cannot be launched (invalid command path).
//
// This test validates that:
// 1. Invalid subprocess paths are detected during Start() phase
// 2. The error is returned immediately (no hang)
// 3. Manager setup completes even when a client fails to connect
//
// Note: This tests the "subprocess launch failure" scenario. The timeout fix
// also handles "subprocess launches but doesn't respond" scenarios, which would
// require a mock server that launches but never sends Initialize response.
func TestSTDIO_InitTimeout(t *testing.T) {
// Initialize global MCP server paths
InitMCPServerPaths(t)
// Create a broken STDIO client by using an invalid path
brokenClient := GetGoTestServerConfig(mcpServerPaths.ExamplesRoot)
brokenClient.ID = "broken-stdio"
brokenClient.Name = "BrokenSTDIOServer"
// Corrupt the command path to cause subprocess launch failure
brokenClient.StdioConfig.Command = brokenClient.StdioConfig.Command + "-INVALID"
brokenClient.IsCodeModeClient = false
brokenClient.ToolsToExecute = []string{"*"}
t.Log("Testing STDIO initialization timeout with broken path...")
start := time.Now()
// This should fail after 30 seconds, not hang indefinitely
// We expect setupMCPManager to fail because the client can't initialize
defer func() {
if r := recover(); r != nil {
elapsed := time.Since(start)
t.Logf("Manager setup panicked after %v: %v", elapsed, r)
// Verify it failed within reasonable time (< 35 seconds to allow some buffer)
if elapsed > 35*time.Second {
t.Fatalf("Initialization took too long (%v), should timeout after 30s", elapsed)
}
t.Logf("✅ Failed as expected within timeout period (%v)", elapsed)
}
}()
// Try to setup manager - this will fail when client can't initialize
manager := setupMCPManager(t, brokenClient)
elapsed := time.Since(start)
// If we get here, check if the client actually connected.
// Disconnected entries may be retained in memory for auto-recovery,
// so only count non-disconnected clients as "connected".
clients := manager.GetClients()
connectedClients := 0
for _, c := range clients {
if c.State != schemas.MCPConnectionStateDisconnected {
connectedClients++
}
}
if connectedClients > 0 {
t.Fatalf("Expected no clients to connect, but got %d", connectedClients)
}
// Verify it failed quickly (< 35 seconds)
if elapsed > 35*time.Second {
t.Fatalf("Initialization took too long (%v), should timeout after 30s", elapsed)
}
t.Logf("✅ Initialization failed within timeout period (%v)", elapsed)
}