2026-10-22 15:38:35 +02:00
|
|
|
package mirror
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"errors"
|
|
|
|
|
"reflect"
|
|
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// fakeVersions lists fixed versions and records what it was asked for.
|
|
|
|
|
type fakeVersions struct {
|
|
|
|
|
versions []string
|
|
|
|
|
err error
|
|
|
|
|
asked []string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f *fakeVersions) ListVersions(_ context.Context, ecosystem, name string) ([]string, error) {
|
|
|
|
|
f.asked = append(f.asked, ecosystem+"/"+name)
|
|
|
|
|
return f.versions, f.err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func enumerate(t *testing.T, source Source) []PackageVersion {
|
|
|
|
|
t.Helper()
|
|
|
|
|
var items []PackageVersion
|
|
|
|
|
if err := source.Enumerate(context.Background(), func(pv PackageVersion) error {
|
|
|
|
|
items = append(items, pv)
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
|
|
|
|
t.Fatalf("Enumerate() error = %v", err)
|
|
|
|
|
}
|
|
|
|
|
return items
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPURLSourceListsVersionsThroughLister(t *testing.T) {
|
|
|
|
|
versions := &fakeVersions{versions: []string{"1.0.0", "1.1.0"}}
|
|
|
|
|
source := &PURLSource{PURLs: []string{"pkg:npm/%40acme/widget"}, Versions: versions}
|
|
|
|
|
|
|
|
|
|
items := enumerate(t, source)
|
|
|
|
|
|
|
|
|
|
want := []PackageVersion{
|
|
|
|
|
{Ecosystem: "npm", Name: "@acme/widget", Version: "1.0.0"},
|
|
|
|
|
{Ecosystem: "npm", Name: "@acme/widget", Version: "1.1.0"},
|
|
|
|
|
}
|
|
|
|
|
if !reflect.DeepEqual(items, want) {
|
|
|
|
|
t.Errorf("items = %v, want %v", items, want)
|
|
|
|
|
}
|
|
|
|
|
if !reflect.DeepEqual(versions.asked, []string{"npm/@acme/widget"}) {
|
|
|
|
|
t.Errorf("lister asked for %v, want npm/@acme/widget", versions.asked)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPURLSourceReportsListerError(t *testing.T) {
|
|
|
|
|
source := &PURLSource{PURLs: []string{"pkg:npm/left-pad"}, Versions: &fakeVersions{err: errors.New("upstream down")}}
|
|
|
|
|
err := source.Enumerate(context.Background(), func(PackageVersion) error { return nil })
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatal("Enumerate() succeeded although listing versions failed")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSBOMSourceListsVersionsThroughLister(t *testing.T) {
|
|
|
|
|
bom := map[string]any{
|
|
|
|
|
"bomFormat": "CycloneDX",
|
|
|
|
|
"specVersion": "1.4",
|
|
|
|
|
"components": []map[string]any{{"type": "library", "name": "left-pad", "purl": "pkg:npm/left-pad"}},
|
|
|
|
|
}
|
|
|
|
|
versions := &fakeVersions{versions: []string{"1.3.0"}}
|
|
|
|
|
source := &SBOMSource{Data: marshalJSON(t, bom), Versions: versions}
|
|
|
|
|
|
|
|
|
|
items := enumerate(t, source)
|
|
|
|
|
|
|
|
|
|
if len(items) != 1 || items[0].Version != "1.3.0" {
|
|
|
|
|
t.Errorf("items = %v, want left-pad@1.3.0 from the lister", items)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSourceFromRequestUsesMirrorVersions(t *testing.T) {
|
|
|
|
|
m := setupTestMirror(t, 1)
|
|
|
|
|
versions := &fakeVersions{}
|
|
|
|
|
m.Versions = versions
|
|
|
|
|
js := NewJobStore(context.Background(), m)
|
|
|
|
|
|
|
|
|
|
source, err := js.sourceFromRequest(JobRequest{PURLs: []string{"pkg:npm/left-pad"}})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("sourceFromRequest() error = %v", err)
|
|
|
|
|
}
|
|
|
|
|
if got := source.(*PURLSource).Versions; got != versions {
|
|
|
|
|
t.Errorf("PURL source lists versions through %v, want the mirror's lister", got)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
source, err = js.sourceFromRequest(JobRequest{SBOM: json.RawMessage(`{"bomFormat":"CycloneDX","components":[]}`)})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("sourceFromRequest() error = %v", err)
|
|
|
|
|
}
|
|
|
|
|
if got := source.(*SBOMSource).Versions; got != versions {
|
|
|
|
|
t.Errorf("SBOM source lists versions through %v, want the mirror's lister", got)
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-10-25 19:37:46 +01:00
|
|
|
|
|
|
|
|
func TestPURLSourceKeepsJuliaUUID(t *testing.T) {
|
|
|
|
|
const uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
|
|
|
|
|
versions := &fakeVersions{versions: []string{"0.5.5"}}
|
|
|
|
|
source := &PURLSource{
|
|
|
|
|
PURLs: []string{"pkg:julia/Example@0.5.4?uuid=" + uuid, "pkg:julia/Example?uuid=" + uuid},
|
|
|
|
|
Versions: versions,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
items := enumerate(t, source)
|
|
|
|
|
|
|
|
|
|
qualifiers := map[string]string{"uuid": uuid}
|
|
|
|
|
want := []PackageVersion{
|
|
|
|
|
{Ecosystem: "julia", Name: "Example", Version: "0.5.4", Qualifiers: qualifiers},
|
|
|
|
|
{Ecosystem: "julia", Name: "Example", Version: "0.5.5", Qualifiers: qualifiers},
|
|
|
|
|
}
|
|
|
|
|
if !reflect.DeepEqual(items, want) {
|
|
|
|
|
t.Errorf("items = %v, want %v", items, want)
|
|
|
|
|
}
|
|
|
|
|
}
|