Files
gocp/tool_gotest.go

106 lines
2.4 KiB
Go
Raw Permalink Normal View History

package main
import (
"context"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
)
type GoTestResult struct {
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
ExitCode int `json:"exit_code"`
Error string `json:"error,omitempty"`
Command string `json:"command"`
WorkDir string `json:"work_dir"`
Passed bool `json:"passed"`
TestCount int `json:"test_count,omitempty"`
}
func goTest(path string, flags []string, timeout time.Duration) (*GoTestResult, error) {
// Resolve absolute path
absPath, err := filepath.Abs(path)
if err != nil {
return &GoTestResult{
Error: err.Error(),
Command: "go test " + path,
}, nil
}
// Determine working directory and target
var workDir string
var target string
// Check if path is a file or directory
info, err := os.Stat(absPath)
if err != nil {
return &GoTestResult{
Error: err.Error(),
Command: "go test " + path,
}, nil
}
if info.IsDir() {
// Testing a package
workDir = absPath
target = "."
} else {
// Testing a specific file (though go test typically works with packages)
workDir = filepath.Dir(absPath)
target = "."
}
// Build command arguments
args := []string{"test"}
args = append(args, flags...)
args = append(args, target)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
cmd := exec.CommandContext(ctx, "go", args...)
cmd.Dir = workDir
stdout, stderr, exitCode, cmdErr := runCommand(cmd)
result := &GoTestResult{
Stdout: stdout,
Stderr: stderr,
ExitCode: exitCode,
Command: "go " + strings.Join(args, " "),
WorkDir: workDir,
Passed: exitCode == 0,
}
// Try to extract test count from output
if strings.Contains(stdout, "PASS") || strings.Contains(stdout, "FAIL") {
result.TestCount = countTests(stdout)
}
if cmdErr != nil {
if ctx.Err() == context.DeadlineExceeded {
result.Error = "execution timeout exceeded"
} else {
result.Error = cmdErr.Error()
}
}
return result, nil
}
// Helper function to count tests from go test output
func countTests(output string) int {
count := 0
lines := strings.Split(output, "\n")
for _, line := range lines {
if strings.HasPrefix(strings.TrimSpace(line), "--- PASS:") ||
strings.HasPrefix(strings.TrimSpace(line), "--- FAIL:") ||
strings.HasPrefix(strings.TrimSpace(line), "--- SKIP:") {
count++
}
}
return count
}