103 lines
3.6 KiB
Go
103 lines
3.6 KiB
Go
package delivery
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
|
|
"go.maximumdirect.net/releasekit/internal/artifact"
|
|
internalbuild "go.maximumdirect.net/releasekit/internal/build"
|
|
"go.maximumdirect.net/releasekit/internal/forge"
|
|
)
|
|
|
|
func deliveryCleanupFixture(t *testing.T) (string, string) {
|
|
t.Helper()
|
|
repo := t.TempDir()
|
|
files := map[string]string{
|
|
"go.mod": "module example.com/delivery\n\ngo 1.25.0\n",
|
|
"main.go": "package main\nimport \"fmt\"\nfunc main() { fmt.Println(\"fixture v1.2.3\") }\n",
|
|
"docs/releases/v1.2.3.md": "# Fixture v1.2.3\n\nNote.\n",
|
|
}
|
|
for name, contents := range files {
|
|
path := filepath.Join(repo, filepath.FromSlash(name))
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(path, []byte(contents), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
for _, args := range [][]string{{"init", "-b", "main"}, {"config", "user.name", "Fixture"}, {"config", "user.email", "fixture@example.invalid"}, {"add", "."}, {"commit", "-m", "fixture"}, {"tag", "v1.2.3"}} {
|
|
command := exec.Command("git", args...)
|
|
command.Dir = repo
|
|
if data, err := command.CombinedOutput(); err != nil {
|
|
t.Fatalf("git %v: %v: %s", args, err, data)
|
|
}
|
|
}
|
|
command := exec.Command("git", "rev-parse", "HEAD")
|
|
command.Dir = repo
|
|
commit, err := command.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return repo, strings.TrimSpace(string(commit))
|
|
}
|
|
|
|
type cancelBuildOutput struct{ cancel context.CancelFunc }
|
|
|
|
func (writer cancelBuildOutput) Write(p []byte) (int, error) {
|
|
if strings.Contains(string(p), "building ") {
|
|
writer.cancel()
|
|
}
|
|
return len(p), nil
|
|
}
|
|
|
|
func TestManagedDeliveryCleanupPreservesOutcome(t *testing.T) {
|
|
for _, mode := range []string{"complete", "build failure", "cancellation"} {
|
|
t.Run(mode, func(t *testing.T) {
|
|
repo, commit := deliveryCleanupFixture(t)
|
|
note := "# Fixture v1.2.3\n\nNote.\n"
|
|
backend := &assetBackend{pageBackend: pageBackend{commit: commit, findResults: []pageFindResult{{release: forge.Release{Tag: "v1.2.3", Body: note, Handle: "release", URL: "https://example.invalid/release"}}}}, lists: []assetListResult{{}}}
|
|
ctx, cancel := context.WithCancel(t.Context())
|
|
defer cancel()
|
|
spec := internalbuild.Spec{MainPackage: ".", BinaryName: "fixture", Targets: []artifact.Target{{OS: runtime.GOOS, Arch: runtime.GOARCH}}}
|
|
if mode == "build failure" {
|
|
spec.MainPackage = "./missing"
|
|
}
|
|
request := Request{RepositoryDir: repo, Product: "Fixture", Version: "v1.2.3", Backend: backend, Build: &spec}
|
|
if mode == "cancellation" {
|
|
request.Output = cancelBuildOutput{cancel}
|
|
}
|
|
cleanupErr := errors.New("cleanup failed")
|
|
var removed string
|
|
result, err := deliver(ctx, request, func(path string) error {
|
|
removed = path
|
|
_ = os.RemoveAll(path)
|
|
return cleanupErr
|
|
})
|
|
if !errors.Is(err, cleanupErr) || removed == "" || !strings.Contains(err.Error(), removed) || result.CandidateCommit != commit {
|
|
t.Fatalf("delivery = %#v, cleanup = %q, error = %v", result, removed, err)
|
|
}
|
|
switch mode {
|
|
case "complete":
|
|
if result.State != Complete || len(result.Uploaded) != 2 || result.ReleaseURL == "" {
|
|
t.Fatalf("completed delivery lost observations: %#v", result)
|
|
}
|
|
case "build failure":
|
|
if result.State != NotAttempted || !strings.Contains(err.Error(), "build delivery assets") {
|
|
t.Fatalf("build failure lost: %#v, %v", result, err)
|
|
}
|
|
case "cancellation":
|
|
if result.State != NotAttempted || !errors.Is(err, context.Canceled) {
|
|
t.Fatalf("cancellation lost: %#v, %v", result, err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|