Watch
1
0
Fork
You've already forked pkg-proxy
1
mirror of https://github.com/git-pkgs/proxy.git synced 2026-11-09 15:49:16 -05:00
pkg-proxy/internal/handler/cooldown_patterns_test.go
Andrew Nesbitt 6d771a8d3a
Use shared cooldown package-pattern policy
Use cooldown.NewPolicy for package-pattern overrides and remove the duplicate local implementation.
2026-10-20 08:53:22 +01:00

104 lines
3.9 KiB
Go

package handler
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/git-pkgs/cooldown"
)
func TestNuGetCooldownPackagePatterns(t *testing.T) {
for _, tc := range []struct {
name, defaultDuration, pattern string
exact map[string]string
blocked bool
}{
{"pattern enables cooldown", "", "14d", nil, true},
{"pattern exempts package", "14d", "0", nil, false},
{"exact overrides exemption", "", "0", map[string]string{"pkg:nuget/testpkg": "14d"}, true},
{"exact exempts package", "", "14d", map[string]string{"pkg:nuget/testpkg": "0"}, false},
} {
t.Run(tc.name, func(t *testing.T) {
p, db, store, fetcher := setupTestProxy(t)
policy, err := cooldown.NewPolicy(&cooldown.Config{Default: tc.defaultDuration, Packages: tc.exact}, map[string]string{"pkg:nuget/test*": tc.pattern})
if err != nil {
t.Fatal(err)
}
p.Cooldown = policy
seedPackage(t, db, store, "nuget", "testpkg", "2.0.0", "testpkg.2.0.0.nupkg", "cached package")
requests := 0
upstream := newNuGetCooldownUpstream(t, &requests)
defer upstream.Close()
p.HTTPClient = upstream.Client()
h := NewNuGetHandlerWithUpstreams(p, "http://proxy.test", upstream.URL, upstream.URL)
list := nugetGet(t, h.Routes(), "/v3-flatcontainer/TestPkg/index.json", http.StatusOK)
if strings.Contains(list.Body.String(), "2.0.0") == tc.blocked {
t.Fatalf("incorrect version list: %s", list.Body.String())
}
status := http.StatusOK
if tc.blocked {
status = http.StatusNotFound
}
nugetGet(t, h.Routes(), "/v3-flatcontainer/TestPkg/2.0.0/testpkg.2.0.0.nupkg", status)
if fetcher.fetchCalled {
t.Fatal("cached or withheld download fetched upstream artifact")
}
})
}
}
func TestNPMCooldownPatternExemptionRespectsDenylist(t *testing.T) {
p, db, store, fetcher := setupTestProxy(t)
var err error
p.Cooldown, err = cooldown.NewPolicy(&cooldown.Config{Default: "7d"}, map[string]string{"pkg:npm/@example/*": "0"})
if err != nil {
t.Fatal(err)
}
setTestDenylist(t, p, "pkg:npm/@example/widget@1.0.0")
published := time.Now().Add(-time.Hour)
for _, version := range []string{"1.0.0", "2.0.0"} {
seedPackage(t, db, store, "npm", "@example/widget", version, "widget-"+version+".tgz", "cached package")
if err := db.SetVersionPublishedAt("pkg:npm/%40example/widget@"+version, "pkg:npm/%40example/widget", published); err != nil {
t.Fatal(err)
}
}
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/@example/widget" {
t.Errorf("unexpected upstream request: %s", r.URL)
}
w.Header().Set("Content-Type", "application/json")
_, _ = fmt.Fprintf(w, `{"name":"@example/widget","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{},"2.0.0":{}},"time":{"1.0.0":%q,"2.0.0":%q}}`, published.Format(time.RFC3339), published.Format(time.RFC3339))
}))
defer upstream.Close()
p.HTTPClient = upstream.Client()
h := NewNPMHandler(p, "http://proxy.test", upstream.URL)
server := httptest.NewServer(h.Routes())
defer server.Close()
for _, tc := range []struct {
path string
status int
contains, absent string
}{
{"/@example%2Fwidget", http.StatusOK, `"latest":"2.0.0"`, "1.0.0"},
{"/@example%2Fwidget/-/widget-1.0.0.tgz", http.StatusForbidden, "denylist", "cached package"},
{"/@example%2Fwidget/-/widget-2.0.0.tgz", http.StatusOK, "cached package", "denylist"},
} {
response, err := server.Client().Get(server.URL + tc.path)
if err != nil {
t.Fatal(err)
}
body, err := io.ReadAll(response.Body)
_ = response.Body.Close()
if err != nil || response.StatusCode != tc.status || !strings.Contains(string(body), tc.contains) || strings.Contains(string(body), tc.absent) {
t.Errorf("GET %s: status=%d body=%s error=%v", tc.path, response.StatusCode, body, err)
}
}
if fetcher.fetchCalled {
t.Error("cached or denied downloads fetched an upstream artifact")
}
}