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/server/mirror_versions_test.go

178 lines
6.8 KiB
Go
Raw Permalink Normal View History

package server
import (
"context"
"io"
"log/slog"
"net/http"
"net/http/httptest"
"slices"
"strings"
"sync/atomic"
"testing"
"github.com/git-pkgs/proxy/internal/config"
)
// newPackumentUpstream serves an npm packument with the given versions for
// path and counts the requests it gets.
func newPackumentUpstream(t *testing.T, path string, versions ...string) (*httptest.Server, *atomic.Int32) {
t.Helper()
var hits atomic.Int32
entries := make([]string, len(versions))
for i, v := range versions {
entries[i] = `"` + v + `":{"version":"` + v + `"}`
}
body := `{"name":"x","versions":{` + strings.Join(entries, ",") + `}}`
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.EqualFold(r.URL.EscapedPath(), path) {
http.NotFound(w, r)
return
}
hits.Add(1)
w.Header().Set("Content-Type", "application/json")
_, _ = io.WriteString(w, body)
}))
t.Cleanup(upstream.Close)
return upstream, &hits
}
func listMirrorVersions(t *testing.T, cfg *config.Config, ecosystem, name string) ([]string, error) {
t.Helper()
cfg.Upstream.AllowLoopback = true
proxy, _ := NewMirrorProxy(cfg, nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil)))
versions, err := NewMirrorVersions(cfg.Upstream, proxy.HTTPClient).ListVersions(context.Background(), ecosystem, name)
slices.Sort(versions)
return versions, err
}
func TestMirrorVersionsComeFromConfiguredUpstream(t *testing.T) {
upstream, hits := newPackumentUpstream(t, "/left-pad", "1.0.0", "1.1.0")
cfg := config.Default()
cfg.Upstream.NPM = upstream.URL
versions, err := listMirrorVersions(t, cfg, "npm", "left-pad")
if err != nil {
t.Fatalf("ListVersions() error = %v", err)
}
if !slices.Equal(versions, []string{"1.0.0", "1.1.0"}) {
t.Errorf("versions = %v, want the configured upstream's 1.0.0 and 1.1.0", versions)
}
if hits.Load() == 0 {
t.Error("the configured npm upstream was never asked")
}
}
func TestMirrorVersionsFollowNPMRoutes(t *testing.T) {
public, publicHits := newPackumentUpstream(t, "/@acme%2fwidget", "9.9.9")
private, _ := newPackumentUpstream(t, "/@acme%2fwidget", "1.0.0")
cfg := config.Default()
cfg.Upstream.NPM = public.URL
cfg.Upstream.NPMRoutes = map[string]string{"@acme/*": private.URL}
versions, err := listMirrorVersions(t, cfg, "npm", "@acme/widget")
if err != nil {
t.Fatalf("ListVersions() error = %v", err)
}
if !slices.Equal(versions, []string{"1.0.0"}) {
t.Errorf("versions = %v, want only the routed registry's 1.0.0", versions)
}
if publicHits.Load() != 0 {
t.Error("a routed package was listed from upstream.npm")
}
}
func TestMirrorVersionsURL(t *testing.T) {
custom := config.Default().Upstream
custom.NPM = "https://npm.example.com/"
custom.Gem = "https://gems.example.com"
custom.Go = "https://goproxy.example.com"
custom.HexAPI = "https://hex.example.com"
custom.Pub = "https://pub.example.com"
custom.PyPI = "https://pypi.example.com"
custom.Maven = "https://maven.example.com/maven2"
custom.NuGet = "https://nuget.example.com"
custom.Composer = "https://packagist.example.com"
custom.ComposerRoutes = map[string]string{"acme/*": "https://composer.example.com"}
custom.CRAN = "https://cran.example.com"
custom.HomebrewAPI = "https://brew.example.com/api"
custom.Helm = map[string]string{"stable": "https://charts.example.com/stable/"}
custom.Cargo = "https://index.example.com"
custom.Conda = "https://conda.example.com"
custom.Julia = "https://julia.example.com"
custom.Swift = "https://swift.example.com/registry/"
tests := []struct {
name string
upstream config.UpstreamConfig
ecosystem string
pkg string
want string
wantErr string
}{
{"npm default", config.Default().Upstream, "npm", "left-pad", "https://registry.npmjs.org", ""},
{"npm unset", config.UpstreamConfig{}, "npm", "left-pad", "https://registry.npmjs.org", ""},
{"npm", custom, "npm", "left-pad", "https://npm.example.com", ""},
{"gem", custom, "gem", "rails", "https://gems.example.com", ""},
{"golang", custom, "golang", "golang.org/x/mod", "https://goproxy.example.com", ""},
{"hex uses the API URL", custom, "hex", "jason", "https://hex.example.com", ""},
{"pub", custom, "pub", "http", "https://pub.example.com", ""},
{"pypi", custom, "pypi", "requests", "https://pypi.example.com", ""},
{"maven", custom, "maven", "org.example:lib", "https://maven.example.com/maven2", ""},
{"nuget lists through v3", custom, "nuget", "Newtonsoft.Json", "https://nuget.example.com/v3", ""},
{"composer", custom, "composer", "monolog/monolog", "https://packagist.example.com", ""},
{"composer route", custom, "composer", "acme/widget", "", "upstream.composer_routes"},
{"cran", custom, "cran", "ggplot2", "https://cran.example.com", ""},
{"brew", custom, "brew", "wget", "https://brew.example.com", ""},
{"cargo default lists from crates.io", config.Default().Upstream, "cargo", "serde", "", ""},
{"cargo index", custom, "cargo", "serde", "", "upstream.cargo"},
{"conda default", config.Default().Upstream, "conda", "numpy", "", ""},
{"conda channel", custom, "conda", "numpy", "", "upstream.conda"},
{"julia default", config.Default().Upstream, "julia", "JSON", "", ""},
{"julia server lists from General", custom, "julia", "JSON", "", ""},
{"helm", custom, "helm", "stable/nginx", "https://charts.example.com/stable", ""},
{"helm without repository", custom, "helm", "nginx", "", "namespace"},
{"helm unknown repository", custom, "helm", "other/nginx", "", "upstream.helm"},
{"swift", custom, "swift", "apple.swift-nio", "https://swift.example.com/registry", ""},
{"apk", custom, "apk", "curl", "", "give a version"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := mirrorVersionsURL(tt.upstream, tt.ecosystem, tt.pkg)
if tt.wantErr != "" {
if err == nil || !strings.Contains(err.Error(), tt.wantErr) {
t.Fatalf("error = %v, want one mentioning %q", err, tt.wantErr)
}
return
}
if err != nil {
t.Fatalf("error = %v", err)
}
if got != tt.want {
t.Errorf("URL = %q, want %q", got, tt.want)
}
})
}
}
func TestServerMirrorListsFromConfiguredUpstream(t *testing.T) {
upstream, hits := newPackumentUpstream(t, "/left-pad", "1.0.0")
cfg := config.Default()
cfg.Upstream.NPM = upstream.URL
cfg.Upstream.AllowLoopback = true
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
proxy, _ := NewMirrorProxy(cfg, nil, nil, logger)
s := &Server{cfg: cfg, logger: logger, ecr: newECRTokens(logger)}
m := s.newMirror(proxy, 1)
if m.Versions == nil {
t.Fatal("the server's mirror lists versions from the public registries")
}
versions, err := m.Versions.ListVersions(context.Background(), "npm", "left-pad")
if err != nil {
t.Fatalf("ListVersions() error = %v", err)
}
if !slices.Equal(versions, []string{"1.0.0"}) || hits.Load() == 0 {
t.Errorf("versions = %v, want 1.0.0 from the configured upstream", versions)
}
}