mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
Merge pull request #91 from anchore/issue-75
Recurse when creating a directory catalog
This commit is contained in:
commit
380cd39514
1
go.mod
1
go.mod
@ -6,6 +6,7 @@ require (
|
|||||||
github.com/adrg/xdg v0.2.1
|
github.com/adrg/xdg v0.2.1
|
||||||
github.com/anchore/go-testutils v0.0.0-20200624184116-66aa578126db
|
github.com/anchore/go-testutils v0.0.0-20200624184116-66aa578126db
|
||||||
github.com/anchore/stereoscope v0.0.0-20200706164556-7cf39d7f4639
|
github.com/anchore/stereoscope v0.0.0-20200706164556-7cf39d7f4639
|
||||||
|
github.com/bmatcuk/doublestar v1.3.1
|
||||||
github.com/go-test/deep v1.0.6
|
github.com/go-test/deep v1.0.6
|
||||||
github.com/google/go-containerregistry v0.1.1 // indirect
|
github.com/google/go-containerregistry v0.1.1 // indirect
|
||||||
github.com/gookit/color v1.2.5
|
github.com/gookit/color v1.2.5
|
||||||
|
|||||||
2
go.sum
2
go.sum
@ -161,6 +161,8 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm
|
|||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
|
||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
|
github.com/bmatcuk/doublestar v1.3.1 h1:rT8rxDPsavp9G+4ZULzqhhUSaI/OPsTZNG88Z3i0xvY=
|
||||||
|
github.com/bmatcuk/doublestar v1.3.1/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
|
||||||
github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTKY95VwV8U=
|
github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTKY95VwV8U=
|
||||||
github.com/bombsimon/wsl/v2 v2.2.0/go.mod h1:Azh8c3XGEJl9LyX0/sFC+CKMc7Ssgua0g+6abzXN4Pg=
|
github.com/bombsimon/wsl/v2 v2.2.0/go.mod h1:Azh8c3XGEJl9LyX0/sFC+CKMc7Ssgua0g+6abzXN4Pg=
|
||||||
github.com/bombsimon/wsl/v3 v3.0.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
|
github.com/bombsimon/wsl/v3 v3.0.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
|
||||||
|
|||||||
@ -13,7 +13,7 @@ type Cataloger struct {
|
|||||||
|
|
||||||
func NewCataloger() *Cataloger {
|
func NewCataloger() *Cataloger {
|
||||||
globParsers := map[string]common.ParserFn{
|
globParsers := map[string]common.ParserFn{
|
||||||
"*/Gemfile.lock": parseGemfileLockEntries,
|
"**/Gemfile.lock": parseGemfileLockEntries,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Cataloger{
|
return &Cataloger{
|
||||||
|
|||||||
@ -12,12 +12,12 @@ type Cataloger struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewCataloger() *Cataloger {
|
func NewCataloger() *Cataloger {
|
||||||
pathParsers := map[string]common.ParserFn{
|
globParsers := map[string]common.ParserFn{
|
||||||
"/var/lib/dpkg/status": parseDpkgStatus,
|
"**/var/lib/dpkg/status": parseDpkgStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Cataloger{
|
return &Cataloger{
|
||||||
cataloger: common.NewGenericCataloger(pathParsers, nil),
|
cataloger: common.NewGenericCataloger(nil, globParsers),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,11 +11,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var archiveFormatGlobs = []string{
|
var archiveFormatGlobs = []string{
|
||||||
"*.jar",
|
"**/*.jar",
|
||||||
"*.war",
|
"**/*.war",
|
||||||
"*.ear",
|
"**/*.ear",
|
||||||
"*.jpi",
|
"**/*.jpi",
|
||||||
"*.hpi",
|
"**/*.hpi",
|
||||||
}
|
}
|
||||||
|
|
||||||
type archiveParser struct {
|
type archiveParser struct {
|
||||||
|
|||||||
@ -13,8 +13,8 @@ type Cataloger struct {
|
|||||||
|
|
||||||
func NewCataloger() *Cataloger {
|
func NewCataloger() *Cataloger {
|
||||||
globParsers := map[string]common.ParserFn{
|
globParsers := map[string]common.ParserFn{
|
||||||
"*egg-info/PKG-INFO": parseEggMetadata,
|
"**/egg-info/PKG-INFO": parseEggMetadata,
|
||||||
"*dist-info/METADATA": parseWheelMetadata,
|
"**/dist-info/METADATA": parseWheelMetadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Cataloger{
|
return &Cataloger{
|
||||||
|
|||||||
@ -12,12 +12,12 @@ type Cataloger struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewCataloger() *Cataloger {
|
func NewCataloger() *Cataloger {
|
||||||
pathParsers := map[string]common.ParserFn{
|
globParsers := map[string]common.ParserFn{
|
||||||
"/var/lib/rpm/Packages": parseRpmDB,
|
"**/var/lib/rpm/Packages": parseRpmDB,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Cataloger{
|
return &Cataloger{
|
||||||
cataloger: common.NewGenericCataloger(pathParsers, nil),
|
cataloger: common.NewGenericCataloger(nil, globParsers),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,10 +5,10 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/anchore/imgbom/internal/log"
|
"github.com/anchore/imgbom/internal/log"
|
||||||
"github.com/anchore/stereoscope/pkg/file"
|
"github.com/anchore/stereoscope/pkg/file"
|
||||||
|
"github.com/bmatcuk/doublestar"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DirectoryResolver struct {
|
type DirectoryResolver struct {
|
||||||
@ -51,7 +51,7 @@ func (s DirectoryResolver) FilesByGlob(patterns ...string) ([]file.Reference, er
|
|||||||
|
|
||||||
for _, pattern := range patterns {
|
for _, pattern := range patterns {
|
||||||
pathPattern := path.Join(s.Path, pattern)
|
pathPattern := path.Join(s.Path, pattern)
|
||||||
matches, err := filepath.Glob(pathPattern)
|
matches, err := doublestar.Glob(pathPattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -138,6 +138,7 @@ func TestDirectoryResolver_FilesByGlobMultiple(t *testing.T) {
|
|||||||
t.Run("finds multiple matching files", func(t *testing.T) {
|
t.Run("finds multiple matching files", func(t *testing.T) {
|
||||||
resolver := DirectoryResolver{"test-fixtures"}
|
resolver := DirectoryResolver{"test-fixtures"}
|
||||||
refs, err := resolver.FilesByGlob("image-symlinks/file*")
|
refs, err := resolver.FilesByGlob("image-symlinks/file*")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("could not use resolver: %+v, %+v", err, refs)
|
t.Fatalf("could not use resolver: %+v, %+v", err, refs)
|
||||||
}
|
}
|
||||||
@ -149,6 +150,22 @@ func TestDirectoryResolver_FilesByGlobMultiple(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDirectoryResolver_FilesByGlobRecursive(t *testing.T) {
|
||||||
|
t.Run("finds multiple matching files", func(t *testing.T) {
|
||||||
|
resolver := DirectoryResolver{"test-fixtures"}
|
||||||
|
refs, err := resolver.FilesByGlob("**/*.txt")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("could not use resolver: %+v, %+v", err, refs)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(refs) != 4 {
|
||||||
|
t.Errorf("unexpected number of refs: %d != 4", len(refs))
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestDirectoryResolver_FilesByGlobSingle(t *testing.T) {
|
func TestDirectoryResolver_FilesByGlobSingle(t *testing.T) {
|
||||||
t.Run("finds multiple matching files", func(t *testing.T) {
|
t.Run("finds multiple matching files", func(t *testing.T) {
|
||||||
resolver := DirectoryResolver{"test-fixtures"}
|
resolver := DirectoryResolver{"test-fixtures"}
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
file 3
|
||||||
@ -1,71 +0,0 @@
|
|||||||
// +build integration
|
|
||||||
|
|
||||||
package integration
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
)
|
|
||||||
|
|
||||||
var update = flag.Bool("update", false, "update the *.golden files for json presenters")
|
|
||||||
|
|
||||||
// these tests are providing inconsistent results... we can fix in another PR
|
|
||||||
|
|
||||||
//func TestDirTextPresenter(t *testing.T) {
|
|
||||||
// var buffer bytes.Buffer
|
|
||||||
// protocol := imgbom.NewProtocol("dir://test-fixtures")
|
|
||||||
// if protocol.Type != imgbom.DirProtocol {
|
|
||||||
// t.Errorf("unexpected protocol returned: %v != %v", protocol.Type, imgbom.DirProtocol)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// catalog, err := imgbom.CatalogDir(protocol.Value, scope.AllLayersScope)
|
|
||||||
// if err != nil {
|
|
||||||
// t.Errorf("could not produce catalog: %w", err)
|
|
||||||
// }
|
|
||||||
// presenterOpt := presenter.ParseOption("text")
|
|
||||||
// dirPresenter := presenter.GetDirPresenter(presenterOpt, protocol.Value, catalog)
|
|
||||||
//
|
|
||||||
// dirPresenter.Present(&buffer)
|
|
||||||
// actual := buffer.Bytes()
|
|
||||||
// if *update {
|
|
||||||
// testutils.UpdateGoldenFileContents(t, actual)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var expected = testutils.GetGoldenFileContents(t)
|
|
||||||
//
|
|
||||||
// if !bytes.Equal(expected, actual) {
|
|
||||||
// dmp := diffmatchpatch.New()
|
|
||||||
// diffs := dmp.DiffMain(string(actual), string(expected), true)
|
|
||||||
// t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func TestDirJsonPresenter(t *testing.T) {
|
|
||||||
// var buffer bytes.Buffer
|
|
||||||
// protocol := imgbom.NewProtocol("dir://test-fixtures")
|
|
||||||
// if protocol.Type != imgbom.DirProtocol {
|
|
||||||
// t.Errorf("unexpected protocol returned: %v != %v", protocol.Type, imgbom.DirProtocol)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// catalog, err := imgbom.CatalogDir(protocol.Value, scope.AllLayersScope)
|
|
||||||
// if err != nil {
|
|
||||||
// t.Errorf("could not produce catalog: %w", err)
|
|
||||||
// }
|
|
||||||
// presenterOpt := presenter.ParseOption("json")
|
|
||||||
// dirPresenter := presenter.GetDirPresenter(presenterOpt, protocol.Value, catalog)
|
|
||||||
//
|
|
||||||
// dirPresenter.Present(&buffer)
|
|
||||||
// actual := buffer.Bytes()
|
|
||||||
// if *update {
|
|
||||||
// testutils.UpdateGoldenFileContents(t, actual)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var expected = testutils.GetGoldenFileContents(t)
|
|
||||||
//
|
|
||||||
// if !bytes.Equal(expected, actual) {
|
|
||||||
// dmp := diffmatchpatch.New()
|
|
||||||
// diffs := dmp.DiffMain(string(actual), string(expected), true)
|
|
||||||
// t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
@ -1,204 +0,0 @@
|
|||||||
// +build integration
|
|
||||||
|
|
||||||
package integration
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/anchore/imgbom/imgbom"
|
|
||||||
|
|
||||||
"github.com/anchore/imgbom/internal"
|
|
||||||
|
|
||||||
"github.com/anchore/go-testutils"
|
|
||||||
"github.com/anchore/imgbom/imgbom/pkg"
|
|
||||||
"github.com/anchore/imgbom/imgbom/scope"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPkgCoverageImage(t *testing.T) {
|
|
||||||
fixtureImageName := "image-pkg-coverage"
|
|
||||||
_, cleanup := testutils.GetFixtureImage(t, "docker-archive", fixtureImageName)
|
|
||||||
tarPath := testutils.GetFixtureImageTarPath(t, fixtureImageName)
|
|
||||||
defer cleanup()
|
|
||||||
|
|
||||||
catalog, _, _, err := imgbom.Catalog("docker-archive://"+tarPath, scope.AllLayersScope)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to catalog image: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cases := []struct {
|
|
||||||
name string
|
|
||||||
pkgType pkg.Type
|
|
||||||
pkgLanguage pkg.Language
|
|
||||||
pkgInfo map[string]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "find rpmdb packages",
|
|
||||||
pkgType: pkg.RpmPkg,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"dive": "0.9.2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find dpkg packages",
|
|
||||||
pkgType: pkg.DebPkg,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"apt": "1.8.2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find java packages",
|
|
||||||
pkgType: pkg.JavaPkg,
|
|
||||||
pkgLanguage: pkg.Java,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"example-java-app-maven": "0.1.0",
|
|
||||||
"example-jenkins-plugin": "1.0-SNAPSHOT", // the jeninks HPI file has a nested JAR of the same name
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find jenkins plugins",
|
|
||||||
pkgType: pkg.JenkinsPluginPkg,
|
|
||||||
pkgLanguage: pkg.Java,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"example-jenkins-plugin": "1.0-SNAPSHOT",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find python wheel packages",
|
|
||||||
pkgType: pkg.WheelPkg,
|
|
||||||
pkgLanguage: pkg.Python,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"Pygments": "2.6.1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find python egg packages",
|
|
||||||
pkgType: pkg.EggPkg,
|
|
||||||
pkgLanguage: pkg.Python,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"requests": "2.22.0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "find bundler packages",
|
|
||||||
pkgType: pkg.BundlerPkg,
|
|
||||||
pkgLanguage: pkg.Ruby,
|
|
||||||
pkgInfo: map[string]string{
|
|
||||||
"actionmailer": "4.1.1",
|
|
||||||
"actionpack": "4.1.1",
|
|
||||||
"actionview": "4.1.1",
|
|
||||||
"activemodel": "4.1.1",
|
|
||||||
"activerecord": "4.1.1",
|
|
||||||
"activesupport": "4.1.1",
|
|
||||||
"arel": "5.0.1.20140414130214",
|
|
||||||
"bootstrap-sass": "3.1.1.1",
|
|
||||||
"builder": "3.2.2",
|
|
||||||
"coffee-rails": "4.0.1",
|
|
||||||
"coffee-script": "2.2.0",
|
|
||||||
"coffee-script-source": "1.7.0",
|
|
||||||
"erubis": "2.7.0",
|
|
||||||
"execjs": "2.0.2",
|
|
||||||
"hike": "1.2.3",
|
|
||||||
"i18n": "0.6.9",
|
|
||||||
"jbuilder": "2.0.7",
|
|
||||||
"jquery-rails": "3.1.0",
|
|
||||||
"json": "1.8.1",
|
|
||||||
"kgio": "2.9.2",
|
|
||||||
"libv8": "3.16.14.3",
|
|
||||||
"mail": "2.5.4",
|
|
||||||
"mime-types": "1.25.1",
|
|
||||||
"minitest": "5.3.4",
|
|
||||||
"multi_json": "1.10.1",
|
|
||||||
"mysql2": "0.3.16",
|
|
||||||
"polyglot": "0.3.4",
|
|
||||||
"rack": "1.5.2",
|
|
||||||
"rack-test": "0.6.2",
|
|
||||||
"rails": "4.1.1",
|
|
||||||
"railties": "4.1.1",
|
|
||||||
"raindrops": "0.13.0",
|
|
||||||
"rake": "10.3.2",
|
|
||||||
"rdoc": "4.1.1",
|
|
||||||
"ref": "1.0.5",
|
|
||||||
"sass": "3.2.19",
|
|
||||||
"sass-rails": "4.0.3",
|
|
||||||
"sdoc": "0.4.0",
|
|
||||||
"spring": "1.1.3",
|
|
||||||
"sprockets": "2.11.0",
|
|
||||||
"sprockets-rails": "2.1.3",
|
|
||||||
"sqlite3": "1.3.9",
|
|
||||||
"therubyracer": "0.12.1",
|
|
||||||
"thor": "0.19.1",
|
|
||||||
"thread_safe": "0.3.3",
|
|
||||||
"tilt": "1.4.1",
|
|
||||||
"treetop": "1.4.15",
|
|
||||||
"turbolinks": "2.2.2",
|
|
||||||
"tzinfo": "1.2.0",
|
|
||||||
"uglifier": "2.5.0",
|
|
||||||
"unicorn": "4.8.3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
observedLanguages := internal.NewStringSet()
|
|
||||||
definedLanguages := internal.NewStringSet()
|
|
||||||
for _, l := range pkg.AllLanguages {
|
|
||||||
definedLanguages.Add(l.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
observedPkgs := internal.NewStringSet()
|
|
||||||
definedPkgs := internal.NewStringSet()
|
|
||||||
for _, p := range pkg.AllPkgs {
|
|
||||||
definedPkgs.Add(p.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range cases {
|
|
||||||
t.Run(c.name, func(t *testing.T) {
|
|
||||||
pkgCount := 0
|
|
||||||
|
|
||||||
for a := range catalog.Enumerate(c.pkgType) {
|
|
||||||
|
|
||||||
observedLanguages.Add(a.Language.String())
|
|
||||||
observedPkgs.Add(a.Type.String())
|
|
||||||
|
|
||||||
expectedVersion, ok := c.pkgInfo[a.Name]
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("unexpected package found: %s", a.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
if expectedVersion != a.Version {
|
|
||||||
t.Errorf("unexpected package version (pkg=%s): %s", a.Name, a.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Language != c.pkgLanguage {
|
|
||||||
t.Errorf("bad language (pkg=%+v): %+v", a.Name, a.Language)
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Type != c.pkgType {
|
|
||||||
t.Errorf("bad package type (pkg=%+v): %+v", a.Name, a.Type)
|
|
||||||
}
|
|
||||||
pkgCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
if pkgCount != len(c.pkgInfo) {
|
|
||||||
for a := range catalog.Enumerate(c.pkgType) {
|
|
||||||
t.Log(" ", a)
|
|
||||||
}
|
|
||||||
t.Fatalf("unexpected package count: %d!=%d", pkgCount, len(c.pkgInfo))
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
observedLanguages.Remove(pkg.UnknownLanguage.String())
|
|
||||||
definedLanguages.Remove(pkg.UnknownLanguage.String())
|
|
||||||
observedPkgs.Remove(pkg.UnknownPkg.String())
|
|
||||||
definedPkgs.Remove(pkg.UnknownPkg.String())
|
|
||||||
|
|
||||||
// ensure that integration test cases stay in sync with the available catalogers
|
|
||||||
if len(observedLanguages) < len(definedLanguages) {
|
|
||||||
t.Errorf("language coverage incomplete (languages=%d, coverage=%d)", len(definedLanguages), len(observedLanguages))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(observedPkgs) < len(definedPkgs) {
|
|
||||||
t.Errorf("package coverage incomplete (packages=%d, coverage=%d)", len(definedPkgs), len(observedPkgs))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
276
integration/fixture_pkg_coverage_test.go
Normal file
276
integration/fixture_pkg_coverage_test.go
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
// +build integration
|
||||||
|
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/anchore/imgbom/imgbom"
|
||||||
|
|
||||||
|
"github.com/anchore/imgbom/internal"
|
||||||
|
|
||||||
|
"github.com/anchore/go-testutils"
|
||||||
|
"github.com/anchore/imgbom/imgbom/pkg"
|
||||||
|
"github.com/anchore/imgbom/imgbom/scope"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cases = []struct {
|
||||||
|
name string
|
||||||
|
pkgType pkg.Type
|
||||||
|
pkgLanguage pkg.Language
|
||||||
|
pkgInfo map[string]string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "find rpmdb packages",
|
||||||
|
pkgType: pkg.RpmPkg,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"dive": "0.9.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find dpkg packages",
|
||||||
|
pkgType: pkg.DebPkg,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"apt": "1.8.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find java packages",
|
||||||
|
pkgType: pkg.JavaPkg,
|
||||||
|
pkgLanguage: pkg.Java,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"example-java-app-maven": "0.1.0",
|
||||||
|
"example-jenkins-plugin": "1.0-SNAPSHOT", // the jenkins HPI file has a nested JAR of the same name
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find jenkins plugins",
|
||||||
|
pkgType: pkg.JenkinsPluginPkg,
|
||||||
|
pkgLanguage: pkg.Java,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"example-jenkins-plugin": "1.0-SNAPSHOT",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find python wheel packages",
|
||||||
|
pkgType: pkg.WheelPkg,
|
||||||
|
pkgLanguage: pkg.Python,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"Pygments": "2.6.1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find python egg packages",
|
||||||
|
pkgType: pkg.EggPkg,
|
||||||
|
pkgLanguage: pkg.Python,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"requests": "2.22.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "find bundler packages",
|
||||||
|
pkgType: pkg.BundlerPkg,
|
||||||
|
pkgLanguage: pkg.Ruby,
|
||||||
|
pkgInfo: map[string]string{
|
||||||
|
"actionmailer": "4.1.1",
|
||||||
|
"actionpack": "4.1.1",
|
||||||
|
"actionview": "4.1.1",
|
||||||
|
"activemodel": "4.1.1",
|
||||||
|
"activerecord": "4.1.1",
|
||||||
|
"activesupport": "4.1.1",
|
||||||
|
"arel": "5.0.1.20140414130214",
|
||||||
|
"bootstrap-sass": "3.1.1.1",
|
||||||
|
"builder": "3.2.2",
|
||||||
|
"coffee-rails": "4.0.1",
|
||||||
|
"coffee-script": "2.2.0",
|
||||||
|
"coffee-script-source": "1.7.0",
|
||||||
|
"erubis": "2.7.0",
|
||||||
|
"execjs": "2.0.2",
|
||||||
|
"hike": "1.2.3",
|
||||||
|
"i18n": "0.6.9",
|
||||||
|
"jbuilder": "2.0.7",
|
||||||
|
"jquery-rails": "3.1.0",
|
||||||
|
"json": "1.8.1",
|
||||||
|
"kgio": "2.9.2",
|
||||||
|
"libv8": "3.16.14.3",
|
||||||
|
"mail": "2.5.4",
|
||||||
|
"mime-types": "1.25.1",
|
||||||
|
"minitest": "5.3.4",
|
||||||
|
"multi_json": "1.10.1",
|
||||||
|
"mysql2": "0.3.16",
|
||||||
|
"polyglot": "0.3.4",
|
||||||
|
"rack": "1.5.2",
|
||||||
|
"rack-test": "0.6.2",
|
||||||
|
"rails": "4.1.1",
|
||||||
|
"railties": "4.1.1",
|
||||||
|
"raindrops": "0.13.0",
|
||||||
|
"rake": "10.3.2",
|
||||||
|
"rdoc": "4.1.1",
|
||||||
|
"ref": "1.0.5",
|
||||||
|
"sass": "3.2.19",
|
||||||
|
"sass-rails": "4.0.3",
|
||||||
|
"sdoc": "0.4.0",
|
||||||
|
"spring": "1.1.3",
|
||||||
|
"sprockets": "2.11.0",
|
||||||
|
"sprockets-rails": "2.1.3",
|
||||||
|
"sqlite3": "1.3.9",
|
||||||
|
"therubyracer": "0.12.1",
|
||||||
|
"thor": "0.19.1",
|
||||||
|
"thread_safe": "0.3.3",
|
||||||
|
"tilt": "1.4.1",
|
||||||
|
"treetop": "1.4.15",
|
||||||
|
"turbolinks": "2.2.2",
|
||||||
|
"tzinfo": "1.2.0",
|
||||||
|
"uglifier": "2.5.0",
|
||||||
|
"unicorn": "4.8.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPkgCoverageImage(t *testing.T) {
|
||||||
|
fixtureImageName := "image-pkg-coverage"
|
||||||
|
_, cleanup := testutils.GetFixtureImage(t, "docker-archive", fixtureImageName)
|
||||||
|
tarPath := testutils.GetFixtureImageTarPath(t, fixtureImageName)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
catalog, _, _, err := imgbom.Catalog("docker-archive://"+tarPath, scope.AllLayersScope)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to catalog image: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
observedLanguages := internal.NewStringSet()
|
||||||
|
definedLanguages := internal.NewStringSet()
|
||||||
|
for _, l := range pkg.AllLanguages {
|
||||||
|
definedLanguages.Add(l.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
observedPkgs := internal.NewStringSet()
|
||||||
|
definedPkgs := internal.NewStringSet()
|
||||||
|
for _, p := range pkg.AllPkgs {
|
||||||
|
definedPkgs.Add(p.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
pkgCount := 0
|
||||||
|
|
||||||
|
for a := range catalog.Enumerate(c.pkgType) {
|
||||||
|
|
||||||
|
observedLanguages.Add(a.Language.String())
|
||||||
|
observedPkgs.Add(a.Type.String())
|
||||||
|
|
||||||
|
expectedVersion, ok := c.pkgInfo[a.Name]
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("unexpected package found: %s", a.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expectedVersion != a.Version {
|
||||||
|
t.Errorf("unexpected package version (pkg=%s): %s", a.Name, a.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.Language != c.pkgLanguage {
|
||||||
|
t.Errorf("bad language (pkg=%+v): %+v", a.Name, a.Language)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.Type != c.pkgType {
|
||||||
|
t.Errorf("bad package type (pkg=%+v): %+v", a.Name, a.Type)
|
||||||
|
}
|
||||||
|
pkgCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
if pkgCount != len(c.pkgInfo) {
|
||||||
|
for a := range catalog.Enumerate(c.pkgType) {
|
||||||
|
t.Log(" ", a)
|
||||||
|
}
|
||||||
|
t.Fatalf("unexpected package count: %d!=%d", pkgCount, len(c.pkgInfo))
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
observedLanguages.Remove(pkg.UnknownLanguage.String())
|
||||||
|
definedLanguages.Remove(pkg.UnknownLanguage.String())
|
||||||
|
observedPkgs.Remove(pkg.UnknownPkg.String())
|
||||||
|
definedPkgs.Remove(pkg.UnknownPkg.String())
|
||||||
|
|
||||||
|
// ensure that integration test cases stay in sync with the available catalogers
|
||||||
|
if len(observedLanguages) < len(definedLanguages) {
|
||||||
|
t.Errorf("language coverage incomplete (languages=%d, coverage=%d)", len(definedLanguages), len(observedLanguages))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(observedPkgs) < len(definedPkgs) {
|
||||||
|
t.Errorf("package coverage incomplete (packages=%d, coverage=%d)", len(definedPkgs), len(observedPkgs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPkgCoverageDirectory(t *testing.T) {
|
||||||
|
catalog, _, _, err := imgbom.Catalog("dir://test-fixtures/image-pkg-coverage", scope.AllLayersScope)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to create scope from dir: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
observedLanguages := internal.NewStringSet()
|
||||||
|
definedLanguages := internal.NewStringSet()
|
||||||
|
for _, l := range pkg.AllLanguages {
|
||||||
|
definedLanguages.Add(l.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
observedPkgs := internal.NewStringSet()
|
||||||
|
definedPkgs := internal.NewStringSet()
|
||||||
|
for _, p := range pkg.AllPkgs {
|
||||||
|
definedPkgs.Add(p.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
pkgCount := 0
|
||||||
|
|
||||||
|
for a := range catalog.Enumerate(c.pkgType) {
|
||||||
|
|
||||||
|
observedLanguages.Add(a.Language.String())
|
||||||
|
observedPkgs.Add(a.Type.String())
|
||||||
|
|
||||||
|
expectedVersion, ok := c.pkgInfo[a.Name]
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("unexpected package found: %s", a.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expectedVersion != a.Version {
|
||||||
|
t.Errorf("unexpected package version (pkg=%s): %s", a.Name, a.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.Language != c.pkgLanguage {
|
||||||
|
t.Errorf("bad language (pkg=%+v): %+v", a.Name, a.Language)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.Type != c.pkgType {
|
||||||
|
t.Errorf("bad package type (pkg=%+v): %+v", a.Name, a.Type)
|
||||||
|
}
|
||||||
|
pkgCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
if pkgCount != len(c.pkgInfo) {
|
||||||
|
for a := range catalog.Enumerate(c.pkgType) {
|
||||||
|
t.Log(" ", a)
|
||||||
|
}
|
||||||
|
t.Fatalf("unexpected package count: %d!=%d", pkgCount, len(c.pkgInfo))
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
observedLanguages.Remove(pkg.UnknownLanguage.String())
|
||||||
|
definedLanguages.Remove(pkg.UnknownLanguage.String())
|
||||||
|
observedPkgs.Remove(pkg.UnknownPkg.String())
|
||||||
|
definedPkgs.Remove(pkg.UnknownPkg.String())
|
||||||
|
|
||||||
|
// ensure that integration test cases stay in sync with the available catalogers
|
||||||
|
if len(observedLanguages) < len(definedLanguages) {
|
||||||
|
t.Errorf("language coverage incomplete (languages=%d, coverage=%d)", len(definedLanguages), len(observedLanguages))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(observedPkgs) < len(definedPkgs) {
|
||||||
|
t.Errorf("package coverage incomplete (packages=%d, coverage=%d)", len(definedPkgs), len(observedPkgs))
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@ -1,256 +0,0 @@
|
|||||||
[Path: test-fixtures]
|
|
||||||
[actionmailer]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[actionpack]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[actionview]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[activemodel]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[activerecord]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[activesupport]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[arel]
|
|
||||||
Version: 5.0.1.20140414130214
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[bootstrap-sass]
|
|
||||||
Version: 3.1.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[builder]
|
|
||||||
Version: 3.2.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[coffee-rails]
|
|
||||||
Version: 4.0.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[coffee-script]
|
|
||||||
Version: 2.2.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[coffee-script-source]
|
|
||||||
Version: 1.7.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[erubis]
|
|
||||||
Version: 2.7.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[execjs]
|
|
||||||
Version: 2.0.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[hike]
|
|
||||||
Version: 1.2.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[i18n]
|
|
||||||
Version: 0.6.9
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[jbuilder]
|
|
||||||
Version: 2.0.7
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[jquery-rails]
|
|
||||||
Version: 3.1.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[json]
|
|
||||||
Version: 1.8.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[kgio]
|
|
||||||
Version: 2.9.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[libv8]
|
|
||||||
Version: 3.16.14.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[mail]
|
|
||||||
Version: 2.5.4
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[mime-types]
|
|
||||||
Version: 1.25.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[minitest]
|
|
||||||
Version: 5.3.4
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[multi_json]
|
|
||||||
Version: 1.10.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[mysql2]
|
|
||||||
Version: 0.3.16
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[polyglot]
|
|
||||||
Version: 0.3.4
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rack]
|
|
||||||
Version: 1.5.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rack-test]
|
|
||||||
Version: 0.6.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rails]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[railties]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[raindrops]
|
|
||||||
Version: 0.13.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rake]
|
|
||||||
Version: 10.3.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[rdoc]
|
|
||||||
Version: 4.1.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[ref]
|
|
||||||
Version: 1.0.5
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sass]
|
|
||||||
Version: 3.2.19
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sass-rails]
|
|
||||||
Version: 4.0.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sdoc]
|
|
||||||
Version: 0.4.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[spring]
|
|
||||||
Version: 1.1.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sprockets]
|
|
||||||
Version: 2.11.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sprockets-rails]
|
|
||||||
Version: 2.1.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[sqlite3]
|
|
||||||
Version: 1.3.9
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[therubyracer]
|
|
||||||
Version: 0.12.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[thor]
|
|
||||||
Version: 0.19.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[thread_safe]
|
|
||||||
Version: 0.3.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[tilt]
|
|
||||||
Version: 1.4.1
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[treetop]
|
|
||||||
Version: 1.4.15
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[turbolinks]
|
|
||||||
Version: 2.2.2
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[tzinfo]
|
|
||||||
Version: 1.2.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[uglifier]
|
|
||||||
Version: 2.5.0
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
[unicorn]
|
|
||||||
Version: 4.8.3
|
|
||||||
Type: bundle
|
|
||||||
Found by: bundler-cataloger
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user