101 lines
3.2 KiB
Go
101 lines
3.2 KiB
Go
//go:build e2e
|
|
|
|
package e2e
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.unkin.net/unkin/artifactapi/internal/testsupport"
|
|
)
|
|
|
|
// assertHeadMatchesGet checks HEAD returns GET's status, type and length with no body.
|
|
func assertHeadMatchesGet(t *testing.T, url string) {
|
|
t.Helper()
|
|
get, err := http.Get(url)
|
|
if err != nil {
|
|
t.Fatalf("GET: %v", err)
|
|
}
|
|
body, _ := io.ReadAll(get.Body)
|
|
get.Body.Close()
|
|
if get.StatusCode != http.StatusOK {
|
|
t.Fatalf("GET %s: %d %s", url, get.StatusCode, body)
|
|
}
|
|
|
|
head, err := http.Head(url)
|
|
if err != nil {
|
|
t.Fatalf("HEAD: %v", err)
|
|
}
|
|
hb, _ := io.ReadAll(head.Body)
|
|
head.Body.Close()
|
|
if head.StatusCode != http.StatusOK {
|
|
t.Fatalf("HEAD %s: got %d, want 200", url, head.StatusCode)
|
|
}
|
|
if len(hb) != 0 {
|
|
t.Errorf("HEAD returned a %d-byte body", len(hb))
|
|
}
|
|
if head.Header.Get("Content-Type") != get.Header.Get("Content-Type") {
|
|
t.Errorf("HEAD Content-Type %q, GET %q", head.Header.Get("Content-Type"), get.Header.Get("Content-Type"))
|
|
}
|
|
if head.ContentLength != int64(len(body)) {
|
|
t.Errorf("HEAD Content-Length %d, GET body %d bytes", head.ContentLength, len(body))
|
|
}
|
|
}
|
|
|
|
func TestProxyHeadNuGetRewritten(t *testing.T) {
|
|
var upstream *httptest.Server
|
|
upstream = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]any{"version": "3.0.0", "resources": []map[string]string{
|
|
{"@id": upstream.URL + "/v3-flatcontainer/", "@type": "PackageBaseAddress/3.0.0"},
|
|
}})
|
|
}))
|
|
defer upstream.Close()
|
|
|
|
createRemote(t, mustFormat(`{"name": "head-nuget", "package_type": "nuget", "base_url": %q}`, upstream.URL+"/v3/index.json"))
|
|
defer deleteRemote(t, "head-nuget")
|
|
|
|
assertHeadMatchesGet(t, apiURL("/api/v1/remote/head-nuget/index.json"))
|
|
}
|
|
|
|
func TestProxyHeadGitHubRPMRepodata(t *testing.T) {
|
|
rpm := testsupport.MinimalRPM("demo", "1.2", "3", "x86_64")
|
|
var gh *httptest.Server
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/repos/acme/tools/releases", func(w http.ResponseWriter, r *http.Request) {
|
|
if p := r.URL.Query().Get("page"); p != "" && p != "1" {
|
|
w.Write([]byte("[]"))
|
|
return
|
|
}
|
|
json.NewEncoder(w).Encode([]map[string]any{{"tag_name": "v1.2-3", "assets": []map[string]any{{
|
|
"name": "demo-1.2-3.x86_64.rpm",
|
|
"size": len(rpm),
|
|
"browser_download_url": gh.URL + "/acme/tools/releases/download/v1.2-3/demo-1.2-3.x86_64.rpm",
|
|
}}}})
|
|
})
|
|
mux.HandleFunc("/acme/tools/releases/download/", func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Length", strconv.Itoa(len(rpm)))
|
|
w.Write(rpm)
|
|
})
|
|
gh = httptest.NewServer(mux)
|
|
defer gh.Close()
|
|
|
|
createRemote(t, mustFormat(`{"name": "head-ghrpm", "package_type": "github_rpm", "base_url": %q, "releases_remote": "github"}`, gh.URL+"/repos/acme/tools"))
|
|
defer deleteRemote(t, "head-ghrpm")
|
|
|
|
url := apiURL("/api/v1/remote/head-ghrpm/repodata/repomd.xml")
|
|
deadline := time.Now().Add(30 * time.Second)
|
|
for {
|
|
if _, status := getBody(t, url); status == http.StatusOK || time.Now().After(deadline) {
|
|
break
|
|
}
|
|
time.Sleep(500 * time.Millisecond)
|
|
}
|
|
assertHeadMatchesGet(t, url)
|
|
}
|