package arch import ( "os" "path/filepath" "testing" ) func TestProjectPath(t *testing.T) { cases := map[string]string{ "tree": "unix-tree", "libsigc++": "libsigcplusplus", "libsigc++-3.0": "libsigcplusplus-3.0", "c++utilities": "cplusplusutilities", "afl++": "aflplusplus", "memtest86+": "memtest86plus", "libxml++2.6": "libxmlplusplus2.6", "libxml++-5.0": "libxmlplusplus-5.0", "libc++": "libcplusplus", "curl": "curl", "python-requests": "python-requests", "gtk+extra": "gtk-extra", "foo__bar--baz": "foo-bar-baz", "a b@c": "a-b-c", "trees": "trees", } for in, want := range cases { if got := ProjectPath(in); got != want { t.Errorf("ProjectPath(%q) = %q, want %q", in, got, want) } } } func TestParseSource(t *testing.T) { cases := []struct { raw string want Source }{ { "git+https://github.com/curl/curl.git?signed#tag=curl-8_22_0", Source{LocalName: "curl", URL: "https://github.com/curl/curl.git", VCS: "git", RefType: "tag", Ref: "curl-8_22_0", Signed: true}, }, { "python-requests::git+https://github.com/psf/requests#tag=v2.34.2", Source{LocalName: "python-requests", URL: "https://github.com/psf/requests", VCS: "git", RefType: "tag", Ref: "v2.34.2"}, }, { "git+https://github.com/systemd/systemd#tag=v262?signed", Source{LocalName: "systemd", URL: "https://github.com/systemd/systemd", VCS: "git", RefType: "tag", Ref: "v262", Signed: true}, }, { "git+https://forge.sourceware.org/gcc/gcc#commit=d564253eb6c859e266d3cae18e82fb4db9a88316", Source{LocalName: "gcc", URL: "https://forge.sourceware.org/gcc/gcc", VCS: "git", RefType: "commit", Ref: "d564253eb6c859e266d3cae18e82fb4db9a88316"}, }, { "gcc-ada-repro.patch", Source{LocalName: "gcc-ada-repro.patch", Local: true}, }, { "https://ftp.gnu.org/gnu/bash/bash-5.3.tar.gz", Source{LocalName: "bash-5.3.tar.gz", URL: "https://ftp.gnu.org/gnu/bash/bash-5.3.tar.gz"}, }, { "fix.patch::https://github.com/madler/zlib/commit/36ff1be48ef696cc67b0855f7c8537ce0276210d.patch", Source{LocalName: "fix.patch", URL: "https://github.com/madler/zlib/commit/36ff1be48ef696cc67b0855f7c8537ce0276210d.patch"}, }, { "hg+https://hg.example.org/repo#branch=stable", Source{LocalName: "repo", URL: "https://hg.example.org/repo", VCS: "hg", RefType: "branch", Ref: "stable"}, }, { "foo::bar.conf", Source{LocalName: "foo", Local: true}, }, } for _, c := range cases { got := ParseSource(c.raw) want := c.want want.Raw = c.raw if got != want { t.Errorf("ParseSource(%q)\n got %+v\nwant %+v", c.raw, got, want) } } if r := ParseSource("git+https://github.com/systemd/systemd#tag=v262?signed").Remote(); r != "git+https://github.com/systemd/systemd#tag=v262" { t.Errorf("Remote() = %q", r) } if r := ParseSource("local.patch").Remote(); r != "" { t.Errorf("Remote() of local = %q", r) } } func readFixture(t *testing.T, name string) []byte { t.Helper() b, err := os.ReadFile(filepath.Join("testdata", name)) if err != nil { t.Fatal(err) } return b } func TestParseSRCINFO(t *testing.T) { cases := []struct { file, pkgbase, version, url string nsources, npkgs int firstSource string locals int }{ {"srcinfo_curl.txt", "curl", "8.22.0-1", "https://curl.se/", 1, 3, "git+https://github.com/curl/curl.git?signed#tag=curl-8_22_0", 0}, {"srcinfo_gcc.txt", "gcc", "16.2.1+r23+gd564253eb6c8-1", "https://gcc.gnu.org", 5, 30, "git+https://forge.sourceware.org/gcc/gcc#commit=d564253eb6c859e266d3cae18e82fb4db9a88316", 4}, {"srcinfo_zlib.txt", "zlib", "1:1.3.2-3", "https://www.zlib.net/", 3, 3, "https://github.com/madler/zlib/releases/download/v1.3.2/zlib-1.3.2.tar.xz", 0}, {"srcinfo_python-requests.txt", "python-requests", "2.34.2-1", "https://requests.readthedocs.io/", 1, 1, "python-requests::git+https://github.com/psf/requests#tag=v2.34.2", 0}, {"srcinfo_systemd.txt", "systemd", "262-1", "https://www.github.com/systemd/systemd", 19, 6, "git+https://github.com/systemd/systemd#tag=v262?signed", 18}, {"srcinfo_unix-tree.txt", "tree", "2.3.2-1", "https://gitlab.com/OldManProgrammer/unix-tree", 1, 1, "https://gitlab.com/OldManProgrammer/unix-tree/-/archive/2.3.2/unix-tree-2.3.2.tar.gz", 0}, } for _, c := range cases { si, err := ParseSRCINFO(readFixture(t, c.file)) if err != nil { t.Errorf("%s: %v", c.file, err) continue } if si.PkgBase != c.pkgbase || si.Version() != c.version || si.URL != c.url { t.Errorf("%s: pkgbase=%q version=%q url=%q", c.file, si.PkgBase, si.Version(), si.URL) } if len(si.Sources) != c.nsources || len(si.PkgNames) != c.npkgs { t.Errorf("%s: %d sources, %d pkgnames", c.file, len(si.Sources), len(si.PkgNames)) } if len(si.Sources) > 0 && si.Sources[0].Raw != c.firstSource { t.Errorf("%s: first source %q", c.file, si.Sources[0].Raw) } locals := 0 for _, s := range si.Sources { if s.Local { locals++ } } if locals != c.locals { t.Errorf("%s: %d local sources, want %d", c.file, locals, c.locals) } if si.PkgNames[0] != c.pkgbase { t.Errorf("%s: first pkgname %q", c.file, si.PkgNames[0]) } } // Details on individual fixtures. zlib, _ := ParseSRCINFO(readFixture(t, "srcinfo_zlib.txt")) if zlib.Epoch != "1" || len(zlib.ValidPGPKeys) != 1 || zlib.ValidPGPKeys[0] != "5ED46A6721D365587791E2AA783FCD8E58BCAFBA" { t.Errorf("zlib: epoch=%q keys=%v", zlib.Epoch, zlib.ValidPGPKeys) } if got := zlib.Fields["sha512sums"]; len(got) != 3 || got[1] != "SKIP" { t.Errorf("zlib sha512sums = %v", got) } if got := zlib.Packages["minizip"]["pkgdesc"]; len(got) != 1 || got[0] != "Mini zip and unzip based on zlib" { t.Errorf("zlib minizip override = %v", got) } if got := zlib.PkgNames; got[1] != "zlib-static" || got[2] != "minizip" { t.Errorf("zlib pkgnames = %v", got) } gcc, _ := ParseSRCINFO(readFixture(t, "srcinfo_gcc.txt")) if s := gcc.Sources[0]; s.VCS != "git" || s.RefType != "commit" || s.Ref != "d564253eb6c859e266d3cae18e82fb4db9a88316" { t.Errorf("gcc git source = %+v", s) } if s := gcc.Sources[3]; !s.Local || s.LocalName != "gcc-ada-repro.patch" { t.Errorf("gcc patch source = %+v", s) } if got := gcc.Fields["options"]; len(got) != 2 || got[1] != "!lto" { t.Errorf("gcc options = %v", got) } sysd, _ := ParseSRCINFO(readFixture(t, "srcinfo_systemd.txt")) if s := sysd.Sources[0]; !s.Signed || s.Ref != "v262" || s.Remote() != "git+https://github.com/systemd/systemd#tag=v262" { t.Errorf("systemd git source = %+v", s) } if len(sysd.ValidPGPKeys) != 4 || len(sysd.Packages["systemd"]["backup"]) != 16 { t.Errorf("systemd keys=%d backup=%d", len(sysd.ValidPGPKeys), len(sysd.Packages["systemd"]["backup"])) } // Arch-specific sources and error cases. si, err := ParseSRCINFO([]byte("pkgbase = x\n\tpkgver = 1\n\tpkgrel = 2\n\tsource = common.tar.gz\n\tsource_x86_64 = https://example.org/x-1-x86_64.tar.gz\n\tsource_aarch64 = https://example.org/x-1-aarch64.tar.gz\n\npkgname = x\n")) if err != nil { t.Fatal(err) } if len(si.Sources) != 3 || si.Sources[1].Arch != "x86_64" || si.Sources[2].Arch != "aarch64" || si.Sources[0].Arch != "" { t.Errorf("arch sources = %+v", si.Sources) } if _, err := ParseSRCINFO([]byte("\tpkgver = 1\n")); err == nil { t.Error("expected error without pkgbase") } if _, err := ParseSRCINFO([]byte("pkgbase = x\nthis is not a key value line\n")); err == nil { t.Error("expected parse error") } }