Complete forge delivery regression coverage
This commit is contained in:
169
delivery_test.go
169
delivery_test.go
@@ -19,6 +19,175 @@ import (
|
||||
releasekit "go.maximumdirect.net/releasekit"
|
||||
)
|
||||
|
||||
func TestDeliveryForgeSelectionIsExplicit(t *testing.T) {
|
||||
var requests int
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
requests++
|
||||
http.Error(w, "unexpected request", http.StatusInternalServerError)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
for _, forge := range []releasekit.Forge{"", " \t", "unknown"} {
|
||||
t.Run(string(forge), func(t *testing.T) {
|
||||
destination := releasekit.DeliveryDestination{
|
||||
Forge: forge, BaseURL: server.URL, Owner: "owner", Repository: "example", Token: "fixture-token",
|
||||
}
|
||||
if err := releasekit.PreflightDelivery(context.Background(), destination); err == nil || !strings.Contains(err.Error(), "forge") {
|
||||
t.Fatalf("PreflightDelivery() error = %v, want explicit forge selection error", err)
|
||||
}
|
||||
result, err := releasekit.Deliver(context.Background(), releasekit.DeliveryRequest{
|
||||
Version: "v1.2.3", Destination: destination,
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "forge") || result.State != releasekit.DeliveryNotAttempted || result.Version != "v1.2.3" {
|
||||
t.Fatalf("Deliver() = %#v, %v; want selection error before delivery", result, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
if requests != 0 {
|
||||
t.Fatalf("hosted requests = %d, want 0 for invalid forge selection", requests)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPreflightDeliveryChecksAuthenticatedRepositoryWithoutCheckout(t *testing.T) {
|
||||
var requests, writes int
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
writes++
|
||||
t.Errorf("preflight method = %q, want GET", r.Method)
|
||||
http.Error(w, "unexpected write", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
if got, want := r.Header.Get("Authorization"), "token fixture-token"; got != want {
|
||||
t.Errorf("authorization = %q, want %q", got, want)
|
||||
}
|
||||
requests++
|
||||
switch r.URL.Path {
|
||||
case "/api/v1/repos/owner/example":
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"id": 31, "name": "example", "full_name": "owner/example", "owner": map[string]string{"login": "owner"}})
|
||||
case "/api/v1/repositories/31":
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"id": 31, "name": "example", "full_name": "owner/example", "owner": map[string]string{"login": "owner"}})
|
||||
default:
|
||||
t.Errorf("preflight path = %q", r.URL.Path)
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
if err := releasekit.PreflightDelivery(context.Background(), facadeDeliveryDestination(server.URL)); err != nil {
|
||||
t.Fatalf("PreflightDelivery() error = %v", err)
|
||||
}
|
||||
if requests != 2 || writes != 0 {
|
||||
t.Fatalf("preflight requests=%d writes=%d, want two reads and no writes", requests, writes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPreflightDeliveryPreservesPublicFailureKindsAndCauses(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
token string
|
||||
status int
|
||||
wantKind releasekit.DeliveryPreflightFailureKind
|
||||
wantReads int
|
||||
canceled bool
|
||||
}{
|
||||
{name: "missing credential", wantKind: releasekit.DeliveryPreflightMissingCredential},
|
||||
{name: "invalid credential", token: "fixture-token", status: http.StatusUnauthorized, wantKind: releasekit.DeliveryPreflightInvalidCredential, wantReads: 1},
|
||||
{name: "inaccessible destination", token: "fixture-token", status: http.StatusForbidden, wantKind: releasekit.DeliveryPreflightInaccessibleDestination, wantReads: 1},
|
||||
{name: "unavailable service", token: "fixture-token", status: http.StatusServiceUnavailable, wantKind: releasekit.DeliveryPreflightUnavailable, wantReads: 1},
|
||||
{name: "canceled request", token: "fixture-token", wantKind: releasekit.DeliveryPreflightUnavailable, canceled: true},
|
||||
}
|
||||
for _, test := range cases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
reads := 0
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
reads++
|
||||
if test.status != 0 {
|
||||
http.Error(w, "controlled failure", test.status)
|
||||
return
|
||||
}
|
||||
t.Errorf("unexpected request to %q", r.URL.Path)
|
||||
http.Error(w, "unexpected request", http.StatusInternalServerError)
|
||||
}))
|
||||
defer server.Close()
|
||||
destination := facadeDeliveryDestination(server.URL)
|
||||
destination.Token = test.token
|
||||
ctx := context.Background()
|
||||
if test.canceled {
|
||||
canceled, cancel := context.WithCancel(ctx)
|
||||
cancel()
|
||||
ctx = canceled
|
||||
}
|
||||
err := releasekit.PreflightDelivery(ctx, destination)
|
||||
var preflight *releasekit.DeliveryPreflightError
|
||||
if !errors.As(err, &preflight) || preflight.Kind != test.wantKind || preflight.Err == nil {
|
||||
t.Fatalf("PreflightDelivery() error = %#v, want kind %q with cause", err, test.wantKind)
|
||||
}
|
||||
if test.canceled && !errors.Is(err, context.Canceled) {
|
||||
t.Fatalf("PreflightDelivery() error = %v, want cancellation identity", err)
|
||||
}
|
||||
if reads != test.wantReads {
|
||||
t.Fatalf("preflight reads = %d, want %d", reads, test.wantReads)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutomaticPreflightFailurePrecedesPrebuiltArtifactHashing(t *testing.T) {
|
||||
repository := newTaggedDeliveryConsumer(t)
|
||||
prebuilt, err := releasekit.Build(context.Background(), releasekit.BuildRequest{
|
||||
RepositoryDir: repository,
|
||||
Version: "v1.2.3",
|
||||
Spec: releasekit.BuildSpec{
|
||||
MainPackage: "./cmd/app",
|
||||
BinaryName: "fixture",
|
||||
Targets: []releasekit.Target{{OS: runtime.GOOS, Arch: runtime.GOARCH}},
|
||||
},
|
||||
OutputDir: t.TempDir(),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Build() error = %v", err)
|
||||
}
|
||||
contents, err := os.ReadFile(prebuilt.Artifacts[0].Path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
contents[0] ^= 0xff
|
||||
if err := os.WriteFile(prebuilt.Artifacts[0].Path, contents, 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var reads, writes int
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
writes++
|
||||
http.Error(w, "unexpected write", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
reads++
|
||||
if r.URL.Path == "/api/v1/repos/owner/example" {
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"id": 31, "name": "example", "full_name": "owner/example", "owner": map[string]string{"login": "owner"}})
|
||||
return
|
||||
}
|
||||
http.Error(w, "verification unavailable", http.StatusServiceUnavailable)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
result, err := releasekit.Deliver(context.Background(), releasekit.DeliveryRequest{
|
||||
RepositoryDir: repository,
|
||||
Product: "Fixture",
|
||||
Version: "v1.2.3",
|
||||
Destination: facadeDeliveryDestination(server.URL),
|
||||
Prebuilt: &prebuilt,
|
||||
})
|
||||
var preflight *releasekit.DeliveryPreflightError
|
||||
if !errors.As(err, &preflight) || preflight.Kind != releasekit.DeliveryPreflightUnavailable || result.State != releasekit.DeliveryNotAttempted {
|
||||
t.Fatalf("Deliver() = %#v, %v; want unavailable preflight before tamper verification", result, err)
|
||||
}
|
||||
if reads != 2 || writes != 0 {
|
||||
t.Fatalf("preflight reads=%d writes=%d, want two reads and no writes", reads, writes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeliverManagedBuildUploadsArtifactsAndCleansTemporaryOutput(t *testing.T) {
|
||||
repository := newTaggedDeliveryConsumer(t)
|
||||
temporaryRoot := t.TempDir()
|
||||
|
||||
Reference in New Issue
Block a user