From f759dd54c028e8b39fd1e21c8c70ebda567aa7cd Mon Sep 17 00:00:00 2001 From: Sida Chen Date: Mon, 15 Oct 2018 16:26:24 -0400 Subject: [PATCH] database: Replace Parent Feature with source metadata Feature's source feature string is directly stored in the database instead of having the parent pointer to simplify the database. --- database/dbutil.go | 9 +- database/models.go | 10 +- database/pgsql/testutil.go | 8 +- ext/featurefmt/apk/apk.go | 26 +-- ext/featurefmt/apk/apk_test.go | 25 +-- ext/featurefmt/dpkg/dpkg.go | 28 +-- ext/featurefmt/dpkg/dpkg_test.go | 191 +++++++++-------- ext/featurefmt/package_info.go | 56 ----- ext/featurefmt/rpm/rpm.go | 14 +- ext/featurefmt/rpm/rpm_test.go | 357 ++++++++++++++++--------------- ext/featurefmt/testutil.go | 36 +--- 11 files changed, 341 insertions(+), 419 deletions(-) delete mode 100644 ext/featurefmt/package_info.go diff --git a/database/dbutil.go b/database/dbutil.go index f1c90a67..9e1c753a 100644 --- a/database/dbutil.go +++ b/database/dbutil.go @@ -40,8 +40,13 @@ func DeduplicateFeatures(features ...Feature) []Feature { fSet.Add(f) } - uniqueFeatures := make([]Feature, 0, fSet.Cardinality()) - for f := range fSet.Iter() { + return ConvertFeatureSetToFeatures(fSet) +} + +// ConvertFeatureSetToFeatures converts a feature set to an array of features +func ConvertFeatureSetToFeatures(features mapset.Set) []Feature { + uniqueFeatures := make([]Feature, 0, features.Cardinality()) + for f := range features.Iter() { uniqueFeatures = append(uniqueFeatures, f.(Feature)) } diff --git a/database/models.go b/database/models.go index 58015011..e448f31b 100644 --- a/database/models.go +++ b/database/models.go @@ -158,19 +158,15 @@ type Namespace struct { // Feature represents a package detected in a layer but the namespace is not // determined. // -// e.g. Name: OpenSSL, Version: 1.0, VersionFormat: dpkg. +// e.g. Name: Libssl1.0, Version: 1.0, Name: Openssl, Version: 1.0, VersionFormat: dpkg. // dpkg is the version format of the installer package manager, which in this // case could be dpkg or apk. type Feature struct { Name string Version string + SourceName string + SourceVersion string VersionFormat string - - // Parent feature indicates that the vulnerability affects parent feature - // will also affect this feature. - // - // e.g. A source package is the parent feature of a binary package. - Parent *Feature } // NamespacedFeature is a feature with determined namespace and can be affected diff --git a/database/pgsql/testutil.go b/database/pgsql/testutil.go index 7f71bf15..45765b35 100644 --- a/database/pgsql/testutil.go +++ b/database/pgsql/testutil.go @@ -26,10 +26,10 @@ import ( // int keys must be the consistent with the database ID. var ( realFeatures = map[int]database.Feature{ - 1: {"ourchat", "0.5", "dpkg", nil}, - 2: {"openssl", "1.0", "dpkg", nil}, - 3: {"openssl", "2.0", "dpkg", nil}, - 4: {"fake", "2.0", "rpm", nil}, + 1: {"ourchat", "0.5", "ourchat", "0.5", "dpkg"}, + 2: {"openssl", "1.0", "openssl", "1.0", "dpkg"}, + 3: {"openssl", "2.0", "openssl", "2.0", "dpkg"}, + 4: {"fake", "2.0", "fake", "2.0", "rpm"}, } realNamespaces = map[int]database.Namespace{ diff --git a/ext/featurefmt/apk/apk.go b/ext/featurefmt/apk/apk.go index 5bd736d2..f0d29d21 100644 --- a/ext/featurefmt/apk/apk.go +++ b/ext/featurefmt/apk/apk.go @@ -35,14 +35,8 @@ func init() { type lister struct{} -func valid(pkg *featurefmt.PackageInfo) bool { - return pkg.PackageName != "" && pkg.PackageVersion != "" -} - -func addSourceVersion(pkg *featurefmt.PackageInfo) { - if pkg.SourceName != "" { - pkg.SourceVersion = pkg.PackageVersion - } +func valid(pkg *database.Feature) bool { + return pkg.Name != "" && pkg.Version != "" } func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) { @@ -55,23 +49,24 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) // package into a feature that will be stored in a set to guarantee // uniqueness. packages := mapset.NewSet() - pkg := featurefmt.PackageInfo{} + pkg := database.Feature{VersionFormat: dpkg.ParserName} scanner := bufio.NewScanner(bytes.NewBuffer(file)) for scanner.Scan() { line := scanner.Text() if len(line) < 2 { if valid(&pkg) { - addSourceVersion(&pkg) packages.Add(pkg) - pkg.Reset() + pkg = database.Feature{VersionFormat: dpkg.ParserName} } continue } // Parse the package name or version. + // Alpine package doesn't have specific source package. The "origin" + // package is sub package. switch line[:2] { case "P:": - pkg.PackageName = line[2:] + pkg.Name = line[2:] case "V:": version := string(line[2:]) err := versionfmt.Valid(dpkg.ParserName, version) @@ -79,20 +74,17 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) log.WithError(err).WithField("version", version).Warning("could not parse package version. skipping") continue } else { - pkg.PackageVersion = version + pkg.Version = version } - case "o:": - pkg.SourceName = line[2:] } } // in case of no terminal line if valid(&pkg) { - addSourceVersion(&pkg) packages.Add(pkg) } - return featurefmt.PackageSetToFeatures(dpkg.ParserName, packages), nil + return database.ConvertFeatureSetToFeatures(packages), nil } func (l lister) RequiredFilenames() []string { diff --git a/ext/featurefmt/apk/apk_test.go b/ext/featurefmt/apk/apk_test.go index 7f71fd3f..60461ed5 100644 --- a/ext/featurefmt/apk/apk_test.go +++ b/ext/featurefmt/apk/apk_test.go @@ -17,6 +17,7 @@ package apk import ( "testing" + "github.com/coreos/clair/database" "github.com/coreos/clair/ext/featurefmt" "github.com/coreos/clair/ext/versionfmt/dpkg" ) @@ -26,18 +27,18 @@ func TestAPKFeatureDetection(t *testing.T) { { "valid case", map[string]string{"lib/apk/db/installed": "apk/testdata/valid"}, - []featurefmt.PackageInfo{ - {"musl", "1.1.14-r10", "", ""}, - {"busybox", "1.24.2-r9", "", ""}, - {"alpine-baselayout", "3.0.3-r0", "", ""}, - {"alpine-keys", "1.1-r0", "", ""}, - {"zlib", "1.2.8-r2", "", ""}, - {"libcrypto1.0", "1.0.2h-r1", "openssl", "1.0.2h-r1"}, - {"libssl1.0", "1.0.2h-r1", "openssl", "1.0.2h-r1"}, - {"apk-tools", "2.6.7-r0", "", ""}, - {"scanelf", "1.1.6-r0", "pax-utils", "1.1.6-r0"}, - {"musl-utils", "1.1.14-r10", "musl", "1.1.14-r10"}, - {"libc-utils", "0.7-r0", "libc-dev", "0.7-r0"}, + []database.Feature{ + {"musl", "1.1.14-r10", "", "", dpkg.ParserName}, + {"busybox", "1.24.2-r9", "", "", dpkg.ParserName}, + {"alpine-baselayout", "3.0.3-r0", "", "", dpkg.ParserName}, + {"alpine-keys", "1.1-r0", "", "", dpkg.ParserName}, + {"zlib", "1.2.8-r2", "", "", dpkg.ParserName}, + {"libcrypto1.0", "1.0.2h-r1", "", "", dpkg.ParserName}, + {"libssl1.0", "1.0.2h-r1", "", "", dpkg.ParserName}, + {"apk-tools", "2.6.7-r0", "", "", dpkg.ParserName}, + {"scanelf", "1.1.6-r0", "", "", dpkg.ParserName}, + {"musl-utils", "1.1.14-r10", "", "", dpkg.ParserName}, + {"libc-utils", "0.7-r0", "", "", dpkg.ParserName}, }, }, } { diff --git a/ext/featurefmt/dpkg/dpkg.go b/ext/featurefmt/dpkg/dpkg.go index d000bfbf..4e0b60e2 100644 --- a/ext/featurefmt/dpkg/dpkg.go +++ b/ext/featurefmt/dpkg/dpkg.go @@ -41,13 +41,17 @@ func init() { featurefmt.RegisterLister("dpkg", "1.0", &lister{}) } -func valid(pkg *featurefmt.PackageInfo) bool { - return pkg.PackageName != "" && pkg.PackageVersion != "" +func valid(pkg *database.Feature) bool { + return pkg.Name != "" && pkg.Version != "" } -func addSourceVersion(pkg *featurefmt.PackageInfo) { - if pkg.SourceName != "" && pkg.SourceVersion == "" { - pkg.SourceVersion = pkg.PackageVersion +func addSourcePackage(pkg *database.Feature) { + if pkg.SourceName == "" { + pkg.SourceName = pkg.Name + } + + if pkg.SourceVersion == "" { + pkg.SourceVersion = pkg.Version } } @@ -58,7 +62,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) } var ( - pkg featurefmt.PackageInfo + pkg = database.Feature{VersionFormat: dpkg.ParserName} pkgs = mapset.NewSet() err error ) @@ -70,8 +74,8 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) // Package line // Defines the name of the package - pkg.PackageName = strings.TrimSpace(strings.TrimPrefix(line, "Package: ")) - pkg.PackageVersion = "" + pkg.Name = strings.TrimSpace(strings.TrimPrefix(line, "Package: ")) + pkg.Version = "" } else if strings.HasPrefix(line, "Source: ") { // Source line (Optional) // Gives the name of the source package @@ -102,19 +106,19 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) if err = versionfmt.Valid(dpkg.ParserName, version); err != nil { log.WithError(err).WithField("version", string(line[1])).Warning("could not parse package version. skipping") } else { - pkg.PackageVersion = version + pkg.Version = version } } else if line == "" { - pkg.Reset() + pkg = database.Feature{VersionFormat: dpkg.ParserName} } if valid(&pkg) { - addSourceVersion(&pkg) + addSourcePackage(&pkg) pkgs.Add(pkg) } } - return featurefmt.PackageSetToFeatures(dpkg.ParserName, pkgs), nil + return database.ConvertFeatureSetToFeatures(pkgs), nil } func (l lister) RequiredFilenames() []string { diff --git a/ext/featurefmt/dpkg/dpkg_test.go b/ext/featurefmt/dpkg/dpkg_test.go index ebbb0ccf..ff1de7a0 100644 --- a/ext/featurefmt/dpkg/dpkg_test.go +++ b/ext/featurefmt/dpkg/dpkg_test.go @@ -17,6 +17,7 @@ package dpkg import ( "testing" + "github.com/coreos/clair/database" "github.com/coreos/clair/ext/featurefmt" "github.com/coreos/clair/ext/versionfmt/dpkg" ) @@ -26,106 +27,106 @@ func TestListFeatures(t *testing.T) { { "valid status file", map[string]string{"var/lib/dpkg/status": "dpkg/testdata/valid"}, - []featurefmt.PackageInfo{ - {"adduser", "3.116ubuntu1", "", ""}, - {"apt", "1.6.3ubuntu0.1", "", ""}, - {"base-files", "10.1ubuntu2.2", "", ""}, - {"base-passwd", "3.5.44", "", ""}, - {"bash", "4.4.18-2ubuntu1", "", ""}, - {"bsdutils", "1:2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1"}, - {"bzip2", "1.0.6-8.1", "", ""}, - {"coreutils", "8.28-1ubuntu1", "", ""}, - {"dash", "0.5.8-2.10", "", ""}, - {"debconf", "1.5.66", "", ""}, - {"debianutils", "4.8.4", "", ""}, - {"diffutils", "1:3.6-1", "", ""}, - {"dpkg", "1.19.0.5ubuntu2", "", ""}, - {"e2fsprogs", "1.44.1-1", "", ""}, - {"fdisk", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1"}, - {"findutils", "4.6.0+git+20170828-2", "", ""}, - {"gcc-8-base", "8-20180414-1ubuntu2", "gcc-8", "8-20180414-1ubuntu2"}, - {"gpgv", "2.2.4-1ubuntu1.1", "gnupg2", "2.2.4-1ubuntu1.1"}, - {"grep", "3.1-2", "", ""}, - {"gzip", "1.6-5ubuntu1", "", ""}, - {"hostname", "3.20", "", ""}, - {"init-system-helpers", "1.51", "", ""}, - {"libacl1", "2.2.52-3build1", "acl", "2.2.52-3build1"}, - {"libapt-pkg5.0", "1.6.3ubuntu0.1", "apt", "1.6.3ubuntu0.1"}, - {"libattr1", "1:2.4.47-2build1", "attr", "1:2.4.47-2build1"}, - {"libaudit-common", "1:2.8.2-1ubuntu1", "audit", "1:2.8.2-1ubuntu1"}, - {"libaudit1", "1:2.8.2-1ubuntu1", "audit", "1:2.8.2-1ubuntu1"}, - {"libblkid1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1"}, - {"libbz2-1.0", "1.0.6-8.1", "bzip2", "1.0.6-8.1"}, - {"libc-bin", "2.27-3ubuntu1", "glibc", "2.27-3ubuntu1"}, - {"libc6", "2.27-3ubuntu1", "glibc", "2.27-3ubuntu1"}, - {"libcap-ng0", "0.7.7-3.1", "libcap-ng", "0.7.7-3.1"}, - {"libcom-err2", "1.44.1-1", "e2fsprogs", "1.44.1-1"}, - {"libdb5.3", "5.3.28-13.1ubuntu1", "db5.3", "5.3.28-13.1ubuntu1"}, - {"libdebconfclient0", "0.213ubuntu1", "cdebconf", "0.213ubuntu1"}, - {"libext2fs2", "1.44.1-1", "e2fsprogs", "1.44.1-1"}, - {"libfdisk1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1"}, - {"libffi6", "3.2.1-8", "libffi", "3.2.1-8"}, - {"libgcc1", "1:8-20180414-1ubuntu2", "gcc-8", "8-20180414-1ubuntu2"}, - {"libgcrypt20", "1.8.1-4ubuntu1.1", "", ""}, - {"libgmp10", "2:6.1.2+dfsg-2", "gmp", "2:6.1.2+dfsg-2"}, - {"libgnutls30", "3.5.18-1ubuntu1", "gnutls28", "3.5.18-1ubuntu1"}, - {"libgpg-error0", "1.27-6", "libgpg-error", "1.27-6"}, - {"libhogweed4", "3.4-1", "nettle", "3.4-1"}, - {"libidn2-0", "2.0.4-1.1build2", "libidn2", "2.0.4-1.1build2"}, - {"liblz4-1", "0.0~r131-2ubuntu3", "lz4", "0.0~r131-2ubuntu3"}, - {"liblzma5", "5.2.2-1.3", "xz-utils", "5.2.2-1.3"}, - {"libmount1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1"}, - {"libncurses5", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04"}, - {"libncursesw5", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04"}, - {"libnettle6", "3.4-1", "nettle", "3.4-1"}, - {"libp11-kit0", "0.23.9-2", "p11-kit", "0.23.9-2"}, - {"libpam-modules", "1.1.8-3.6ubuntu2", "pam", "1.1.8-3.6ubuntu2"}, - {"libpam-modules-bin", "1.1.8-3.6ubuntu2", "pam", "1.1.8-3.6ubuntu2"}, - {"libpam-runtime", "1.1.8-3.6ubuntu2", "pam", "1.1.8-3.6ubuntu2"}, - {"libpam0g", "1.1.8-3.6ubuntu2", "pam", "1.1.8-3.6ubuntu2"}, - {"libpcre3", "2:8.39-9", "pcre3", "2:8.39-9"}, - {"libprocps6", "2:3.3.12-3ubuntu1.1", "procps", "2:3.3.12-3ubuntu1.1"}, - {"libseccomp2", "2.3.1-2.1ubuntu4", "libseccomp", "2.3.1-2.1ubuntu4"}, - {"libselinux1", "2.7-2build2", "libselinux", "2.7-2build2"}, - {"libsemanage-common", "2.7-2build2", "libsemanage", "2.7-2build2"}, - {"libsemanage1", "2.7-2build2", "libsemanage", "2.7-2build2"}, - {"libsepol1", "2.7-1", "libsepol", "2.7-1"}, - {"libsmartcols1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1"}, - {"libss2", "1.44.1-1", "e2fsprogs", "1.44.1-1"}, - {"libstdc++6", "8-20180414-1ubuntu2", "gcc-8", "8-20180414-1ubuntu2"}, - {"libsystemd0", "237-3ubuntu10.3", "systemd", "237-3ubuntu10.3"}, - {"libtasn1-6", "4.13-2", "", ""}, - {"libtinfo5", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04"}, - {"libudev1", "237-3ubuntu10.3", "systemd", "237-3ubuntu10.3"}, - {"libunistring2", "0.9.9-0ubuntu1", "libunistring", "0.9.9-0ubuntu1"}, - {"libuuid1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1"}, - {"libzstd1", "1.3.3+dfsg-2ubuntu1", "libzstd", "1.3.3+dfsg-2ubuntu1"}, - {"login", "1:4.5-1ubuntu1", "shadow", "1:4.5-1ubuntu1"}, - {"lsb-base", "9.20170808ubuntu1", "lsb", "9.20170808ubuntu1"}, - {"mawk", "1.3.3-17ubuntu3", "", ""}, - {"mount", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1"}, - {"ncurses-base", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04"}, - {"ncurses-bin", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04"}, - {"passwd", "1:4.5-1ubuntu1", "shadow", "1:4.5-1ubuntu1"}, - {"perl-base", "5.26.1-6ubuntu0.2", "perl", "5.26.1-6ubuntu0.2"}, - {"procps", "2:3.3.12-3ubuntu1.1", "", ""}, - {"sed", "4.4-2", "", ""}, - {"sensible-utils", "0.0.12", "", ""}, - {"sysvinit-utils", "2.88dsf-59.10ubuntu1", "sysvinit", "2.88dsf-59.10ubuntu1"}, - {"tar", "1.29b-2", "", ""}, - {"ubuntu-keyring", "2018.02.28", "", ""}, - {"util-linux", "2.31.1-0.4ubuntu3.1", "", ""}, - {"zlib1g", "1:1.2.11.dfsg-0ubuntu2", "zlib", "1:1.2.11.dfsg-0ubuntu2"}, + []database.Feature{ + {"adduser", "3.116ubuntu1", "adduser", "3.116ubuntu1", dpkg.ParserName}, + {"apt", "1.6.3ubuntu0.1", "apt", "1.6.3ubuntu0.1", dpkg.ParserName}, + {"base-files", "10.1ubuntu2.2", "base-files", "10.1ubuntu2.2", dpkg.ParserName}, + {"base-passwd", "3.5.44", "base-passwd", "3.5.44", dpkg.ParserName}, + {"bash", "4.4.18-2ubuntu1", "bash", "4.4.18-2ubuntu1", dpkg.ParserName}, + {"bsdutils", "1:2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1", dpkg.ParserName}, + {"bzip2", "1.0.6-8.1", "bzip2", "1.0.6-8.1", dpkg.ParserName}, + {"coreutils", "8.28-1ubuntu1", "coreutils", "8.28-1ubuntu1", dpkg.ParserName}, + {"dash", "0.5.8-2.10", "dash", "0.5.8-2.10", dpkg.ParserName}, + {"debconf", "1.5.66", "debconf", "1.5.66", dpkg.ParserName}, + {"debianutils", "4.8.4", "debianutils", "4.8.4", dpkg.ParserName}, + {"diffutils", "1:3.6-1", "diffutils", "1:3.6-1", dpkg.ParserName}, + {"dpkg", "1.19.0.5ubuntu2", "dpkg", "1.19.0.5ubuntu2", dpkg.ParserName}, + {"e2fsprogs", "1.44.1-1", "e2fsprogs", "1.44.1-1", dpkg.ParserName}, + {"fdisk", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1", dpkg.ParserName}, + {"findutils", "4.6.0+git+20170828-2", "findutils", "4.6.0+git+20170828-2", dpkg.ParserName}, + {"gcc-8-base", "8-20180414-1ubuntu2", "gcc-8", "8-20180414-1ubuntu2", dpkg.ParserName}, + {"gpgv", "2.2.4-1ubuntu1.1", "gnupg2", "2.2.4-1ubuntu1.1", dpkg.ParserName}, + {"grep", "3.1-2", "grep", "3.1-2", dpkg.ParserName}, + {"gzip", "1.6-5ubuntu1", "gzip", "1.6-5ubuntu1", dpkg.ParserName}, + {"hostname", "3.20", "hostname", "3.20", dpkg.ParserName}, + {"init-system-helpers", "1.51", "init-system-helpers", "1.51", dpkg.ParserName}, + {"libacl1", "2.2.52-3build1", "acl", "2.2.52-3build1", dpkg.ParserName}, + {"libapt-pkg5.0", "1.6.3ubuntu0.1", "apt", "1.6.3ubuntu0.1", dpkg.ParserName}, + {"libattr1", "1:2.4.47-2build1", "attr", "1:2.4.47-2build1", dpkg.ParserName}, + {"libaudit-common", "1:2.8.2-1ubuntu1", "audit", "1:2.8.2-1ubuntu1", dpkg.ParserName}, + {"libaudit1", "1:2.8.2-1ubuntu1", "audit", "1:2.8.2-1ubuntu1", dpkg.ParserName}, + {"libblkid1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1", dpkg.ParserName}, + {"libbz2-1.0", "1.0.6-8.1", "bzip2", "1.0.6-8.1", dpkg.ParserName}, + {"libc-bin", "2.27-3ubuntu1", "glibc", "2.27-3ubuntu1", dpkg.ParserName}, + {"libc6", "2.27-3ubuntu1", "glibc", "2.27-3ubuntu1", dpkg.ParserName}, + {"libcap-ng0", "0.7.7-3.1", "libcap-ng", "0.7.7-3.1", dpkg.ParserName}, + {"libcom-err2", "1.44.1-1", "e2fsprogs", "1.44.1-1", dpkg.ParserName}, + {"libdb5.3", "5.3.28-13.1ubuntu1", "db5.3", "5.3.28-13.1ubuntu1", dpkg.ParserName}, + {"libdebconfclient0", "0.213ubuntu1", "cdebconf", "0.213ubuntu1", dpkg.ParserName}, + {"libext2fs2", "1.44.1-1", "e2fsprogs", "1.44.1-1", dpkg.ParserName}, + {"libfdisk1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1", dpkg.ParserName}, + {"libffi6", "3.2.1-8", "libffi", "3.2.1-8", dpkg.ParserName}, + {"libgcc1", "1:8-20180414-1ubuntu2", "gcc-8", "8-20180414-1ubuntu2", dpkg.ParserName}, + {"libgcrypt20", "1.8.1-4ubuntu1.1", "libgcrypt20", "1.8.1-4ubuntu1.1", dpkg.ParserName}, + {"libgmp10", "2:6.1.2+dfsg-2", "gmp", "2:6.1.2+dfsg-2", dpkg.ParserName}, + {"libgnutls30", "3.5.18-1ubuntu1", "gnutls28", "3.5.18-1ubuntu1", dpkg.ParserName}, + {"libgpg-error0", "1.27-6", "libgpg-error", "1.27-6", dpkg.ParserName}, + {"libhogweed4", "3.4-1", "nettle", "3.4-1", dpkg.ParserName}, + {"libidn2-0", "2.0.4-1.1build2", "libidn2", "2.0.4-1.1build2", dpkg.ParserName}, + {"liblz4-1", "0.0~r131-2ubuntu3", "lz4", "0.0~r131-2ubuntu3", dpkg.ParserName}, + {"liblzma5", "5.2.2-1.3", "xz-utils", "5.2.2-1.3", dpkg.ParserName}, + {"libmount1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1", dpkg.ParserName}, + {"libncurses5", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04", dpkg.ParserName}, + {"libncursesw5", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04", dpkg.ParserName}, + {"libnettle6", "3.4-1", "nettle", "3.4-1", dpkg.ParserName}, + {"libp11-kit0", "0.23.9-2", "p11-kit", "0.23.9-2", dpkg.ParserName}, + {"libpam-modules", "1.1.8-3.6ubuntu2", "pam", "1.1.8-3.6ubuntu2", dpkg.ParserName}, + {"libpam-modules-bin", "1.1.8-3.6ubuntu2", "pam", "1.1.8-3.6ubuntu2", dpkg.ParserName}, + {"libpam-runtime", "1.1.8-3.6ubuntu2", "pam", "1.1.8-3.6ubuntu2", dpkg.ParserName}, + {"libpam0g", "1.1.8-3.6ubuntu2", "pam", "1.1.8-3.6ubuntu2", dpkg.ParserName}, + {"libpcre3", "2:8.39-9", "pcre3", "2:8.39-9", dpkg.ParserName}, + {"libprocps6", "2:3.3.12-3ubuntu1.1", "procps", "2:3.3.12-3ubuntu1.1", dpkg.ParserName}, + {"libseccomp2", "2.3.1-2.1ubuntu4", "libseccomp", "2.3.1-2.1ubuntu4", dpkg.ParserName}, + {"libselinux1", "2.7-2build2", "libselinux", "2.7-2build2", dpkg.ParserName}, + {"libsemanage-common", "2.7-2build2", "libsemanage", "2.7-2build2", dpkg.ParserName}, + {"libsemanage1", "2.7-2build2", "libsemanage", "2.7-2build2", dpkg.ParserName}, + {"libsepol1", "2.7-1", "libsepol", "2.7-1", dpkg.ParserName}, + {"libsmartcols1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1", dpkg.ParserName}, + {"libss2", "1.44.1-1", "e2fsprogs", "1.44.1-1", dpkg.ParserName}, + {"libstdc++6", "8-20180414-1ubuntu2", "gcc-8", "8-20180414-1ubuntu2", dpkg.ParserName}, + {"libsystemd0", "237-3ubuntu10.3", "systemd", "237-3ubuntu10.3", dpkg.ParserName}, + {"libtasn1-6", "4.13-2", "libtasn1-6", "4.13-2", dpkg.ParserName}, + {"libtinfo5", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04", dpkg.ParserName}, + {"libudev1", "237-3ubuntu10.3", "systemd", "237-3ubuntu10.3", dpkg.ParserName}, + {"libunistring2", "0.9.9-0ubuntu1", "libunistring", "0.9.9-0ubuntu1", dpkg.ParserName}, + {"libuuid1", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1", dpkg.ParserName}, + {"libzstd1", "1.3.3+dfsg-2ubuntu1", "libzstd", "1.3.3+dfsg-2ubuntu1", dpkg.ParserName}, + {"login", "1:4.5-1ubuntu1", "shadow", "1:4.5-1ubuntu1", dpkg.ParserName}, + {"lsb-base", "9.20170808ubuntu1", "lsb", "9.20170808ubuntu1", dpkg.ParserName}, + {"mawk", "1.3.3-17ubuntu3", "mawk", "1.3.3-17ubuntu3", dpkg.ParserName}, + {"mount", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1", dpkg.ParserName}, + {"ncurses-base", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04", dpkg.ParserName}, + {"ncurses-bin", "6.1-1ubuntu1.18.04", "ncurses", "6.1-1ubuntu1.18.04", dpkg.ParserName}, + {"passwd", "1:4.5-1ubuntu1", "shadow", "1:4.5-1ubuntu1", dpkg.ParserName}, + {"perl-base", "5.26.1-6ubuntu0.2", "perl", "5.26.1-6ubuntu0.2", dpkg.ParserName}, + {"procps", "2:3.3.12-3ubuntu1.1", "procps", "2:3.3.12-3ubuntu1.1", dpkg.ParserName}, + {"sed", "4.4-2", "sed", "4.4-2", dpkg.ParserName}, + {"sensible-utils", "0.0.12", "sensible-utils", "0.0.12", dpkg.ParserName}, + {"sysvinit-utils", "2.88dsf-59.10ubuntu1", "sysvinit", "2.88dsf-59.10ubuntu1", dpkg.ParserName}, + {"tar", "1.29b-2", "tar", "1.29b-2", dpkg.ParserName}, + {"ubuntu-keyring", "2018.02.28", "ubuntu-keyring", "2018.02.28", dpkg.ParserName}, + {"util-linux", "2.31.1-0.4ubuntu3.1", "util-linux", "2.31.1-0.4ubuntu3.1", dpkg.ParserName}, + {"zlib1g", "1:1.2.11.dfsg-0ubuntu2", "zlib", "1:1.2.11.dfsg-0ubuntu2", dpkg.ParserName}, }, }, { "corrupted status file", map[string]string{"var/lib/dpkg/status": "dpkg/testdata/corrupted"}, - []featurefmt.PackageInfo{ - {"libpam-runtime", "1.1.8-3.1ubuntu3", "pam", "1.1.8-3.1ubuntu3"}, - {"libpam-modules-bin", "1.1.8-3.1ubuntu3", "pam", "1.1.8-3.1ubuntu3"}, - {"makedev", "2.3.1-93ubuntu1", "", ""}, - {"libgcc1", "1:5.1.1-12ubuntu1", "gcc-5", "5.1.1-12ubuntu1"}, + []database.Feature{ + {"libpam-runtime", "1.1.8-3.1ubuntu3", "pam", "1.1.8-3.1ubuntu3", dpkg.ParserName}, + {"libpam-modules-bin", "1.1.8-3.1ubuntu3", "pam", "1.1.8-3.1ubuntu3", dpkg.ParserName}, + {"makedev", "2.3.1-93ubuntu1", "makedev", "2.3.1-93ubuntu1", dpkg.ParserName}, + {"libgcc1", "1:5.1.1-12ubuntu1", "gcc-5", "5.1.1-12ubuntu1", dpkg.ParserName}, }, }, } { diff --git a/ext/featurefmt/package_info.go b/ext/featurefmt/package_info.go deleted file mode 100644 index 91f9aed1..00000000 --- a/ext/featurefmt/package_info.go +++ /dev/null @@ -1,56 +0,0 @@ -package featurefmt - -import ( - "github.com/coreos/clair/database" - "github.com/deckarep/golang-set" -) - -// PackageInfo is the extracted raw information from the package managers that -// can be converted to a feature. -type PackageInfo struct { - PackageName string - PackageVersion string - SourceName string - SourceVersion string -} - -// Reset defaults the internal string fields to empty strings. -func (pkg *PackageInfo) Reset() { - pkg.PackageName = "" - pkg.PackageVersion = "" - pkg.SourceName = "" - pkg.SourceVersion = "" -} - -func (pkg *PackageInfo) asFeature(versionFormat string) database.Feature { - feature := database.Feature{ - Name: pkg.PackageName, - Version: pkg.PackageVersion, - VersionFormat: versionFormat, - } - - if pkg.SourceName != "" { - parent := database.Feature{ - Name: pkg.SourceName, - Version: pkg.SourceVersion, - VersionFormat: versionFormat, - } - - if parent != feature { - feature.Parent = &parent - } - } - - return feature -} - -// PackageSetToFeatures converts a package set to feature slice -func PackageSetToFeatures(versionFormat string, pkgs mapset.Set) []database.Feature { - features := make([]database.Feature, 0, pkgs.Cardinality()) - for pkg := range pkgs.Iter() { - p := pkg.(PackageInfo) - features = append(features, p.asFeature(versionFormat)) - } - - return features -} diff --git a/ext/featurefmt/rpm/rpm.go b/ext/featurefmt/rpm/rpm.go index 634dfd0e..5ad70191 100644 --- a/ext/featurefmt/rpm/rpm.go +++ b/ext/featurefmt/rpm/rpm.go @@ -55,8 +55,8 @@ func isIgnored(packageName string) bool { return false } -func valid(pkg *featurefmt.PackageInfo) bool { - return pkg.PackageName != "" && pkg.PackageVersion != "" && +func valid(pkg *database.Feature) bool { + return pkg.Name != "" && pkg.Version != "" && ((pkg.SourceName == "" && pkg.SourceVersion != "") || (pkg.SourceName != "" && pkg.SourceVersion != "")) } @@ -104,9 +104,9 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) continue } - pkg := featurefmt.PackageInfo{PackageName: line[0]} - pkg.PackageVersion = strings.Replace(line[1], "(none):", "", -1) - if err := versionfmt.Valid(rpm.ParserName, pkg.PackageVersion); err != nil { + pkg := database.Feature{Name: line[0], VersionFormat: rpm.ParserName} + pkg.Version = strings.Replace(line[1], "(none):", "", -1) + if err := versionfmt.Valid(rpm.ParserName, pkg.Version); err != nil { log.WithError(err).WithField("version", line[1]).Warning("skipped unparseable package") continue } @@ -121,7 +121,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) } } - return featurefmt.PackageSetToFeatures(rpm.ParserName, packages), nil + return database.ConvertFeatureSetToFeatures(packages), nil } func (l lister) RequiredFilenames() []string { @@ -140,7 +140,7 @@ const ( // parseSourceRPM parses the source rpm package representation string // http://ftp.rpm.org/max-rpm/ch-rpm-file-format.html -func parseSourceRPM(sourceRPM string, pkg *featurefmt.PackageInfo) error { +func parseSourceRPM(sourceRPM string, pkg *database.Feature) error { state := parseRPM previousCheckPoint := len(sourceRPM) release := "" diff --git a/ext/featurefmt/rpm/rpm_test.go b/ext/featurefmt/rpm/rpm_test.go index a4e05fae..d727d203 100644 --- a/ext/featurefmt/rpm/rpm_test.go +++ b/ext/featurefmt/rpm/rpm_test.go @@ -19,184 +19,185 @@ import ( "github.com/stretchr/testify/require" + "github.com/coreos/clair/database" "github.com/coreos/clair/ext/featurefmt" "github.com/coreos/clair/ext/versionfmt/rpm" ) -var expectedBigCaseInfo = []featurefmt.PackageInfo{ - {"publicsuffix-list-dafsa", "20180514-1.fc28", "publicsuffix-list", "20180514-1.fc28"}, - {"libreport-filesystem", "2.9.5-1.fc28", "libreport", "2.9.5-1.fc28"}, - {"fedora-gpg-keys", "28-5", "fedora-repos", "28-5"}, - {"fedora-release", "28-2", "", ""}, - {"filesystem", "3.8-2.fc28", "", ""}, - {"tzdata", "2018e-1.fc28", "", ""}, - {"pcre2", "10.31-10.fc28", "", ""}, - {"glibc-minimal-langpack", "2.27-32.fc28", "glibc", "2.27-32.fc28"}, - {"glibc-common", "2.27-32.fc28", "glibc", "2.27-32.fc28"}, - {"bash", "4.4.23-1.fc28", "", ""}, - {"zlib", "1.2.11-8.fc28", "", ""}, - {"bzip2-libs", "1.0.6-26.fc28", "bzip2", "1.0.6-26.fc28"}, - {"libcap", "2.25-9.fc28", "", ""}, - {"libgpg-error", "1.31-1.fc28", "", ""}, - {"libzstd", "1.3.5-1.fc28", "zstd", "1.3.5-1.fc28"}, - {"expat", "2.2.5-3.fc28", "", ""}, - {"nss-util", "3.38.0-1.0.fc28", "", ""}, - {"libcom_err", "1.44.2-0.fc28", "e2fsprogs", "1.44.2-0.fc28"}, - {"libffi", "3.1-16.fc28", "", ""}, - {"libgcrypt", "1.8.3-1.fc28", "", ""}, - {"libxml2", "2.9.8-4.fc28", "", ""}, - {"libacl", "2.2.53-1.fc28", "acl", "2.2.53-1.fc28"}, - {"sed", "4.5-1.fc28", "", ""}, - {"libmount", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28"}, - {"p11-kit", "0.23.12-1.fc28", "", ""}, - {"libidn2", "2.0.5-1.fc28", "", ""}, - {"libcap-ng", "0.7.9-4.fc28", "", ""}, - {"lz4-libs", "1.8.1.2-4.fc28", "lz4", "1.8.1.2-4.fc28"}, - {"libassuan", "2.5.1-3.fc28", "", ""}, - {"keyutils-libs", "1.5.10-6.fc28", "keyutils", "1.5.10-6.fc28"}, - {"glib2", "2.56.1-4.fc28", "", ""}, - {"systemd-libs", "238-9.git0e0aa59.fc28", "systemd", "238-9.git0e0aa59.fc28"}, - {"dbus-libs", "1:1.12.10-1.fc28", "dbus", "1.12.10-1.fc28"}, - {"libtasn1", "4.13-2.fc28", "", ""}, - {"ca-certificates", "2018.2.24-1.0.fc28", "", ""}, - {"libarchive", "3.3.1-4.fc28", "", ""}, - {"openssl", "1:1.1.0h-3.fc28", "openssl", "1.1.0h-3.fc28"}, - {"libusbx", "1.0.22-1.fc28", "", ""}, - {"libsemanage", "2.8-2.fc28", "", ""}, - {"libutempter", "1.1.6-14.fc28", "", ""}, - {"mpfr", "3.1.6-1.fc28", "", ""}, - {"gnutls", "3.6.3-4.fc28", "", ""}, - {"gzip", "1.9-3.fc28", "", ""}, - {"acl", "2.2.53-1.fc28", "", ""}, - {"nss-softokn-freebl", "3.38.0-1.0.fc28", "nss-softokn", "3.38.0-1.0.fc28"}, - {"nss", "3.38.0-1.0.fc28", "", ""}, - {"libmetalink", "0.1.3-6.fc28", "", ""}, - {"libdb-utils", "5.3.28-30.fc28", "libdb", "5.3.28-30.fc28"}, - {"file-libs", "5.33-7.fc28", "file", "5.33-7.fc28"}, - {"libsss_idmap", "1.16.3-2.fc28", "sssd", "1.16.3-2.fc28"}, - {"libsigsegv", "2.11-5.fc28", "", ""}, - {"krb5-libs", "1.16.1-13.fc28", "krb5", "1.16.1-13.fc28"}, - {"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "", ""}, - {"python3-pip", "9.0.3-2.fc28", "python-pip", "9.0.3-2.fc28"}, - {"python3", "3.6.6-1.fc28", "", ""}, - {"pam", "1.3.1-1.fc28", "", ""}, - {"python3-gobject-base", "3.28.3-1.fc28", "pygobject3", "3.28.3-1.fc28"}, - {"python3-smartcols", "0.3.0-2.fc28", "python-smartcols", "0.3.0-2.fc28"}, - {"python3-iniparse", "0.4-30.fc28", "python-iniparse", "0.4-30.fc28"}, - {"openldap", "2.4.46-3.fc28", "", ""}, - {"libseccomp", "2.3.3-2.fc28", "", ""}, - {"npth", "1.5-4.fc28", "", ""}, - {"gpgme", "1.10.0-4.fc28", "", ""}, - {"json-c", "0.13.1-2.fc28", "", ""}, - {"libyaml", "0.1.7-5.fc28", "", ""}, - {"libpkgconf", "1.4.2-1.fc28", "pkgconf", "1.4.2-1.fc28"}, - {"pkgconf-pkg-config", "1.4.2-1.fc28", "pkgconf", "1.4.2-1.fc28"}, - {"iptables-libs", "1.6.2-3.fc28", "iptables", "1.6.2-3.fc28"}, - {"device-mapper-libs", "1.02.146-5.fc28", "lvm2", "2.02.177-5.fc28"}, - {"systemd-pam", "238-9.git0e0aa59.fc28", "systemd", "238-9.git0e0aa59.fc28"}, - {"systemd", "238-9.git0e0aa59.fc28", "", ""}, - {"elfutils-default-yama-scope", "0.173-1.fc28", "elfutils", "0.173-1.fc28"}, - {"libcurl", "7.59.0-6.fc28", "curl", "7.59.0-6.fc28"}, - {"python3-librepo", "1.8.1-7.fc28", "librepo", "1.8.1-7.fc28"}, - {"rpm-plugin-selinux", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28"}, - {"rpm", "4.14.1-9.fc28", "", ""}, - {"libdnf", "0.11.1-3.fc28", "", ""}, - {"rpm-build-libs", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28"}, - {"python3-rpm", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28"}, - {"dnf", "2.7.5-12.fc28", "", ""}, - {"deltarpm", "3.6-25.fc28", "", ""}, - {"sssd-client", "1.16.3-2.fc28", "sssd", "1.16.3-2.fc28"}, - {"cracklib-dicts", "2.9.6-13.fc28", "cracklib", "2.9.6-13.fc28"}, - {"tar", "2:1.30-3.fc28", "tar", "1.30-3.fc28"}, - {"diffutils", "3.6-4.fc28", "", ""}, - {"langpacks-en", "1.0-12.fc28", "langpacks", "1.0-12.fc28"}, - {"libgcc", "8.1.1-5.fc28", "gcc", "8.1.1-5.fc28"}, - {"pkgconf-m4", "1.4.2-1.fc28", "pkgconf", "1.4.2-1.fc28"}, - {"dnf-conf", "2.7.5-12.fc28", "dnf", "2.7.5-12.fc28"}, - {"fedora-repos", "28-5", "", ""}, - {"setup", "2.11.4-1.fc28", "", ""}, - {"basesystem", "11-5.fc28", "", ""}, - {"ncurses-base", "6.1-5.20180224.fc28", "ncurses", "6.1-5.20180224.fc28"}, - {"libselinux", "2.8-1.fc28", "", ""}, - {"ncurses-libs", "6.1-5.20180224.fc28", "ncurses", "6.1-5.20180224.fc28"}, - {"glibc", "2.27-32.fc28", "", ""}, - {"libsepol", "2.8-1.fc28", "", ""}, - {"xz-libs", "5.2.4-2.fc28", "xz", "5.2.4-2.fc28"}, - {"info", "6.5-4.fc28", "texinfo", "6.5-4.fc28"}, - {"libdb", "5.3.28-30.fc28", "", ""}, - {"elfutils-libelf", "0.173-1.fc28", "elfutils", "0.173-1.fc28"}, - {"popt", "1.16-14.fc28", "", ""}, - {"nspr", "4.19.0-1.fc28", "", ""}, - {"libxcrypt", "4.1.2-1.fc28", "", ""}, - {"lua-libs", "5.3.4-10.fc28", "lua", "5.3.4-10.fc28"}, - {"libuuid", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28"}, - {"readline", "7.0-11.fc28", "", ""}, - {"libattr", "2.4.48-3.fc28", "attr", "2.4.48-3.fc28"}, - {"coreutils-single", "8.29-7.fc28", "coreutils", "8.29-7.fc28"}, - {"libblkid", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28"}, - {"gmp", "1:6.1.2-7.fc28", "gmp", "6.1.2-7.fc28"}, - {"libunistring", "0.9.10-1.fc28", "", ""}, - {"sqlite-libs", "3.22.0-4.fc28", "sqlite", "3.22.0-4.fc28"}, - {"audit-libs", "2.8.4-2.fc28", "audit", "2.8.4-2.fc28"}, - {"chkconfig", "1.10-4.fc28", "", ""}, - {"libsmartcols", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28"}, - {"pcre", "8.42-3.fc28", "", ""}, - {"grep", "3.1-5.fc28", "", ""}, - {"crypto-policies", "20180425-5.git6ad4018.fc28", "", ""}, - {"gdbm-libs", "1:1.14.1-4.fc28", "gdbm", "1.14.1-4.fc28"}, - {"p11-kit-trust", "0.23.12-1.fc28", "p11-kit", "0.23.12-1.fc28"}, - {"openssl-libs", "1:1.1.0h-3.fc28", "openssl", "1.1.0h-3.fc28"}, - {"ima-evm-utils", "1.1-2.fc28", "", ""}, - {"gdbm", "1:1.14.1-4.fc28", "gdbm", "1.14.1-4.fc28"}, - {"gobject-introspection", "1.56.1-1.fc28", "", ""}, - {"shadow-utils", "2:4.6-1.fc28", "shadow-utils", "4.6-1.fc28"}, - {"libpsl", "0.20.2-2.fc28", "", ""}, - {"nettle", "3.4-2.fc28", "", ""}, - {"libfdisk", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28"}, - {"cracklib", "2.9.6-13.fc28", "", ""}, - {"libcomps", "0.1.8-11.fc28", "", ""}, - {"nss-softokn", "3.38.0-1.0.fc28", "", ""}, - {"nss-sysinit", "3.38.0-1.0.fc28", "nss", "3.38.0-1.0.fc28"}, - {"libksba", "1.3.5-7.fc28", "", ""}, - {"kmod-libs", "25-2.fc28", "kmod", "25-2.fc28"}, - {"libsss_nss_idmap", "1.16.3-2.fc28", "sssd", "1.16.3-2.fc28"}, - {"libverto", "0.3.0-5.fc28", "", ""}, - {"gawk", "4.2.1-1.fc28", "", ""}, - {"libtirpc", "1.0.3-3.rc2.fc28", "", ""}, - {"python3-libs", "3.6.6-1.fc28", "python3", "3.6.6-1.fc28"}, - {"python3-setuptools", "39.2.0-6.fc28", "python-setuptools", "39.2.0-6.fc28"}, - {"libpwquality", "1.4.0-7.fc28", "", ""}, - {"util-linux", "2.32.1-1.fc28", "", ""}, - {"python3-libcomps", "0.1.8-11.fc28", "libcomps", "0.1.8-11.fc28"}, - {"python3-six", "1.11.0-3.fc28", "python-six", "1.11.0-3.fc28"}, - {"cyrus-sasl-lib", "2.1.27-0.2rc7.fc28", "cyrus-sasl", "2.1.27-0.2rc7.fc28"}, - {"libssh", "0.8.2-1.fc28", "", ""}, - {"qrencode-libs", "3.4.4-5.fc28", "qrencode", "3.4.4-5.fc28"}, - {"gnupg2", "2.2.8-1.fc28", "", ""}, - {"python3-gpg", "1.10.0-4.fc28", "gpgme", "1.10.0-4.fc28"}, - {"libargon2", "20161029-5.fc28", "argon2", "20161029-5.fc28"}, - {"libmodulemd", "1.6.2-2.fc28", "", ""}, - {"pkgconf", "1.4.2-1.fc28", "", ""}, - {"libpcap", "14:1.9.0-1.fc28", "libpcap", "1.9.0-1.fc28"}, - {"device-mapper", "1.02.146-5.fc28", "lvm2", "2.02.177-5.fc28"}, - {"cryptsetup-libs", "2.0.4-1.fc28", "cryptsetup", "2.0.4-1.fc28"}, - {"elfutils-libs", "0.173-1.fc28", "elfutils", "0.173-1.fc28"}, - {"dbus", "1:1.12.10-1.fc28", "dbus", "1.12.10-1.fc28"}, - {"libnghttp2", "1.32.1-1.fc28", "nghttp2", "1.32.1-1.fc28"}, - {"librepo", "1.8.1-7.fc28", "", ""}, - {"curl", "7.59.0-6.fc28", "", ""}, - {"rpm-libs", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28"}, - {"libsolv", "0.6.35-1.fc28", "", ""}, - {"python3-hawkey", "0.11.1-3.fc28", "libdnf", "0.11.1-3.fc28"}, - {"rpm-sign-libs", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28"}, - {"python3-dnf", "2.7.5-12.fc28", "dnf", "2.7.5-12.fc28"}, - {"dnf-yum", "2.7.5-12.fc28", "dnf", "2.7.5-12.fc28"}, - {"rpm-plugin-systemd-inhibit", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28"}, - {"nss-tools", "3.38.0-1.0.fc28", "nss", "3.38.0-1.0.fc28"}, - {"openssl-pkcs11", "0.4.8-1.fc28", "", ""}, - {"vim-minimal", "2:8.1.328-1.fc28", "vim", "8.1.328-1.fc28"}, - {"glibc-langpack-en", "2.27-32.fc28", "glibc", "2.27-32.fc28"}, - {"rootfiles", "8.1-22.fc28", "", ""}, +var expectedBigCaseInfo = []database.Feature{ + {"publicsuffix-list-dafsa", "20180514-1.fc28", "publicsuffix-list", "20180514-1.fc28", rpm.ParserName}, + {"libreport-filesystem", "2.9.5-1.fc28", "libreport", "2.9.5-1.fc28", rpm.ParserName}, + {"fedora-gpg-keys", "28-5", "fedora-repos", "28-5", rpm.ParserName}, + {"fedora-release", "28-2", "fedora-release", "28-2", rpm.ParserName}, + {"filesystem", "3.8-2.fc28", "filesystem", "3.8-2.fc28", rpm.ParserName}, + {"tzdata", "2018e-1.fc28", "tzdata", "2018e-1.fc28", rpm.ParserName}, + {"pcre2", "10.31-10.fc28", "pcre2", "10.31-10.fc28", rpm.ParserName}, + {"glibc-minimal-langpack", "2.27-32.fc28", "glibc", "2.27-32.fc28", rpm.ParserName}, + {"glibc-common", "2.27-32.fc28", "glibc", "2.27-32.fc28", rpm.ParserName}, + {"bash", "4.4.23-1.fc28", "bash", "4.4.23-1.fc28", rpm.ParserName}, + {"zlib", "1.2.11-8.fc28", "zlib", "1.2.11-8.fc28", rpm.ParserName}, + {"bzip2-libs", "1.0.6-26.fc28", "bzip2", "1.0.6-26.fc28", rpm.ParserName}, + {"libcap", "2.25-9.fc28", "libcap", "2.25-9.fc28", rpm.ParserName}, + {"libgpg-error", "1.31-1.fc28", "libgpg-error", "1.31-1.fc28", rpm.ParserName}, + {"libzstd", "1.3.5-1.fc28", "zstd", "1.3.5-1.fc28", rpm.ParserName}, + {"expat", "2.2.5-3.fc28", "expat", "2.2.5-3.fc28", rpm.ParserName}, + {"nss-util", "3.38.0-1.0.fc28", "nss-util", "3.38.0-1.0.fc28", rpm.ParserName}, + {"libcom_err", "1.44.2-0.fc28", "e2fsprogs", "1.44.2-0.fc28", rpm.ParserName}, + {"libffi", "3.1-16.fc28", "libffi", "3.1-16.fc28", rpm.ParserName}, + {"libgcrypt", "1.8.3-1.fc28", "libgcrypt", "1.8.3-1.fc28", rpm.ParserName}, + {"libxml2", "2.9.8-4.fc28", "libxml2", "2.9.8-4.fc28", rpm.ParserName}, + {"libacl", "2.2.53-1.fc28", "acl", "2.2.53-1.fc28", rpm.ParserName}, + {"sed", "4.5-1.fc28", "sed", "4.5-1.fc28", rpm.ParserName}, + {"libmount", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28", rpm.ParserName}, + {"p11-kit", "0.23.12-1.fc28", "p11-kit", "0.23.12-1.fc28", rpm.ParserName}, + {"libidn2", "2.0.5-1.fc28", "libidn2", "2.0.5-1.fc28", rpm.ParserName}, + {"libcap-ng", "0.7.9-4.fc28", "libcap-ng", "0.7.9-4.fc28", rpm.ParserName}, + {"lz4-libs", "1.8.1.2-4.fc28", "lz4", "1.8.1.2-4.fc28", rpm.ParserName}, + {"libassuan", "2.5.1-3.fc28", "libassuan", "2.5.1-3.fc28", rpm.ParserName}, + {"keyutils-libs", "1.5.10-6.fc28", "keyutils", "1.5.10-6.fc28", rpm.ParserName}, + {"glib2", "2.56.1-4.fc28", "glib2", "2.56.1-4.fc28", rpm.ParserName}, + {"systemd-libs", "238-9.git0e0aa59.fc28", "systemd", "238-9.git0e0aa59.fc28", rpm.ParserName}, + {"dbus-libs", "1:1.12.10-1.fc28", "dbus", "1.12.10-1.fc28", rpm.ParserName}, + {"libtasn1", "4.13-2.fc28", "libtasn1", "4.13-2.fc28", rpm.ParserName}, + {"ca-certificates", "2018.2.24-1.0.fc28", "ca-certificates", "2018.2.24-1.0.fc28", rpm.ParserName}, + {"libarchive", "3.3.1-4.fc28", "libarchive", "3.3.1-4.fc28", rpm.ParserName}, + {"openssl", "1:1.1.0h-3.fc28", "openssl", "1.1.0h-3.fc28", rpm.ParserName}, + {"libusbx", "1.0.22-1.fc28", "libusbx", "1.0.22-1.fc28", rpm.ParserName}, + {"libsemanage", "2.8-2.fc28", "libsemanage", "2.8-2.fc28", rpm.ParserName}, + {"libutempter", "1.1.6-14.fc28", "libutempter", "1.1.6-14.fc28", rpm.ParserName}, + {"mpfr", "3.1.6-1.fc28", "mpfr", "3.1.6-1.fc28", rpm.ParserName}, + {"gnutls", "3.6.3-4.fc28", "gnutls", "3.6.3-4.fc28", rpm.ParserName}, + {"gzip", "1.9-3.fc28", "gzip", "1.9-3.fc28", rpm.ParserName}, + {"acl", "2.2.53-1.fc28", "acl", "2.2.53-1.fc28", rpm.ParserName}, + {"nss-softokn-freebl", "3.38.0-1.0.fc28", "nss-softokn", "3.38.0-1.0.fc28", rpm.ParserName}, + {"nss", "3.38.0-1.0.fc28", "nss", "3.38.0-1.0.fc28", rpm.ParserName}, + {"libmetalink", "0.1.3-6.fc28", "libmetalink", "0.1.3-6.fc28", rpm.ParserName}, + {"libdb-utils", "5.3.28-30.fc28", "libdb", "5.3.28-30.fc28", rpm.ParserName}, + {"file-libs", "5.33-7.fc28", "file", "5.33-7.fc28", rpm.ParserName}, + {"libsss_idmap", "1.16.3-2.fc28", "sssd", "1.16.3-2.fc28", rpm.ParserName}, + {"libsigsegv", "2.11-5.fc28", "libsigsegv", "2.11-5.fc28", rpm.ParserName}, + {"krb5-libs", "1.16.1-13.fc28", "krb5", "1.16.1-13.fc28", rpm.ParserName}, + {"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "libnsl2", "1.2.0-2.20180605git4a062cf.fc28", rpm.ParserName}, + {"python3-pip", "9.0.3-2.fc28", "python-pip", "9.0.3-2.fc28", rpm.ParserName}, + {"python3", "3.6.6-1.fc28", "python3", "3.6.6-1.fc28", rpm.ParserName}, + {"pam", "1.3.1-1.fc28", "pam", "1.3.1-1.fc28", rpm.ParserName}, + {"python3-gobject-base", "3.28.3-1.fc28", "pygobject3", "3.28.3-1.fc28", rpm.ParserName}, + {"python3-smartcols", "0.3.0-2.fc28", "python-smartcols", "0.3.0-2.fc28", rpm.ParserName}, + {"python3-iniparse", "0.4-30.fc28", "python-iniparse", "0.4-30.fc28", rpm.ParserName}, + {"openldap", "2.4.46-3.fc28", "openldap", "2.4.46-3.fc28", rpm.ParserName}, + {"libseccomp", "2.3.3-2.fc28", "libseccomp", "2.3.3-2.fc28", rpm.ParserName}, + {"npth", "1.5-4.fc28", "npth", "1.5-4.fc28", rpm.ParserName}, + {"gpgme", "1.10.0-4.fc28", "gpgme", "1.10.0-4.fc28", rpm.ParserName}, + {"json-c", "0.13.1-2.fc28", "json-c", "0.13.1-2.fc28", rpm.ParserName}, + {"libyaml", "0.1.7-5.fc28", "libyaml", "0.1.7-5.fc28", rpm.ParserName}, + {"libpkgconf", "1.4.2-1.fc28", "pkgconf", "1.4.2-1.fc28", rpm.ParserName}, + {"pkgconf-pkg-config", "1.4.2-1.fc28", "pkgconf", "1.4.2-1.fc28", rpm.ParserName}, + {"iptables-libs", "1.6.2-3.fc28", "iptables", "1.6.2-3.fc28", rpm.ParserName}, + {"device-mapper-libs", "1.02.146-5.fc28", "lvm2", "2.02.177-5.fc28", rpm.ParserName}, + {"systemd-pam", "238-9.git0e0aa59.fc28", "systemd", "238-9.git0e0aa59.fc28", rpm.ParserName}, + {"systemd", "238-9.git0e0aa59.fc28", "systemd", "238-9.git0e0aa59.fc28", rpm.ParserName}, + {"elfutils-default-yama-scope", "0.173-1.fc28", "elfutils", "0.173-1.fc28", rpm.ParserName}, + {"libcurl", "7.59.0-6.fc28", "curl", "7.59.0-6.fc28", rpm.ParserName}, + {"python3-librepo", "1.8.1-7.fc28", "librepo", "1.8.1-7.fc28", rpm.ParserName}, + {"rpm-plugin-selinux", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28", rpm.ParserName}, + {"rpm", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28", rpm.ParserName}, + {"libdnf", "0.11.1-3.fc28", "libdnf", "0.11.1-3.fc28", rpm.ParserName}, + {"rpm-build-libs", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28", rpm.ParserName}, + {"python3-rpm", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28", rpm.ParserName}, + {"dnf", "2.7.5-12.fc28", "dnf", "2.7.5-12.fc28", rpm.ParserName}, + {"deltarpm", "3.6-25.fc28", "deltarpm", "3.6-25.fc28", rpm.ParserName}, + {"sssd-client", "1.16.3-2.fc28", "sssd", "1.16.3-2.fc28", rpm.ParserName}, + {"cracklib-dicts", "2.9.6-13.fc28", "cracklib", "2.9.6-13.fc28", rpm.ParserName}, + {"tar", "2:1.30-3.fc28", "tar", "1.30-3.fc28", rpm.ParserName}, + {"diffutils", "3.6-4.fc28", "diffutils", "3.6-4.fc28", rpm.ParserName}, + {"langpacks-en", "1.0-12.fc28", "langpacks", "1.0-12.fc28", rpm.ParserName}, + {"libgcc", "8.1.1-5.fc28", "gcc", "8.1.1-5.fc28", rpm.ParserName}, + {"pkgconf-m4", "1.4.2-1.fc28", "pkgconf", "1.4.2-1.fc28", rpm.ParserName}, + {"dnf-conf", "2.7.5-12.fc28", "dnf", "2.7.5-12.fc28", rpm.ParserName}, + {"fedora-repos", "28-5", "fedora-repos", "28-5", rpm.ParserName}, + {"setup", "2.11.4-1.fc28", "setup", "2.11.4-1.fc28", rpm.ParserName}, + {"basesystem", "11-5.fc28", "basesystem", "11-5.fc28", rpm.ParserName}, + {"ncurses-base", "6.1-5.20180224.fc28", "ncurses", "6.1-5.20180224.fc28", rpm.ParserName}, + {"libselinux", "2.8-1.fc28", "libselinux", "2.8-1.fc28", rpm.ParserName}, + {"ncurses-libs", "6.1-5.20180224.fc28", "ncurses", "6.1-5.20180224.fc28", rpm.ParserName}, + {"glibc", "2.27-32.fc28", "glibc", "2.27-32.fc28", rpm.ParserName}, + {"libsepol", "2.8-1.fc28", "libsepol", "2.8-1.fc28", rpm.ParserName}, + {"xz-libs", "5.2.4-2.fc28", "xz", "5.2.4-2.fc28", rpm.ParserName}, + {"info", "6.5-4.fc28", "texinfo", "6.5-4.fc28", rpm.ParserName}, + {"libdb", "5.3.28-30.fc28", "libdb", "5.3.28-30.fc28", rpm.ParserName}, + {"elfutils-libelf", "0.173-1.fc28", "elfutils", "0.173-1.fc28", rpm.ParserName}, + {"popt", "1.16-14.fc28", "popt", "1.16-14.fc28", rpm.ParserName}, + {"nspr", "4.19.0-1.fc28", "nspr", "4.19.0-1.fc28", rpm.ParserName}, + {"libxcrypt", "4.1.2-1.fc28", "libxcrypt", "4.1.2-1.fc28", rpm.ParserName}, + {"lua-libs", "5.3.4-10.fc28", "lua", "5.3.4-10.fc28", rpm.ParserName}, + {"libuuid", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28", rpm.ParserName}, + {"readline", "7.0-11.fc28", "readline", "7.0-11.fc28", rpm.ParserName}, + {"libattr", "2.4.48-3.fc28", "attr", "2.4.48-3.fc28", rpm.ParserName}, + {"coreutils-single", "8.29-7.fc28", "coreutils", "8.29-7.fc28", rpm.ParserName}, + {"libblkid", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28", rpm.ParserName}, + {"gmp", "1:6.1.2-7.fc28", "gmp", "6.1.2-7.fc28", rpm.ParserName}, + {"libunistring", "0.9.10-1.fc28", "libunistring", "0.9.10-1.fc28", rpm.ParserName}, + {"sqlite-libs", "3.22.0-4.fc28", "sqlite", "3.22.0-4.fc28", rpm.ParserName}, + {"audit-libs", "2.8.4-2.fc28", "audit", "2.8.4-2.fc28", rpm.ParserName}, + {"chkconfig", "1.10-4.fc28", "chkconfig", "1.10-4.fc28", rpm.ParserName}, + {"libsmartcols", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28", rpm.ParserName}, + {"pcre", "8.42-3.fc28", "pcre", "8.42-3.fc28", rpm.ParserName}, + {"grep", "3.1-5.fc28", "grep", "3.1-5.fc28", rpm.ParserName}, + {"crypto-policies", "20180425-5.git6ad4018.fc28", "crypto-policies", "20180425-5.git6ad4018.fc28", rpm.ParserName}, + {"gdbm-libs", "1:1.14.1-4.fc28", "gdbm", "1.14.1-4.fc28", rpm.ParserName}, + {"p11-kit-trust", "0.23.12-1.fc28", "p11-kit", "0.23.12-1.fc28", rpm.ParserName}, + {"openssl-libs", "1:1.1.0h-3.fc28", "openssl", "1.1.0h-3.fc28", rpm.ParserName}, + {"ima-evm-utils", "1.1-2.fc28", "ima-evm-utils", "1.1-2.fc28", rpm.ParserName}, + {"gdbm", "1:1.14.1-4.fc28", "gdbm", "1.14.1-4.fc28", rpm.ParserName}, + {"gobject-introspection", "1.56.1-1.fc28", "gobject-introspection", "1.56.1-1.fc28", rpm.ParserName}, + {"shadow-utils", "2:4.6-1.fc28", "shadow-utils", "4.6-1.fc28", rpm.ParserName}, + {"libpsl", "0.20.2-2.fc28", "libpsl", "0.20.2-2.fc28", rpm.ParserName}, + {"nettle", "3.4-2.fc28", "nettle", "3.4-2.fc28", rpm.ParserName}, + {"libfdisk", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28", rpm.ParserName}, + {"cracklib", "2.9.6-13.fc28", "cracklib", "2.9.6-13.fc28", rpm.ParserName}, + {"libcomps", "0.1.8-11.fc28", "libcomps", "0.1.8-11.fc28", rpm.ParserName}, + {"nss-softokn", "3.38.0-1.0.fc28", "nss-softokn", "3.38.0-1.0.fc28", rpm.ParserName}, + {"nss-sysinit", "3.38.0-1.0.fc28", "nss", "3.38.0-1.0.fc28", rpm.ParserName}, + {"libksba", "1.3.5-7.fc28", "libksba", "1.3.5-7.fc28", rpm.ParserName}, + {"kmod-libs", "25-2.fc28", "kmod", "25-2.fc28", rpm.ParserName}, + {"libsss_nss_idmap", "1.16.3-2.fc28", "sssd", "1.16.3-2.fc28", rpm.ParserName}, + {"libverto", "0.3.0-5.fc28", "libverto", "0.3.0-5.fc28", rpm.ParserName}, + {"gawk", "4.2.1-1.fc28", "gawk", "4.2.1-1.fc28", rpm.ParserName}, + {"libtirpc", "1.0.3-3.rc2.fc28", "libtirpc", "1.0.3-3.rc2.fc28", rpm.ParserName}, + {"python3-libs", "3.6.6-1.fc28", "python3", "3.6.6-1.fc28", rpm.ParserName}, + {"python3-setuptools", "39.2.0-6.fc28", "python-setuptools", "39.2.0-6.fc28", rpm.ParserName}, + {"libpwquality", "1.4.0-7.fc28", "libpwquality", "1.4.0-7.fc28", rpm.ParserName}, + {"util-linux", "2.32.1-1.fc28", "util-linux", "2.32.1-1.fc28", rpm.ParserName}, + {"python3-libcomps", "0.1.8-11.fc28", "libcomps", "0.1.8-11.fc28", rpm.ParserName}, + {"python3-six", "1.11.0-3.fc28", "python-six", "1.11.0-3.fc28", rpm.ParserName}, + {"cyrus-sasl-lib", "2.1.27-0.2rc7.fc28", "cyrus-sasl", "2.1.27-0.2rc7.fc28", rpm.ParserName}, + {"libssh", "0.8.2-1.fc28", "libssh", "0.8.2-1.fc28", rpm.ParserName}, + {"qrencode-libs", "3.4.4-5.fc28", "qrencode", "3.4.4-5.fc28", rpm.ParserName}, + {"gnupg2", "2.2.8-1.fc28", "gnupg2", "2.2.8-1.fc28", rpm.ParserName}, + {"python3-gpg", "1.10.0-4.fc28", "gpgme", "1.10.0-4.fc28", rpm.ParserName}, + {"libargon2", "20161029-5.fc28", "argon2", "20161029-5.fc28", rpm.ParserName}, + {"libmodulemd", "1.6.2-2.fc28", "libmodulemd", "1.6.2-2.fc28", rpm.ParserName}, + {"pkgconf", "1.4.2-1.fc28", "pkgconf", "1.4.2-1.fc28", rpm.ParserName}, + {"libpcap", "14:1.9.0-1.fc28", "libpcap", "1.9.0-1.fc28", rpm.ParserName}, + {"device-mapper", "1.02.146-5.fc28", "lvm2", "2.02.177-5.fc28", rpm.ParserName}, + {"cryptsetup-libs", "2.0.4-1.fc28", "cryptsetup", "2.0.4-1.fc28", rpm.ParserName}, + {"elfutils-libs", "0.173-1.fc28", "elfutils", "0.173-1.fc28", rpm.ParserName}, + {"dbus", "1:1.12.10-1.fc28", "dbus", "1.12.10-1.fc28", rpm.ParserName}, + {"libnghttp2", "1.32.1-1.fc28", "nghttp2", "1.32.1-1.fc28", rpm.ParserName}, + {"librepo", "1.8.1-7.fc28", "librepo", "1.8.1-7.fc28", rpm.ParserName}, + {"curl", "7.59.0-6.fc28", "curl", "7.59.0-6.fc28", rpm.ParserName}, + {"rpm-libs", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28", rpm.ParserName}, + {"libsolv", "0.6.35-1.fc28", "libsolv", "0.6.35-1.fc28", rpm.ParserName}, + {"python3-hawkey", "0.11.1-3.fc28", "libdnf", "0.11.1-3.fc28", rpm.ParserName}, + {"rpm-sign-libs", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28", rpm.ParserName}, + {"python3-dnf", "2.7.5-12.fc28", "dnf", "2.7.5-12.fc28", rpm.ParserName}, + {"dnf-yum", "2.7.5-12.fc28", "dnf", "2.7.5-12.fc28", rpm.ParserName}, + {"rpm-plugin-systemd-inhibit", "4.14.1-9.fc28", "rpm", "4.14.1-9.fc28", rpm.ParserName}, + {"nss-tools", "3.38.0-1.0.fc28", "nss", "3.38.0-1.0.fc28", rpm.ParserName}, + {"openssl-pkcs11", "0.4.8-1.fc28", "openssl-pkcs11", "0.4.8-1.fc28", rpm.ParserName}, + {"vim-minimal", "2:8.1.328-1.fc28", "vim", "8.1.328-1.fc28", rpm.ParserName}, + {"glibc-langpack-en", "2.27-32.fc28", "glibc", "2.27-32.fc28", rpm.ParserName}, + {"rootfiles", "8.1-22.fc28", "rootfiles", "8.1-22.fc28", rpm.ParserName}, } func TestRpmFeatureDetection(t *testing.T) { @@ -204,9 +205,9 @@ func TestRpmFeatureDetection(t *testing.T) { { "valid small case", map[string]string{"var/lib/rpm/Packages": "rpm/testdata/valid"}, - []featurefmt.PackageInfo{ - {"centos-release", "7-1.1503.el7.centos.2.8", "", ""}, - {"filesystem", "3.2-18.el7", "", ""}, + []database.Feature{ + {"centos-release", "7-1.1503.el7.centos.2.8", "centos-release", "7-1.1503.el7.centos.2.8", rpm.ParserName}, + {"filesystem", "3.2-18.el7", "filesystem", "3.2-18.el7", rpm.ParserName}, }, }, { @@ -247,7 +248,7 @@ func TestParseSourceRPM(t *testing.T) { // actual expected: name="lua", version="5.3.4", release="10.fc-28" {"lua-5.3.4-10.fc-28.src.rpm", "lua-5.3.4", "10.fc-28", ""}, } { - pkg := featurefmt.PackageInfo{} + pkg := database.Feature{} err := parseSourceRPM(test.sourceRPM, &pkg) if test.expectedErr != "" { require.EqualError(t, err, test.expectedErr) diff --git a/ext/featurefmt/testutil.go b/ext/featurefmt/testutil.go index f9225c98..d9cebb64 100644 --- a/ext/featurefmt/testutil.go +++ b/ext/featurefmt/testutil.go @@ -54,7 +54,7 @@ func loadTestFiles(testFilePaths map[string]string) tarutil.FilesMap { type TestCase struct { Name string FilePaths map[string]string - ExpectedResult []PackageInfo + ExpectedResult []database.Feature } // RunTest runs a featurefmt test by loading the package info database files and @@ -65,7 +65,7 @@ func RunTest(t *testing.T, test TestCase, lister Lister, expectedVersionFormat s expected := test.ExpectedResult features, err := lister.ListFeatures(filesMap) require.Nil(t, err) - visited := map[PackageInfo]bool{} + visited := map[database.Feature]bool{} // we only enforce the unique packages to match, the result features // should be always deduplicated. for _, pkg := range expected { @@ -75,22 +75,16 @@ func RunTest(t *testing.T, test TestCase, lister Lister, expectedVersionFormat s assert.Len(t, features, len(visited)) for _, f := range features { assert.Equal(t, expectedVersionFormat, f.VersionFormat) - if f.Parent != nil { - // currently we don't have more than 2 levels deep features. - assert.Equal(t, expectedVersionFormat, f.Parent.VersionFormat) - } - - pkg := convertToPackageInfo(&f) - if ok, found := visited[pkg]; ok { - assert.Fail(t, "duplicated features is not allowed", "feature=%#v", f, pkg) + if ok, found := visited[f]; ok { + assert.Fail(t, "duplicated features is not allowed", "feature=%#v", f) } else if !found { - assert.Fail(t, "unexpected feature", "feature = %#v", pkg) + assert.Fail(t, "unexpected feature", "feature = %#v", f) } - visited[pkg] = true + visited[f] = true } - missingPackages := []PackageInfo{} + missingPackages := []database.Feature{} for pkg, ok := range visited { if !ok { missingPackages = append(missingPackages, pkg) @@ -100,19 +94,3 @@ func RunTest(t *testing.T, test TestCase, lister Lister, expectedVersionFormat s assert.Len(t, missingPackages, 0, "missing packages") }) } - -func convertToPackageInfo(feature *database.Feature) PackageInfo { - pkg := PackageInfo{ - PackageName: feature.Name, - PackageVersion: feature.Version, - } - - // Since in the actual package manager metadata file, there's no explicit - // tree structure, the features are converted to compare the metadata only. - if feature.Parent != nil { - pkg.SourceName = feature.Parent.Name - pkg.SourceVersion = feature.Parent.Version - } - - return pkg -}