Files
mcp/internal/agent/testhelpers_test.go
Kyle Isom 8b1c89fdc9 Add mcp build command and deploy auto-build
Extends MCP to own the full build-push-deploy lifecycle. When deploying,
the CLI checks whether each component's image tag exists in the registry
and builds/pushes automatically if missing and build config is present.

- Add Build, Push, ImageExists to runtime.Runtime interface (podman impl)
- Add mcp build <service>[/<image>] command
- Add [build] section to CLI config (workspace path)
- Add path and [build.images] to service definitions
- Wire auto-build into mcp deploy before agent RPC
- Update ARCHITECTURE.md with runtime interface and deploy auto-build docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 01:34:25 -07:00

66 lines
1.9 KiB
Go

package agent
import (
"context"
"log/slog"
"path/filepath"
"testing"
"git.wntrmute.dev/kyle/mcp/internal/config"
"git.wntrmute.dev/kyle/mcp/internal/registry"
"git.wntrmute.dev/kyle/mcp/internal/runtime"
)
// fakeRuntime implements runtime.Runtime for testing.
type fakeRuntime struct {
containers []runtime.ContainerInfo
inspectMap map[string]runtime.ContainerInfo
listErr error
}
func (f *fakeRuntime) Pull(_ context.Context, _ string) error { return nil }
func (f *fakeRuntime) Run(_ context.Context, _ runtime.ContainerSpec) error { return nil }
func (f *fakeRuntime) Stop(_ context.Context, _ string) error { return nil }
func (f *fakeRuntime) Remove(_ context.Context, _ string) error { return nil }
func (f *fakeRuntime) Build(_ context.Context, _, _, _ string) error { return nil }
func (f *fakeRuntime) Push(_ context.Context, _ string) error { return nil }
func (f *fakeRuntime) ImageExists(_ context.Context, _ string) (bool, error) { return true, nil }
func (f *fakeRuntime) List(_ context.Context) ([]runtime.ContainerInfo, error) {
return f.containers, f.listErr
}
func (f *fakeRuntime) Inspect(_ context.Context, name string) (runtime.ContainerInfo, error) {
if f.inspectMap != nil {
if info, ok := f.inspectMap[name]; ok {
return info, nil
}
}
for _, c := range f.containers {
if c.Name == name {
return c, nil
}
}
return runtime.ContainerInfo{}, nil
}
// newTestAgent creates an Agent with a temp database for testing.
func newTestAgent(t *testing.T, rt runtime.Runtime) *Agent {
t.Helper()
db, err := registry.Open(filepath.Join(t.TempDir(), "test.db"))
if err != nil {
t.Fatalf("open test db: %v", err)
}
t.Cleanup(func() { _ = db.Close() })
return &Agent{
Config: &config.AgentConfig{
Agent: config.AgentSettings{NodeName: "test-node"},
},
DB: db,
Runtime: rt,
Logger: slog.Default(),
}
}