Something went wrong. Try again.
Maps Linux distribution source packages to their upstream repositories, and through them to each other
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159package bulk
import ( "context" "errors" "path/filepath" "testing" "time"
"tangled.org/odd.computer/isomorph/internal/distro/alpine" "tangled.org/odd.computer/isomorph/internal/distro/arch" "tangled.org/odd.computer/isomorph/internal/distro/opensuse" "tangled.org/odd.computer/isomorph/internal/model")
type fakeSRCINFO struct { files map[string]string cached map[string]bool}
func (f fakeSRCINFO) SRCINFOAt(_ context.Context, pkgbase, commit string) (*arch.SRCINFO, error) { body, ok := f.files[pkgbase+"@"+commit] if !ok { return nil, errors.New("404") } return arch.ParseSRCINFO([]byte(body))}
func (f fakeSRCINFO) FetchSRCINFO(ctx context.Context, pkgbase, commit string, _ bool) (*arch.SRCINFO, error) { return f.SRCINFOAt(ctx, pkgbase, commit)}
func (f fakeSRCINFO) HasSRCINFO(pkgbase, commit string) bool { return f.cached[pkgbase+"@"+commit] }
func TestFromArchAndCompare(t *testing.T) { defer func(d time.Duration) { CrawlInterval = d }(CrawlInterval) CrawlInterval = 0 f := fakeSRCINFO{files: map[string]string{ "json-c@aaaa": "pkgbase = json-c\n\tpkgver = 0.18\n\tpkgrel = 1\n\turl = https://github.com/json-c/json-c/wiki\n" + "\tsource = git+https://github.com/json-c/json-c#tag=json-c-0.18-20240915\n\tsha256sums = SKIP\n\npkgname = json-c\n", "gzip@bbbb": "pkgbase = gzip\n\tpkgver = 1.13\n\tpkgrel = 1\n\turl = https://www.gnu.org/software/gzip/\n" + "\tsource = https://ftp.gnu.org/pub/gnu/gzip/gzip-1.13.tar.xz\n\tsha256sums = 7777\n\npkgname = gzip\n", }, cached: map[string]bool{"json-c@aaaa": true}} dbs := []arch.SyncPackage{ {Repo: "extra", Name: "json-c", Base: "json-c", Version: "0.18-1", URL: "https://github.com/json-c/json-c/wiki"}, {Repo: "core", Name: "gzip", Base: "gzip", Version: "1.13-1", URL: "https://www.gnu.org/software/gzip/"}, {Repo: "extra", Name: "gone-bin", Base: "gone", Version: "1-1", URL: "https://github.com/gone/gone"}, {Repo: "extra", Name: "gone-docs", Base: "gone", Version: "1-1"}, } state := []arch.StateEntry{ {Repo: "extra", PkgBase: "json-c", Version: "0.18-1", Commit: "aaaa"}, {Repo: "core", PkgBase: "gzip", Version: "1.13-1", Commit: "bbbb"}, {Repo: "extra", PkgBase: "gone", Version: "1-1", Commit: "cccc"}, } // Cache only: json-c from .SRCINFO, the others from the databases' url. pkgs, st := FromArch(context.Background(), f, dbs, state, 0, nil) if st.PkgBases != 3 || st.FromSRCINFO != 1 || st.Fetched != 0 { t.Fatalf("cache-only stats: %+v", st) } by := map[string]Package{} for _, p := range pkgs { by[p.Name] = p } if p := by["json-c"]; p.Basis != BasisVCSSource || p.UpstreamKey != "github.com/json-c/json-c" { t.Errorf("json-c from cached .SRCINFO: %+v", p) } if p := by["gone"]; p.UpstreamKey != "github.com/gone/gone" || p.Basis != BasisHomepage || len(p.Binaries) != 2 { t.Errorf("gone from the database url: %+v", p) } // With a crawl budget the uncached ones are fetched; a failing fetch keeps the baseline. pkgs, st = FromArch(context.Background(), f, dbs, state, 10, nil) if st.FromSRCINFO != 2 || st.Fetched != 2 || st.FetchErrors != 1 { t.Fatalf("crawl stats: %+v", st) } by = map[string]Package{} for _, p := range pkgs { by[p.Name] = p } if p := by["gzip"]; p.UpstreamKey != "git.savannah.gnu.org/gzip" || p.Basis != BasisReleaseURL || len(p.SourceSHA256) != 1 { t.Errorf("gzip: %+v", p) } if p := by["gone"]; p.UpstreamKey != "github.com/gone/gone" { t.Errorf("gone after a failed fetch: %+v", p) } pkgs = []Package{by["json-c"], by["gzip"], by["gone"]}
ctx := context.Background() db, err := Open(ctx, filepath.Join(t.TempDir(), "p.sqlite")) if err != nil { t.Fatal(err) } defer db.Close() deb := FromUDD(udd(), "sid") deb[1].SourceSHA256 = []string{"7777"} // gzip: the same release tarball as Arch Replace(ctx, db, Source{Distro: model.Debian, Suite: "sid", Origin: "t", FetchedAt: time.Now()}, deb) Replace(ctx, db, Source{Distro: model.Arch, Suite: "extra", Origin: "t", FetchedAt: time.Now()}, []Package{pkgs[0], pkgs[2]}) Replace(ctx, db, Source{Distro: model.Arch, Suite: "core", Origin: "t", FetchedAt: time.Now()}, []Package{pkgs[1]}) _ = st ags, err := Compare(ctx, db, "debian", "arch") if err != nil { t.Fatal(err) } if sha := ags[0]; sha.Join != "sha256" || sha.Pairs != 1 || sha.Agree != 1 { t.Errorf("sha256 join: %+v", sha) } if name := ags[1]; name.Join != "name" || name.Pairs != 2 || name.BothResolved != 2 || name.Agree != 2 { t.Errorf("name join: %+v", name) }}
func TestFromOpenSUSE(t *testing.T) { srcs := []opensuse.RPM{ {Name: "json-c", Arch: "src", Version: "0.18-1.2", URL: "https://github.com/json-c/json-c/wiki"}, {Name: "at", Arch: "src", Version: "1:3.2-4"}, } bins := []opensuse.RPM{ {Name: "libjson-c5", Arch: "x86_64", SourceRPM: "json-c-0.18-1.2.src.rpm"}, {Name: "libjson-c-devel", Arch: "x86_64", SourceRPM: "json-c-0.18-1.2.src.rpm"}, {Name: "libjson-c5", Arch: "i586", SourceRPM: "json-c-0.18-1.2.src.rpm"}, } pkgs := FromOpenSUSE(srcs, bins, map[string][]string{"at": {"https://salsa.debian.org/debian/at.git"}}, nil) if len(pkgs) != 2 { t.Fatalf("%d rows", len(pkgs)) } at, j := pkgs[0], pkgs[1] if j.Name != "json-c" || j.UpstreamKey != "github.com/json-c/json-c" || j.Basis != BasisHomepage || j.OSVEcosystem != "openSUSE:Tumbleweed" || len(j.Binaries) != 2 || j.PURL != "pkg:rpm/opensuse/json-c?arch=src" { t.Errorf("json-c: %+v", j) } if at.UpstreamKey != "salsa.debian.org/debian/at" || at.Basis != BasisDerived { t.Errorf("at via giturls: %+v", at) }}
func TestFromAlpine(t *testing.T) { index := map[string][]alpine.IndexEntry{ "community": { {Name: "sysstat", Version: "12.7.1-r0", Origin: "sysstat", URL: "https://github.com/sysstat/sysstat"}, {Name: "sysstat-doc", Version: "12.7.1-r0", Origin: "sysstat", URL: "https://github.com/sysstat/sysstat"}, }, "main": {{Name: "libfoo", Version: "1-r0", Origin: "foo", URL: "https://gitlab.com/foo/foo"}}, } ab, err := alpine.ParseAPKBUILD([]byte("pkgname=sysstat\npkgver=12.7.1\npkgrel=0\nurl=\"https://sebastien.godard.pagesperso-orange.fr/\"\nsource=\"$pkgname-$pkgver.tar.gz::https://github.com/sysstat/sysstat/archive/v$pkgver.tar.gz\"\n")) if err != nil { t.Fatal(err) } pkgs := FromAlpine(index, map[string]*alpine.APKBUILD{"community/sysstat": ab}) if len(pkgs) != 2 { t.Fatalf("%d rows", len(pkgs)) } s, f := pkgs[0], pkgs[1] if s.Name != "sysstat" || s.Suite != "edge-community" || s.UpstreamKey != "github.com/sysstat/sysstat" || s.Basis != BasisReleaseURL || len(s.Binaries) != 2 { t.Errorf("sysstat: %+v", s) } if f.Name != "foo" || f.UpstreamKey != "gitlab.com/foo/foo" || f.Basis != BasisHomepage { t.Errorf("foo from the index url: %+v", f) }}