mirror of
https://github.com/git-pkgs/proxy.git
synced 2026-11-09 07:39:19 -05:00
82 lines
2.8 KiB
Go
82 lines
2.8 KiB
Go
package mirror
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"github.com/git-pkgs/registries"
|
|
"github.com/git-pkgs/registries/client"
|
|
"github.com/git-pkgs/registries/fetch"
|
|
)
|
|
|
|
type mirrorCacheRegistry struct {
|
|
downloadURL string
|
|
resolutions atomic.Int64
|
|
}
|
|
|
|
type rejectingMirrorTransport struct{}
|
|
|
|
func (rejectingMirrorTransport) RoundTrip(*http.Request) (*http.Response, error) {
|
|
return nil, errors.New("unexpected artifact download on a cache hit")
|
|
}
|
|
|
|
func (*mirrorCacheRegistry) Ecosystem() string { return "npm" }
|
|
func (*mirrorCacheRegistry) FetchVersions(context.Context, string) ([]registries.Version, error) {
|
|
return nil, errors.New("unexpected metadata request")
|
|
}
|
|
func (r *mirrorCacheRegistry) URLs() client.URLBuilder { //nolint:ireturn // required by fetch.Registry
|
|
return &client.BaseURLs{DownloadFn: func(_, _ string) string {
|
|
r.resolutions.Add(1)
|
|
return r.downloadURL
|
|
}}
|
|
}
|
|
|
|
func TestMirrorRepeatedRunSkipsCachedArtifact(t *testing.T) {
|
|
var downloads atomic.Int64
|
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/example-1.0.0.tgz" {
|
|
t.Errorf("unexpected artifact path: %s", r.URL.Path)
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
downloads.Add(1)
|
|
_, _ = io.WriteString(w, "tarball bytes")
|
|
}))
|
|
defer upstream.Close()
|
|
m := setupTestMirror(t, 1)
|
|
registry := &mirrorCacheRegistry{downloadURL: upstream.URL + "/example-1.0.0.tgz"}
|
|
m.proxy.Resolver.RegisterRegistry(registry)
|
|
fetcher := fetch.NewFetcher(fetch.WithHTTPClient(upstream.Client()), fetch.WithMaxRetries(0))
|
|
t.Cleanup(func() { _ = fetcher.Close() })
|
|
m.proxy.Fetcher = fetcher
|
|
source := &PURLSource{PURLs: []string{"pkg:npm/example@1.0.0"}}
|
|
first, err := m.Run(context.Background(), source)
|
|
if err != nil || first.Completed != 1 || first.Skipped != 0 || first.Failed != 0 {
|
|
t.Fatalf("first mirror: progress=%+v err=%v", first, err)
|
|
}
|
|
before, err := m.db.GetArtifact("pkg:npm/example@1.0.0", "example-1.0.0.tgz")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// The second run must succeed even when the artifact server is offline.
|
|
upstream.Close()
|
|
second, err := m.Run(context.Background(), source)
|
|
if err != nil || second.Completed != 0 || second.Skipped != 1 || second.Failed != 0 {
|
|
t.Fatalf("second mirror: progress=%+v err=%v", second, err)
|
|
}
|
|
after, err := m.db.GetArtifact("pkg:npm/example@1.0.0", "example-1.0.0.tgz")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if before.FetchedAt != after.FetchedAt || before.ContentHash != after.ContentHash || before.StoragePath != after.StoragePath {
|
|
t.Fatal("second mirror changed the cached artifact")
|
|
}
|
|
if downloads.Load() != 1 || registry.resolutions.Load() != 2 {
|
|
t.Fatalf("downloads=%d resolutions=%d; want 1 and 2", downloads.Load(), registry.resolutions.Load())
|
|
}
|
|
}
|