mirror of
https://github.com/git-pkgs/proxy.git
synced 2026-11-09 07:39:19 -05:00
101 lines
3.3 KiB
Go
101 lines
3.3 KiB
Go
package handler
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/git-pkgs/cooldown"
|
|
registryclient "github.com/git-pkgs/registries/client"
|
|
)
|
|
|
|
func TestDownloadCooldownLookupFailures(t *testing.T) {
|
|
for _, c := range downloadCooldownCases() {
|
|
for _, failure := range []string{"upstream error", "invalid metadata", "rate limited"} {
|
|
for _, cached := range []bool{false, true} {
|
|
t.Run(fmt.Sprintf("%s/%s/cached=%t", c.ecosystem, failure, cached), func(t *testing.T) {
|
|
assertDownloadLookupFailure(t, c, failure, cached)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func assertDownloadLookupFailure(t *testing.T, c downloadCooldownCase, failure string, cached bool) {
|
|
t.Helper()
|
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
if failure == "upstream error" {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}
|
|
_, _ = w.Write([]byte("invalid metadata"))
|
|
}))
|
|
t.Cleanup(upstream.Close)
|
|
proxy, _, _, fetcher := setupTestProxy(t)
|
|
proxy.Cooldown = &cooldown.Config{Default: "7d"}
|
|
proxy.HTTPClient = upstream.Client()
|
|
if failure == "rate limited" {
|
|
proxy.HTTPClient = &http.Client{Transport: roundTripperFunc(func(_ *http.Request) (*http.Response, error) {
|
|
return nil, ®istryclient.HeldError{Host: "upstream.example", Until: time.Now().Add(time.Minute), RetryAfter: time.Minute}
|
|
})}
|
|
}
|
|
if cached {
|
|
c.seedCachedArtifact(t, proxy, cooldownRecentVersion)
|
|
}
|
|
w := serveGet(t, c.handler(proxy, upstream.URL), c.path(cooldownRecentVersion))
|
|
want := http.StatusBadGateway
|
|
if failure == "rate limited" {
|
|
want = http.StatusServiceUnavailable
|
|
}
|
|
if cached {
|
|
want = http.StatusOK
|
|
if w.Body.Len() == 0 {
|
|
t.Fatal("cached artifact body is empty")
|
|
}
|
|
}
|
|
wantStatus(t, w, want, "")
|
|
if fetcher.fetchCalled {
|
|
t.Fatal("lookup failure fetched an unchecked artifact")
|
|
}
|
|
}
|
|
|
|
func TestDownloadPublishIndexesHaveShortTTLWithoutMetadataCache(t *testing.T) {
|
|
for _, c := range downloadCooldownCases() {
|
|
if c.ecosystem != "conda" && c.ecosystem != "helm" {
|
|
continue
|
|
}
|
|
t.Run(c.ecosystem, func(t *testing.T) {
|
|
var calls atomic.Int64
|
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
calls.Add(1)
|
|
c.metadata(w, r, map[string]time.Time{
|
|
cooldownOldVersion: time.Now().Add(-30 * 24 * time.Hour),
|
|
cooldownRecentVersion: time.Now().Add(-time.Hour),
|
|
})
|
|
}))
|
|
t.Cleanup(upstream.Close)
|
|
proxy, _, _, _ := setupTestProxy(t)
|
|
proxy.HTTPClient = upstream.Client()
|
|
proxy.Cooldown = &cooldown.Config{Default: "7d"}
|
|
clock := &testClock{t: time.Now()}
|
|
proxy.now = clock.now
|
|
c.seedCachedArtifact(t, proxy, cooldownOldVersion)
|
|
c.seedCachedArtifact(t, proxy, cooldownRecentVersion)
|
|
h := c.handler(proxy, upstream.URL)
|
|
for range 3 {
|
|
wantStatus(t, serveGet(t, h, c.path(cooldownOldVersion)), http.StatusOK, "")
|
|
wantStatus(t, serveGet(t, h, c.path(cooldownRecentVersion)), http.StatusNotFound, "")
|
|
}
|
|
if n := calls.Load(); n != 1 {
|
|
t.Fatalf("index downloads within TTL = %d, want 1", n)
|
|
}
|
|
clock.advance(time.Minute + time.Second)
|
|
wantStatus(t, serveGet(t, h, c.path(cooldownRecentVersion)), http.StatusNotFound, "")
|
|
if n := calls.Load(); n != 2 {
|
|
t.Errorf("index downloads after expiry = %d, want 2", n)
|
|
}
|
|
})
|
|
}
|
|
}
|