Use focused candidate fixtures for release wrapper tests
This commit is contained in:
@@ -12,9 +12,6 @@ import (
|
||||
)
|
||||
|
||||
func TestReleaseWrapperPreservesNativeExitStatuses(t *testing.T) {
|
||||
if os.Getenv("RELEASEKIT_SKIP_WRAPPER_TEST") == "1" {
|
||||
t.Skip("release wrapper is already running candidate validation")
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("POSIX release entry point")
|
||||
}
|
||||
@@ -25,56 +22,53 @@ func TestReleaseWrapperPreservesNativeExitStatuses(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
controller, err := os.ReadFile(filepath.Join(root, "cmd/releasekit/main.go"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
updatedSources := map[string][]byte{}
|
||||
for _, path := range []string{
|
||||
"check.go", "publish.go", "delivery.go", "internal/candidate/check.go", "internal/delivery/delivery.go", "internal/publish/publish.go",
|
||||
"build_test.go", "publish_test.go", "internal/candidate/check_test.go",
|
||||
"internal/gitea/upload.go", "internal/gitea/upload_test.go",
|
||||
"delivery_test.go", "cmd/releasekit/main_test.go", "cmd/releasekit/release_wrapper_test.go",
|
||||
"cmd/releasekit/internal/cli/config_test.go", "examples/releasekit.json",
|
||||
"cmd/releasekit/internal/cli/config.go",
|
||||
} {
|
||||
contents, err := os.ReadFile(filepath.Join(root, path))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
updatedSources[path] = contents
|
||||
}
|
||||
wrapper, err := os.ReadFile(filepath.Join(root, "scripts/release"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sources := releaseWrapperSources(t, root)
|
||||
for _, mode := range []struct {
|
||||
name string
|
||||
status int
|
||||
version string
|
||||
}{{"success", 0, "v1.2.3"}, {"invalid", 2, "invalid"}, {"rejected", 1, "v1.2.3"}, {"unknown", 3, "v1.2.3"}} {
|
||||
t.Run(mode.name, func(t *testing.T) {
|
||||
t.Setenv("RELEASEKIT_SKIP_WRAPPER_TEST", "1")
|
||||
repository := filepath.Join(t.TempDir(), "source")
|
||||
clone := exec.Command(realGit, "clone", "--local", "--no-hardlinks", root, repository)
|
||||
if output, err := clone.CombinedOutput(); err != nil {
|
||||
t.Fatalf("clone: %v %s", err, output)
|
||||
for path, contents := range sources {
|
||||
name := filepath.Join(repository, path)
|
||||
if err := os.MkdirAll(filepath.Dir(name), 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(name, contents, 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := os.Chmod(filepath.Join(repository, "scripts/release"), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cliGitRun(t, repository, "init", "--initial-branch=main")
|
||||
cliGitRun(t, repository, "config", "user.name", "ReleaseKit Test")
|
||||
cliGitRun(t, repository, "config", "user.email", "fixture@example.test")
|
||||
cliGitRun(t, repository, "config", "commit.gpgsign", "false")
|
||||
if err := os.WriteFile(filepath.Join(repository, "scripts/release"), wrapper, 0755); err != nil {
|
||||
validationLog := filepath.Join(t.TempDir(), "validation.log")
|
||||
t.Setenv("RELEASEKIT_TEST_CANDIDATE_LOG", validationLog)
|
||||
candidateTest := `package releasekit
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReleaseCandidate(t *testing.T) {
|
||||
f, err := os.OpenFile(os.Getenv("RELEASEKIT_TEST_CANDIDATE_LOG"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err := f.WriteString("validated\n"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
`
|
||||
if err := os.WriteFile(filepath.Join(repository, "candidate_test.go"), []byte(candidateTest), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Exercise the current controller, including changes awaiting this commit.
|
||||
if err := os.WriteFile(filepath.Join(repository, "cmd/releasekit/main.go"), controller, 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for path, contents := range updatedSources {
|
||||
if err := os.WriteFile(filepath.Join(repository, filepath.FromSlash(path)), contents, 0600); err != nil {
|
||||
t.Fatalf("write current source %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(repository, "docs/releases"), 0700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -99,7 +93,7 @@ func TestReleaseWrapperPreservesNativeExitStatuses(t *testing.T) {
|
||||
cliGitRun(t, repository, "commit", "-m", "prepare wrapper fixture")
|
||||
remote := filepath.Join(t.TempDir(), "origin.git")
|
||||
cliGitRun(t, repository, "init", "--bare", remote)
|
||||
cliGitRun(t, repository, "remote", "set-url", "origin", remote)
|
||||
cliGitRun(t, repository, "remote", "add", "origin", remote)
|
||||
cliGitRun(t, repository, "push", "origin", "HEAD:refs/heads/main")
|
||||
fetch := filepath.Join(t.TempDir(), "fetch.git")
|
||||
cliGitRun(t, repository, "init", "--bare", fetch)
|
||||
@@ -138,7 +132,6 @@ exec "$RELEASEKIT_TEST_REAL_GIT" "$@"
|
||||
t.Setenv("RELEASEKIT_TEST_PUSH_MARKER", marker)
|
||||
t.Setenv("RELEASEKIT_TEST_MOVED_ENDPOINT", fetch)
|
||||
t.Setenv("RELEASEKIT_TEST_ARM_GIT_SHIM", armMarker)
|
||||
t.Setenv("RELEASEKIT_SKIP_WRAPPER_TEST", "1")
|
||||
}
|
||||
command := exec.Command("./scripts/release", mode.version)
|
||||
command.Dir = repository
|
||||
@@ -154,6 +147,14 @@ exec "$RELEASEKIT_TEST_REAL_GIT" "$@"
|
||||
if status != mode.status {
|
||||
t.Fatalf("status=%d want=%d output=%s", status, mode.status, output)
|
||||
}
|
||||
validated, readErr := os.ReadFile(validationLog)
|
||||
if mode.name == "invalid" {
|
||||
if !os.IsNotExist(readErr) {
|
||||
t.Fatalf("invalid input ran candidate validation: %q, %v", validated, readErr)
|
||||
}
|
||||
} else if readErr != nil || string(validated) != "validated\n" {
|
||||
t.Fatalf("candidate suite must run once: %q, %v", validated, readErr)
|
||||
}
|
||||
if mode.name == "unknown" {
|
||||
if !strings.Contains(string(output), fmt.Sprintf("endpoint=%q", remote)) {
|
||||
t.Fatalf("captured endpoint missing: %s", output)
|
||||
@@ -190,3 +191,30 @@ exec "$RELEASEKIT_TEST_REAL_GIT" "$@"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Capture current, nonignored source once, including worktree changes. The
|
||||
// candidate gets one small test instead of the project's full test suite.
|
||||
func releaseWrapperSources(t *testing.T, root string) map[string][]byte {
|
||||
t.Helper()
|
||||
list := exec.Command("git", "ls-files", "-z", "--cached", "--others", "--exclude-standard")
|
||||
list.Dir = root
|
||||
paths, err := list.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sources := make(map[string][]byte)
|
||||
for _, path := range strings.Split(string(paths), "\x00") {
|
||||
if path == "" || strings.HasSuffix(path, "_test.go") {
|
||||
continue
|
||||
}
|
||||
contents, err := os.ReadFile(filepath.Join(root, path))
|
||||
if os.IsNotExist(err) {
|
||||
continue // Tracked files removed from the current worktree.
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sources[path] = contents
|
||||
}
|
||||
return sources
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user