scripts/e2e_cover_test.go
Rama main · réplica de lectura del repositorio original.
package scripts_test
import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
)
func buildInstrumented(t *testing.T) string {
t.Helper()
dir := t.TempDir()
sources := map[string]string{
"go.mod": "module hello\n\ngo 1.27\n",
"main.go": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(\"hello\")\n}\n",
}
for name, body := range sources {
if err := os.WriteFile(filepath.Join(dir, name), []byte(body), 0o600); err != nil {
t.Fatalf("write %s: %v", name, err)
}
}
binary := filepath.Join(dir, "hello")
build := exec.Command("go", "build", "-cover", "-covermode=atomic", "-o", binary, ".")
build.Dir = dir
if out, err := build.CombinedOutput(); err != nil {
t.Fatalf("build instrumented program: %v\n%s", err, out)
}
return binary
}
func runInstrumented(t *testing.T, binary, counters string) {
t.Helper()
if err := os.MkdirAll(counters, 0o700); err != nil {
t.Fatalf("make %s: %v", counters, err)
}
cmd := exec.Command(binary)
cmd.Env = append(os.Environ(), "GOCOVERDIR="+counters)
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("run instrumented program: %v\n%s", err, out)
}
}
func runE2ECover(t *testing.T, env []string, args ...string) (string, error) {
t.Helper()
if runtime.GOOS == "windows" {
t.Skip("the e2e coverage merge runs in the Linux CI job")
}
cmd := exec.Command("bash", append([]string{"e2e-cover.sh"}, args...)...)
cmd.Env = append(os.Environ(), env...)
out, err := cmd.CombinedOutput()
return string(out), err
}
func TestE2ECoverMergesEveryInstance(t *testing.T) {
binary := buildInstrumented(t)
dir := t.TempDir()
runInstrumented(t, binary, filepath.Join(dir, "main"))
runInstrumented(t, binary, filepath.Join(dir, "readonly"))
profile := filepath.Join(dir, "coverage.out")
out, err := runE2ECover(t, nil, dir, profile)
if err != nil {
t.Fatalf("merge: %v\n%s", err, out)
}
for _, want := range []string{
"E2E Go coverage: 100.0%",
"2 instrumented instances were merged.",
"hello",
"coverage: 100.0% of statements",
} {
if !strings.Contains(out, want) {
t.Errorf("output lacks %q:\n%s", want, out)
}
}
written, readErr := os.ReadFile(profile)
if readErr != nil {
t.Fatalf("read profile: %v", readErr)
}
if !strings.HasPrefix(string(written), "mode: atomic") {
t.Fatalf("profile starts with %q, want an atomic mode line", firstLine(string(written)))
}
}
func TestE2ECoverMarksASelectiveRunPartial(t *testing.T) {
binary := buildInstrumented(t)
dir := t.TempDir()
runInstrumented(t, binary, filepath.Join(dir, "job-a"))
runInstrumented(t, binary, filepath.Join(dir, "job-b"))
summary := filepath.Join(t.TempDir(), "summary.md")
out, err := runE2ECover(t, []string{"GITHUB_STEP_SUMMARY=" + summary}, dir, filepath.Join(dir, "coverage.out"), "39", "2", "16")
if err != nil {
t.Fatalf("merge: %v\n%s", err, out)
}
for _, want := range []string{
"E2E Go coverage (partial): 100.0%",
"2 of 39 browser jobs contributed coverage.",
"2 of 16 groups were selected for this change.",
} {
if !strings.Contains(out, want) {
t.Errorf("output lacks %q:\n%s", want, out)
}
}
written, readErr := os.ReadFile(summary)
if readErr != nil {
t.Fatalf("read step summary: %v", readErr)
}
if !strings.HasPrefix(string(written), "## E2E Go coverage (partial): 100.0%\n") {
t.Fatalf("step summary starts with %q", firstLine(string(written)))
}
if strings.Count(string(written), "```") != 2 {
t.Fatalf("step summary has %d fences, want 2:\n%s", strings.Count(string(written), "```"), written)
}
}
func TestE2ECoverRefusesAnInstanceThatWasKilled(t *testing.T) {
binary := buildInstrumented(t)
dir := t.TempDir()
runInstrumented(t, binary, filepath.Join(dir, "main"))
marker := filepath.Join(dir, "readonly.unclean")
if err := os.WriteFile(marker, []byte("pid 4242 was still running\n"), 0o600); err != nil {
t.Fatalf("write marker: %v", err)
}
out, err := runE2ECover(t, nil, dir, filepath.Join(dir, "coverage.out"))
if code := exitCode(t, err); code != 1 {
t.Fatalf("exit code = %d, want 1\n%s", code, out)
}
if !strings.Contains(out, "killed before they could write their counters") {
t.Fatalf("output does not name the killed instance:\n%s", out)
}
if !strings.Contains(out, "readonly.unclean: pid 4242 was still running") {
t.Fatalf("output does not quote the marker:\n%s", out)
}
}
func TestE2ECoverRefusesADirectoryWithoutCounters(t *testing.T) {
dir := t.TempDir()
out, err := runE2ECover(t, nil, dir, filepath.Join(dir, "coverage.out"))
if code := exitCode(t, err); code != 1 {
t.Fatalf("exit code = %d, want 1\n%s", code, out)
}
if !strings.Contains(out, "no counter files under") {
t.Fatalf("output does not explain the missing counters:\n%s", out)
}
}
func TestE2ECoverRefusesAMissingDirectory(t *testing.T) {
dir := filepath.Join(t.TempDir(), "never-created")
out, err := runE2ECover(t, nil, dir, filepath.Join(t.TempDir(), "coverage.out"))
if code := exitCode(t, err); code != 1 {
t.Fatalf("exit code = %d, want 1\n%s", code, out)
}
if !strings.Contains(out, "does not exist; the suite did not run") {
t.Fatalf("output does not say the suite did not run:\n%s", out)
}
}
func firstLine(text string) string {
line, _, _ := strings.Cut(text, "\n")
return line
}