Files
cc-connect/agent/codex/integration_test.go
2026-06-02 23:14:41 +08:00

110 lines
3.1 KiB
Go

package codex
import (
"encoding/json"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
// TestIntegration_CodexProviderFlow verifies the full provider config flow:
// 1. ensureCodexProviderConfig writes correct config.toml
// 2. ensureCodexAuth writes correct auth.json
// 3. Codex CLI can authenticate and respond using the written config
//
// Requires: SHENGSUANYUN_API_KEY env var and `codex` CLI in PATH.
// Skip with: go test ./agent/codex/ -run TestIntegration -v
func TestIntegration_CodexProviderFlow(t *testing.T) {
apiKey := os.Getenv("SHENGSUANYUN_API_KEY")
if apiKey == "" {
t.Skip("SHENGSUANYUN_API_KEY not set, skipping integration test")
}
if _, err := exec.LookPath("codex"); err != nil {
t.Skip("codex CLI not in PATH, skipping integration test")
}
home := filepath.Join(t.TempDir(), ".codex")
// Step 1: write config.toml via our function
err := ensureCodexProviderConfig(home, "shengsuanyun-codex",
"https://router.shengsuanyun.com/api/v1", "responses", nil)
if err != nil {
t.Fatalf("ensureCodexProviderConfig: %v", err)
}
// Verify config.toml content
cfgData, err := os.ReadFile(filepath.Join(home, "config.toml"))
if err != nil {
t.Fatalf("read config.toml: %v", err)
}
cfgContent := string(cfgData)
t.Logf("Generated config.toml:\n%s", cfgContent)
for _, want := range []string{
`[model_providers.shengsuanyun-codex]`,
`base_url = "https://router.shengsuanyun.com/api/v1"`,
`wire_api = "responses"`,
`env_key = "OPENAI_API_KEY"`,
} {
if !strings.Contains(cfgContent, want) {
t.Errorf("config.toml missing: %s", want)
}
}
// Step 2: write auth.json via our function
err = ensureCodexAuth(home, apiKey)
if err != nil {
t.Fatalf("ensureCodexAuth: %v", err)
}
// Verify auth.json content
authData, err := os.ReadFile(filepath.Join(home, "auth.json"))
if err != nil {
t.Fatalf("read auth.json: %v", err)
}
var authMap map[string]any
if err := json.Unmarshal(authData, &authMap); err != nil {
t.Fatalf("parse auth.json: %v", err)
}
if authMap["auth_mode"] != "apikey" {
t.Errorf("auth_mode = %v, want apikey", authMap["auth_mode"])
}
if authMap["OPENAI_API_KEY"] != apiKey {
t.Errorf("OPENAI_API_KEY not set correctly in auth.json")
}
// Step 3: run codex exec with the generated config
workDir := filepath.Join(t.TempDir(), "repo")
os.MkdirAll(workDir, 0o755)
gitInit := exec.Command("git", "init", "-q")
gitInit.Dir = workDir
if err := gitInit.Run(); err != nil {
t.Fatalf("git init: %v", err)
}
cmd := exec.Command("codex", "exec",
"--model", "openai/gpt-5.3-codex",
"-c", `model_provider="shengsuanyun-codex"`,
"-c", `openai_base_url="https://router.shengsuanyun.com/api/v1"`,
"--full-auto",
)
cmd.Dir = workDir
cmd.Env = append(os.Environ(),
"CODEX_HOME="+home,
"OPENAI_API_KEY="+apiKey,
)
cmd.Stdin = strings.NewReader("reply with exactly 'integration-ok' and nothing else")
output, err := cmd.CombinedOutput()
t.Logf("Codex output:\n%s", string(output))
if err != nil {
t.Fatalf("codex exec failed: %v\noutput: %s", err, output)
}
if !strings.Contains(string(output), "integration-ok") {
t.Errorf("expected 'integration-ok' in output, got:\n%s", output)
}
}