mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +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/anchore/go-testutils v0.0.0-20200624184116-66aa578126db
|
||||
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/google/go-containerregistry v0.1.1 // indirect
|
||||
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/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||
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.2.0/go.mod h1:Azh8c3XGEJl9LyX0/sFC+CKMc7Ssgua0g+6abzXN4Pg=
|
||||
github.com/bombsimon/wsl/v3 v3.0.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
|
||||
|
||||
@ -13,7 +13,7 @@ type Cataloger struct {
|
||||
|
||||
func NewCataloger() *Cataloger {
|
||||
globParsers := map[string]common.ParserFn{
|
||||
"*/Gemfile.lock": parseGemfileLockEntries,
|
||||
"**/Gemfile.lock": parseGemfileLockEntries,
|
||||
}
|
||||
|
||||
return &Cataloger{
|
||||
|
||||
@ -12,12 +12,12 @@ type Cataloger struct {
|
||||
}
|
||||
|
||||
func NewCataloger() *Cataloger {
|
||||
pathParsers := map[string]common.ParserFn{
|
||||
"/var/lib/dpkg/status": parseDpkgStatus,
|
||||
globParsers := map[string]common.ParserFn{
|
||||
"**/var/lib/dpkg/status": parseDpkgStatus,
|
||||
}
|
||||
|
||||
return &Cataloger{
|
||||
cataloger: common.NewGenericCataloger(pathParsers, nil),
|
||||
cataloger: common.NewGenericCataloger(nil, globParsers),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,11 +11,11 @@ import (
|
||||
)
|
||||
|
||||
var archiveFormatGlobs = []string{
|
||||
"*.jar",
|
||||
"*.war",
|
||||
"*.ear",
|
||||
"*.jpi",
|
||||
"*.hpi",
|
||||
"**/*.jar",
|
||||
"**/*.war",
|
||||
"**/*.ear",
|
||||
"**/*.jpi",
|
||||
"**/*.hpi",
|
||||
}
|
||||
|
||||
type archiveParser struct {
|
||||
|
||||
@ -13,8 +13,8 @@ type Cataloger struct {
|
||||
|
||||
func NewCataloger() *Cataloger {
|
||||
globParsers := map[string]common.ParserFn{
|
||||
"*egg-info/PKG-INFO": parseEggMetadata,
|
||||
"*dist-info/METADATA": parseWheelMetadata,
|
||||
"**/egg-info/PKG-INFO": parseEggMetadata,
|
||||
"**/dist-info/METADATA": parseWheelMetadata,
|
||||
}
|
||||
|
||||
return &Cataloger{
|
||||
|
||||
@ -12,12 +12,12 @@ type Cataloger struct {
|
||||
}
|
||||
|
||||
func NewCataloger() *Cataloger {
|
||||
pathParsers := map[string]common.ParserFn{
|
||||
"/var/lib/rpm/Packages": parseRpmDB,
|
||||
globParsers := map[string]common.ParserFn{
|
||||
"**/var/lib/rpm/Packages": parseRpmDB,
|
||||
}
|
||||
|
||||
return &Cataloger{
|
||||
cataloger: common.NewGenericCataloger(pathParsers, nil),
|
||||
cataloger: common.NewGenericCataloger(nil, globParsers),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,10 +5,10 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/anchore/imgbom/internal/log"
|
||||
"github.com/anchore/stereoscope/pkg/file"
|
||||
"github.com/bmatcuk/doublestar"
|
||||
)
|
||||
|
||||
type DirectoryResolver struct {
|
||||
@ -51,7 +51,7 @@ func (s DirectoryResolver) FilesByGlob(patterns ...string) ([]file.Reference, er
|
||||
|
||||
for _, pattern := range patterns {
|
||||
pathPattern := path.Join(s.Path, pattern)
|
||||
matches, err := filepath.Glob(pathPattern)
|
||||
matches, err := doublestar.Glob(pathPattern)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
@ -138,6 +138,7 @@ func TestDirectoryResolver_FilesByGlobMultiple(t *testing.T) {
|
||||
t.Run("finds multiple matching files", func(t *testing.T) {
|
||||
resolver := DirectoryResolver{"test-fixtures"}
|
||||
refs, err := resolver.FilesByGlob("image-symlinks/file*")
|
||||
|
||||
if err != nil {
|
||||
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) {
|
||||
t.Run("finds multiple matching files", func(t *testing.T) {
|
||||
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