Move asset verification into the artifact package
This commit is contained in:
@@ -5,33 +5,16 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"go.maximumdirect.net/releasekit/internal/artifact"
|
||||
)
|
||||
|
||||
const assetListPath = "/api/v1/repos/owner/project/releases/10/assets"
|
||||
|
||||
func TestBuildManifestSortsNamesAndOmitsEmptySourceOnlyManifest(t *testing.T) {
|
||||
manifest, err := BuildManifest([]ExpectedAsset{
|
||||
assetFor("zeta.bin", []byte("zeta")),
|
||||
assetFor("alpha.bin", []byte("alpha")),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := fmt.Sprintf("%s alpha.bin\n%s zeta.bin\n", digest([]byte("alpha")), digest([]byte("zeta")))
|
||||
if string(manifest.Content) != want || manifest.Filename != ManifestFilename || manifest.SHA256 != digest([]byte(want)) || manifest.Size != int64(len(want)) {
|
||||
t.Fatalf("manifest = %#v, content %q", manifest, manifest.Content)
|
||||
}
|
||||
empty, err := BuildManifest(nil)
|
||||
if err != nil || empty.Filename != "" || len(empty.Content) != 0 {
|
||||
t.Fatalf("empty manifest = %#v, error = %v", empty, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectAssetsAcceptsMatchingContentAndPreservesUnrelatedFiles(t *testing.T) {
|
||||
content := []byte("selected binary")
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -53,7 +36,7 @@ func TestInspectAssetsAcceptsMatchingContentAndPreservesUnrelatedFiles(t *testin
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []ExpectedAsset{assetFor("app-v1.2.3-linux-amd64", content)})
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []artifact.ExpectedAsset{assetFor("app-v1.2.3-linux-amd64", content)})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -66,7 +49,7 @@ func TestInspectAssetsAcceptsMatchingContentAndPreservesUnrelatedFiles(t *testin
|
||||
}
|
||||
|
||||
func TestInspectAssetsDetectsSameNameAndSizeWithDifferentBytes(t *testing.T) {
|
||||
expected := []ExpectedAsset{assetFor("app.bin", []byte("alpha")), assetFor("other.bin", []byte("beta"))}
|
||||
expected := []artifact.ExpectedAsset{assetFor("app.bin", []byte("alpha")), assetFor("other.bin", []byte("beta"))}
|
||||
var appDownloads, otherDownloads atomic.Int32
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assertAssetGET(t, r, "")
|
||||
@@ -96,8 +79,8 @@ func TestInspectAssetsDetectsSameNameAndSizeWithDifferentBytes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInspectAssetsAcceptsFullManifestWhenBinariesAreMissing(t *testing.T) {
|
||||
binaries := []ExpectedAsset{assetFor("alpha.bin", []byte("alpha")), assetFor("beta.bin", []byte("beta"))}
|
||||
manifest, err := BuildManifest(binaries)
|
||||
binaries := []artifact.ExpectedAsset{assetFor("alpha.bin", []byte("alpha")), assetFor("beta.bin", []byte("beta"))}
|
||||
manifest, err := artifact.BuildManifest(binaries)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -124,25 +107,25 @@ func TestInspectAssetsAcceptsFullManifestWhenBinariesAreMissing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInspectAssetsRejectsSubsetManifest(t *testing.T) {
|
||||
binaries := []ExpectedAsset{assetFor("alpha.bin", []byte("alpha")), assetFor("beta.bin", []byte("beta"))}
|
||||
full, err := BuildManifest(binaries)
|
||||
binaries := []artifact.ExpectedAsset{assetFor("alpha.bin", []byte("alpha")), assetFor("beta.bin", []byte("beta"))}
|
||||
full, err := artifact.BuildManifest(binaries)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
subset, err := BuildManifest(binaries[:1])
|
||||
subset, err := artifact.BuildManifest(binaries[:1])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assertAssetGET(t, r, "")
|
||||
if r.URL.Path == assetListPath {
|
||||
writeAssetList(t, w, []assetResponse{{ID: 3, Name: ManifestFilename, Size: subset.Size, BrowserDownloadURL: "/files/manifest"}})
|
||||
writeAssetList(t, w, []assetResponse{{ID: 3, Name: artifact.ManifestFilename, Size: subset.Size, BrowserDownloadURL: "/files/manifest"}})
|
||||
return
|
||||
}
|
||||
_, _ = w.Write(subset.Content)
|
||||
}))
|
||||
defer server.Close()
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []ExpectedAsset{full})
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []artifact.ExpectedAsset{full})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -152,7 +135,7 @@ func TestInspectAssetsRejectsSubsetManifest(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInspectAssetsRejectsDifferentManifest(t *testing.T) {
|
||||
expected, err := BuildManifest([]ExpectedAsset{assetFor("alpha.bin", []byte("alpha"))})
|
||||
expected, err := artifact.BuildManifest([]artifact.ExpectedAsset{assetFor("alpha.bin", []byte("alpha"))})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -160,13 +143,13 @@ func TestInspectAssetsRejectsDifferentManifest(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assertAssetGET(t, r, "")
|
||||
if r.URL.Path == assetListPath {
|
||||
writeAssetList(t, w, []assetResponse{{ID: 3, Name: ManifestFilename, Size: int64(len(different)), BrowserDownloadURL: "/files/manifest"}})
|
||||
writeAssetList(t, w, []assetResponse{{ID: 3, Name: artifact.ManifestFilename, Size: int64(len(different)), BrowserDownloadURL: "/files/manifest"}})
|
||||
return
|
||||
}
|
||||
_, _ = w.Write(different)
|
||||
}))
|
||||
defer server.Close()
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []ExpectedAsset{expected})
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []artifact.ExpectedAsset{expected})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -186,7 +169,7 @@ func TestInspectAssetsMarksUnreadableContentUnverifiable(t *testing.T) {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
}))
|
||||
defer server.Close()
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []ExpectedAsset{expected})
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []artifact.ExpectedAsset{expected})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -201,7 +184,7 @@ func TestInspectAssetsRejectsMalformedAttachmentList(t *testing.T) {
|
||||
_, _ = w.Write([]byte("null"))
|
||||
}))
|
||||
defer server.Close()
|
||||
_, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []ExpectedAsset{assetFor("app.bin", []byte("alpha"))})
|
||||
_, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []artifact.ExpectedAsset{assetFor("app.bin", []byte("alpha"))})
|
||||
if failureKind(t, err) != FailureMalformed {
|
||||
t.Fatalf("error = %v", err)
|
||||
}
|
||||
@@ -243,7 +226,7 @@ func TestInspectAssetsFollowsSameOriginRedirectWithAuthorization(t *testing.T) {
|
||||
return
|
||||
}))
|
||||
defer server.Close()
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []ExpectedAsset{expected})
|
||||
inspection, err := testClient(server).InspectAssets(context.Background(), testDestination(server.URL), 10, []artifact.ExpectedAsset{expected})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -282,7 +265,7 @@ func TestInspectAssetsVerifiesExternalContentWithoutGiteaToken(t *testing.T) {
|
||||
http.Redirect(w, r, external.URL+"/content", http.StatusFound)
|
||||
}))
|
||||
defer origin.Close()
|
||||
inspection, err := testClient(origin).InspectAssets(context.Background(), testDestination(origin.URL), 10, []ExpectedAsset{expected})
|
||||
inspection, err := testClient(origin).InspectAssets(context.Background(), testDestination(origin.URL), 10, []artifact.ExpectedAsset{expected})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -297,9 +280,9 @@ func TestInspectAssetsVerifiesExternalContentWithoutGiteaToken(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func assetFor(filename string, content []byte) ExpectedAsset {
|
||||
func assetFor(filename string, content []byte) artifact.ExpectedAsset {
|
||||
sum := sha256.Sum256(content)
|
||||
return ExpectedAsset{Filename: filename, SHA256: hex.EncodeToString(sum[:]), Size: int64(len(content)), Content: append([]byte(nil), content...)}
|
||||
return artifact.ExpectedAsset{Filename: filename, SHA256: hex.EncodeToString(sum[:]), Size: int64(len(content)), Content: append([]byte(nil), content...)}
|
||||
}
|
||||
|
||||
func writeAssetList(t *testing.T, w http.ResponseWriter, assets []assetResponse) {
|
||||
|
||||
Reference in New Issue
Block a user