fix(mcp/docker): harden tests

Christian Rocha created

Change summary

internal/config/docker_mcp.go      |  8 +++-
internal/config/docker_mcp_test.go | 53 +++++++++++++++++++++++--------
2 files changed, 45 insertions(+), 16 deletions(-)

Detailed changes

internal/config/docker_mcp.go 🔗

@@ -7,6 +7,11 @@ import (
 	"time"
 )
 
+var dockerMCPVersionRunner = func(ctx context.Context) error {
+	cmd := exec.CommandContext(ctx, "docker", "mcp", "version")
+	return cmd.Run()
+}
+
 // DockerMCPName is the name of the Docker MCP configuration.
 const DockerMCPName = "docker"
 
@@ -16,8 +21,7 @@ func IsDockerMCPAvailable() bool {
 	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 	defer cancel()
 
-	cmd := exec.CommandContext(ctx, "docker", "mcp", "version")
-	err := cmd.Run()
+	err := dockerMCPVersionRunner(ctx)
 	return err == nil
 }
 

internal/config/docker_mcp_test.go 🔗

@@ -1,6 +1,8 @@
 package config
 
 import (
+	"context"
+	"errors"
 	"os"
 	"path/filepath"
 	"testing"
@@ -9,6 +11,17 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
+var errDockerUnavailable = errors.New("docker unavailable")
+
+func setDockerMCPVersionRunner(t *testing.T, runner func(context.Context) error) {
+	t.Helper()
+	orig := dockerMCPVersionRunner
+	dockerMCPVersionRunner = runner
+	t.Cleanup(func() {
+		dockerMCPVersionRunner = orig
+	})
+}
+
 func TestIsDockerMCPEnabled(t *testing.T) {
 	t.Parallel()
 
@@ -43,10 +56,8 @@ func TestIsDockerMCPEnabled(t *testing.T) {
 }
 
 func TestEnableDockerMCP(t *testing.T) {
-	t.Parallel()
-
 	t.Run("adds docker mcp to config", func(t *testing.T) {
-		t.Parallel()
+		setDockerMCPVersionRunner(t, func(context.Context) error { return nil })
 
 		// Create a temporary directory for config.
 		tmpDir := t.TempDir()
@@ -61,11 +72,6 @@ func TestEnableDockerMCP(t *testing.T) {
 			resolver:       NewShellVariableResolver(env.New()),
 		}
 
-		// Only run this test if docker mcp is available.
-		if !IsDockerMCPAvailable() {
-			t.Skip("Docker MCP not available, skipping test")
-		}
-
 		err := store.EnableDockerMCP()
 		require.NoError(t, err)
 
@@ -86,7 +92,7 @@ func TestEnableDockerMCP(t *testing.T) {
 	})
 
 	t.Run("fails when docker mcp not available", func(t *testing.T) {
-		t.Parallel()
+		setDockerMCPVersionRunner(t, func(context.Context) error { return errDockerUnavailable })
 
 		// Create a temporary directory for config.
 		tmpDir := t.TempDir()
@@ -101,11 +107,6 @@ func TestEnableDockerMCP(t *testing.T) {
 			resolver:       NewShellVariableResolver(env.New()),
 		}
 
-		// Skip if docker mcp is actually available.
-		if IsDockerMCPAvailable() {
-			t.Skip("Docker MCP is available, skipping unavailable test")
-		}
-
 		err := store.EnableDockerMCP()
 		require.Error(t, err)
 		require.Contains(t, err.Error(), "docker mcp is not available")
@@ -166,3 +167,27 @@ func TestDisableDockerMCP(t *testing.T) {
 		require.NoError(t, err)
 	})
 }
+
+func TestEnableDockerMCPWithRealDockerWhenAvailable(t *testing.T) {
+	t.Parallel()
+
+	if !IsDockerMCPAvailable() {
+		t.Skip("docker mcp not available on this machine")
+	}
+
+	tmpDir := t.TempDir()
+	configPath := filepath.Join(tmpDir, "crush.json")
+
+	cfg := &Config{
+		MCP: make(map[string]MCPConfig),
+	}
+	store := &ConfigStore{
+		config:         cfg,
+		globalDataPath: configPath,
+		resolver:       NewShellVariableResolver(env.New()),
+	}
+
+	err := store.EnableDockerMCP()
+	require.NoError(t, err)
+	require.True(t, cfg.IsDockerMCPEnabled())
+}