Files
agentic-coding-workflow/internal/acp/test_helpers_test.go
T

87 lines
2.8 KiB
Go

//go:build integration
// test_helpers_test.go 是 supervisor_test.go 的共享脚手架:
// - notifyRepoStub:满足 notify.Repository(5 方法),让 dispatcher 落库变成空操作
// - slogDiscard:丢弃日志的 logger
// - encryptForTest:用与 AgentKindService 相同格式产出加密 env(map → JSON → AES-GCM)
// - fakeAgentBinary:构建 cmd/fake-acp-agent 二进制供子进程 spawn
//
// 集成测试专用,不参与 go test 默认 build。
package acp_test
import (
"context"
"encoding/json"
"io"
"log/slog"
"os"
"os/exec"
"path/filepath"
"runtime"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/yan1h/agent-coding-workflow/internal/infra/notify"
)
// notifyRepoStub 实现 notify.Repository 全部 5 方法。supervisor.onExit
// 会通过 dispatcher 落库一条 crashed 通知,落库走 stub → 永远成功 + 不存。
type notifyRepoStub struct{}
func (notifyRepoStub) Insert(context.Context, notify.Message) error { return nil }
func (notifyRepoStub) List(context.Context, uuid.UUID, bool, int) ([]notify.Message, error) {
return nil, nil
}
func (notifyRepoStub) CountUnread(context.Context, uuid.UUID) (int, error) { return 0, nil }
func (notifyRepoStub) MarkRead(context.Context, uuid.UUID, uuid.UUID) error { return nil }
func (notifyRepoStub) MarkAllRead(context.Context, uuid.UUID) error { return nil }
// slogDiscard 返回静音 logger,避免测试输出污染。
func slogDiscard() *slog.Logger { return slog.New(slog.NewTextHandler(io.Discard, nil)) }
// encryptForTest 以 AgentKindService 同格式(JSON marshal → AES-GCM)产出
// EncryptedEnv 字节,让 supervisor.decryptEnv 还原为同一 map。
func encryptForTest(t *testing.T, m map[string]string) []byte {
t.Helper()
enc := testEncryptor(t)
plain, err := json.Marshal(m)
require.NoError(t, err)
out, err := enc.Encrypt(plain)
require.NoError(t, err)
return out
}
// repoRoot 从测试 cwd 向上找 go.mod,返回仓库根目录。t.TempDir + go build 用。
func repoRoot(t *testing.T) string {
t.Helper()
wd, err := os.Getwd()
require.NoError(t, err)
for {
if _, err := os.Stat(filepath.Join(wd, "go.mod")); err == nil {
return wd
}
parent := filepath.Dir(wd)
if parent == wd {
t.Fatal("go.mod not found upward")
}
wd = parent
}
}
// fakeAgentBinary 编译 cmd/fake-acp-agent 到 t.TempDir() 并返回路径。
// 测试结束后 t.TempDir 自动清理。
func fakeAgentBinary(t *testing.T) string {
t.Helper()
bin := filepath.Join(t.TempDir(), "fake-acp-agent")
if runtime.GOOS == "windows" {
bin += ".exe"
}
cmd := exec.Command("go", "build", "-o", bin, "./cmd/fake-acp-agent")
cmd.Dir = repoRoot(t)
out, err := cmd.CombinedOutput()
require.NoError(t, err, "build fake-acp-agent: %s", out)
return bin
}