mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
797 lines
19 KiB
Go
797 lines
19 KiB
Go
//go:build !windows
|
|
// +build !windows
|
|
|
|
package source
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
"syscall"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/anchore/stereoscope/pkg/image"
|
|
"github.com/anchore/stereoscope/pkg/imagetest"
|
|
"github.com/anchore/syft/syft/artifact"
|
|
)
|
|
|
|
func TestParseInput(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
platform string
|
|
expected Scheme
|
|
errFn require.ErrorAssertionFunc
|
|
}{
|
|
{
|
|
name: "ParseInput parses a file input",
|
|
input: "test-fixtures/image-simple/file-1.txt",
|
|
expected: FileScheme,
|
|
},
|
|
{
|
|
name: "errors out when using platform for non-image scheme",
|
|
input: "test-fixtures/image-simple/file-1.txt",
|
|
platform: "arm64",
|
|
errFn: require.Error,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
if test.errFn == nil {
|
|
test.errFn = require.NoError
|
|
}
|
|
sourceInput, err := ParseInput(test.input, test.platform, true)
|
|
test.errFn(t, err)
|
|
if test.expected != "" {
|
|
require.NotNil(t, sourceInput)
|
|
assert.Equal(t, sourceInput.Scheme, test.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewFromImageFails(t *testing.T) {
|
|
t.Run("no image given", func(t *testing.T) {
|
|
_, err := NewFromImage(nil, "")
|
|
if err == nil {
|
|
t.Errorf("expected an error condition but none was given")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestSetID(t *testing.T) {
|
|
layer := image.NewLayer(nil)
|
|
layer.Metadata = image.LayerMetadata{
|
|
Digest: "sha256:6f4fb385d4e698647bf2a450749dfbb7bc2831ec9a730ef4046c78c08d468e89",
|
|
}
|
|
img := image.Image{
|
|
Layers: []*image.Layer{layer},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
input *Source
|
|
expected artifact.ID
|
|
}{
|
|
{
|
|
name: "source.SetID sets the ID for FileScheme",
|
|
input: &Source{
|
|
Metadata: Metadata{
|
|
Scheme: FileScheme,
|
|
Path: "test-fixtures/image-simple/file-1.txt",
|
|
},
|
|
},
|
|
expected: artifact.ID("55096713247489add592ce977637be868497132b36d1e294a3831925ec64319a"),
|
|
},
|
|
{
|
|
name: "source.SetID sets the ID for ImageScheme",
|
|
input: &Source{
|
|
Image: &img,
|
|
Metadata: Metadata{
|
|
Scheme: ImageScheme,
|
|
},
|
|
},
|
|
expected: artifact.ID("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
|
|
},
|
|
{
|
|
name: "source.SetID sets the ID for DirectoryScheme",
|
|
input: &Source{
|
|
Image: &img,
|
|
Metadata: Metadata{
|
|
Scheme: DirectoryScheme,
|
|
Path: "test-fixtures/image-simple",
|
|
},
|
|
},
|
|
expected: artifact.ID("91db61e5e0ae097ef764796ce85e442a93f2a03e5313d4c7307e9b413f62e8c4"),
|
|
},
|
|
{
|
|
name: "source.SetID sets the ID for UnknownScheme",
|
|
input: &Source{
|
|
Image: &img,
|
|
Metadata: Metadata{
|
|
Scheme: UnknownScheme,
|
|
Path: "test-fixtures/image-simple",
|
|
},
|
|
},
|
|
expected: artifact.ID("febd2d6148dc327d"),
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
test.input.SetID()
|
|
assert.Equal(t, test.expected, test.input.ID())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewFromImage(t *testing.T) {
|
|
layer := image.NewLayer(nil)
|
|
img := image.Image{
|
|
Layers: []*image.Layer{layer},
|
|
}
|
|
|
|
t.Run("create a new source object from image", func(t *testing.T) {
|
|
_, err := NewFromImage(&img, "")
|
|
if err != nil {
|
|
t.Errorf("unexpected error when creating a new Locations from img: %+v", err)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestNewFromDirectory(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
input string
|
|
expString string
|
|
inputPaths []string
|
|
expectedRefs int
|
|
expectedErr bool
|
|
}{
|
|
{
|
|
desc: "no paths exist",
|
|
input: "foobar/",
|
|
inputPaths: []string{"/opt/", "/other"},
|
|
expectedErr: true,
|
|
},
|
|
{
|
|
desc: "path detected",
|
|
input: "test-fixtures",
|
|
inputPaths: []string{"path-detected/.vimrc"},
|
|
expectedRefs: 1,
|
|
},
|
|
{
|
|
desc: "directory ignored",
|
|
input: "test-fixtures",
|
|
inputPaths: []string{"path-detected"},
|
|
expectedRefs: 0,
|
|
},
|
|
{
|
|
desc: "no files-by-path detected",
|
|
input: "test-fixtures",
|
|
inputPaths: []string{"no-path-detected"},
|
|
expectedRefs: 0,
|
|
},
|
|
}
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
src, err := NewFromDirectory(test.input)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, test.input, src.Metadata.Path)
|
|
|
|
resolver, err := src.FileResolver(SquashedScope)
|
|
if test.expectedErr {
|
|
if err == nil {
|
|
t.Fatal("expected an error when making the resolver but got none")
|
|
}
|
|
return
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
refs, err := resolver.FilesByPath(test.inputPaths...)
|
|
if err != nil {
|
|
t.Errorf("FilesByPath call produced an error: %+v", err)
|
|
}
|
|
if len(refs) != test.expectedRefs {
|
|
t.Errorf("unexpected number of refs returned: %d != %d", len(refs), test.expectedRefs)
|
|
|
|
}
|
|
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewFromFile(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
input string
|
|
expString string
|
|
inputPaths []string
|
|
expRefs int
|
|
}{
|
|
{
|
|
desc: "path detected",
|
|
input: "test-fixtures/path-detected",
|
|
inputPaths: []string{"/.vimrc"},
|
|
expRefs: 1,
|
|
},
|
|
}
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
src, cleanup := NewFromFile(test.input)
|
|
if cleanup != nil {
|
|
t.Cleanup(cleanup)
|
|
}
|
|
|
|
assert.Equal(t, test.input, src.Metadata.Path)
|
|
assert.Equal(t, src.Metadata.Path, src.path)
|
|
|
|
resolver, err := src.FileResolver(SquashedScope)
|
|
require.NoError(t, err)
|
|
|
|
refs, err := resolver.FilesByPath(test.inputPaths...)
|
|
require.NoError(t, err)
|
|
assert.Len(t, refs, test.expRefs)
|
|
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewFromFile_WithArchive(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
input string
|
|
expString string
|
|
inputPaths []string
|
|
expRefs int
|
|
}{
|
|
{
|
|
desc: "path detected",
|
|
input: "test-fixtures/path-detected",
|
|
inputPaths: []string{"/.vimrc"},
|
|
expRefs: 1,
|
|
},
|
|
}
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
archivePath := setupArchiveTest(t, test.input)
|
|
|
|
src, cleanup := NewFromFile(archivePath)
|
|
if cleanup != nil {
|
|
t.Cleanup(cleanup)
|
|
}
|
|
|
|
assert.Equal(t, archivePath, src.Metadata.Path)
|
|
assert.NotEqual(t, src.Metadata.Path, src.path)
|
|
|
|
resolver, err := src.FileResolver(SquashedScope)
|
|
require.NoError(t, err)
|
|
|
|
refs, err := resolver.FilesByPath(test.inputPaths...)
|
|
require.NoError(t, err)
|
|
assert.Len(t, refs, test.expRefs)
|
|
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewFromDirectoryShared(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
input string
|
|
expString string
|
|
notExist string
|
|
inputPaths []string
|
|
expRefs int
|
|
}{
|
|
{
|
|
desc: "path detected",
|
|
input: "test-fixtures",
|
|
notExist: "foobar/",
|
|
inputPaths: []string{"path-detected/.vimrc"},
|
|
expRefs: 1,
|
|
},
|
|
{
|
|
desc: "directory ignored",
|
|
input: "test-fixtures",
|
|
notExist: "foobar/",
|
|
inputPaths: []string{"path-detected"},
|
|
expRefs: 0,
|
|
},
|
|
{
|
|
desc: "no files-by-path detected",
|
|
input: "test-fixtures",
|
|
notExist: "foobar/",
|
|
inputPaths: []string{"no-path-detected"},
|
|
expRefs: 0,
|
|
},
|
|
}
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
src, err := NewFromDirectory(test.input)
|
|
|
|
if err != nil {
|
|
t.Errorf("could not create NewDirScope: %+v", err)
|
|
}
|
|
if src.Metadata.Path != test.input {
|
|
t.Errorf("mismatched stringer: '%s' != '%s'", src.Metadata.Path, test.input)
|
|
}
|
|
|
|
_, err = src.FileResolver(SquashedScope)
|
|
assert.NoError(t, err)
|
|
|
|
src.Metadata.Path = test.notExist
|
|
resolver2, err := src.FileResolver(SquashedScope)
|
|
assert.NoError(t, err)
|
|
|
|
refs, err := resolver2.FilesByPath(test.inputPaths...)
|
|
if err != nil {
|
|
t.Errorf("FilesByPath call produced an error: %+v", err)
|
|
}
|
|
if len(refs) != test.expRefs {
|
|
t.Errorf("unexpected number of refs returned: %d != %d", len(refs), test.expRefs)
|
|
|
|
}
|
|
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFilesByPathDoesNotExist(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
input string
|
|
path string
|
|
expected string
|
|
}{
|
|
{
|
|
input: "test-fixtures/path-detected",
|
|
desc: "path does not exist",
|
|
path: "foo",
|
|
},
|
|
}
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
src, err := NewFromDirectory(test.input)
|
|
if err != nil {
|
|
t.Errorf("could not create NewDirScope: %+v", err)
|
|
}
|
|
resolver, err := src.FileResolver(SquashedScope)
|
|
if err != nil {
|
|
t.Errorf("could not get resolver error: %+v", err)
|
|
}
|
|
refs, err := resolver.FilesByPath(test.path)
|
|
if err != nil {
|
|
t.Errorf("could not get file references from path: %s, %v", test.path, err)
|
|
}
|
|
|
|
if len(refs) != 0 {
|
|
t.Errorf("didnt' expect a ref, but got: %d", len(refs))
|
|
}
|
|
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFilesByGlob(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
input string
|
|
glob string
|
|
expected int
|
|
}{
|
|
{
|
|
input: "test-fixtures",
|
|
desc: "no matches",
|
|
glob: "bar/foo",
|
|
expected: 0,
|
|
},
|
|
{
|
|
input: "test-fixtures/path-detected",
|
|
desc: "a single match",
|
|
glob: "**/*vimrc",
|
|
expected: 1,
|
|
},
|
|
{
|
|
input: "test-fixtures/path-detected",
|
|
desc: "multiple matches",
|
|
glob: "**",
|
|
expected: 2,
|
|
},
|
|
}
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
src, err := NewFromDirectory(test.input)
|
|
if err != nil {
|
|
t.Errorf("could not create NewDirScope: %+v", err)
|
|
}
|
|
resolver, err := src.FileResolver(SquashedScope)
|
|
if err != nil {
|
|
t.Errorf("could not get resolver error: %+v", err)
|
|
}
|
|
contents, err := resolver.FilesByGlob(test.glob)
|
|
if err != nil {
|
|
t.Errorf("could not get files by glob: %s+v", err)
|
|
}
|
|
if len(contents) != test.expected {
|
|
t.Errorf("unexpected number of files found by glob (%s): %d != %d", test.glob, len(contents), test.expected)
|
|
}
|
|
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDirectoryExclusions(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
input string
|
|
glob string
|
|
expected int
|
|
exclusions []string
|
|
err bool
|
|
}{
|
|
{
|
|
input: "test-fixtures/system_paths",
|
|
desc: "exclude everything",
|
|
glob: "**",
|
|
expected: 0,
|
|
exclusions: []string{"**/*"},
|
|
},
|
|
{
|
|
input: "test-fixtures/image-simple",
|
|
desc: "a single path excluded",
|
|
glob: "**",
|
|
expected: 3,
|
|
exclusions: []string{"**/target/**"},
|
|
},
|
|
{
|
|
input: "test-fixtures/image-simple",
|
|
desc: "exclude explicit directory relative to the root",
|
|
glob: "**",
|
|
expected: 3,
|
|
exclusions: []string{"./target"},
|
|
},
|
|
{
|
|
input: "test-fixtures/image-simple",
|
|
desc: "exclude explicit file relative to the root",
|
|
glob: "**",
|
|
expected: 3,
|
|
exclusions: []string{"./file-1.txt"},
|
|
},
|
|
{
|
|
input: "test-fixtures/image-simple",
|
|
desc: "exclude wildcard relative to the root",
|
|
glob: "**",
|
|
expected: 2,
|
|
exclusions: []string{"./*.txt"},
|
|
},
|
|
{
|
|
input: "test-fixtures/image-simple",
|
|
desc: "exclude files deeper",
|
|
glob: "**",
|
|
expected: 3,
|
|
exclusions: []string{"**/really/**"},
|
|
},
|
|
{
|
|
input: "test-fixtures/image-simple",
|
|
desc: "files excluded with extension",
|
|
glob: "**",
|
|
expected: 1,
|
|
exclusions: []string{"**/*.txt"},
|
|
},
|
|
{
|
|
input: "test-fixtures/image-simple",
|
|
desc: "keep files with different extensions",
|
|
glob: "**",
|
|
expected: 4,
|
|
exclusions: []string{"**/target/**/*.jar"},
|
|
},
|
|
{
|
|
input: "test-fixtures/path-detected",
|
|
desc: "file directly excluded",
|
|
glob: "**",
|
|
expected: 1,
|
|
exclusions: []string{"**/empty"},
|
|
},
|
|
{
|
|
input: "test-fixtures/path-detected",
|
|
desc: "pattern error containing **/",
|
|
glob: "**",
|
|
expected: 1,
|
|
exclusions: []string{"/**/empty"},
|
|
err: true,
|
|
},
|
|
{
|
|
input: "test-fixtures/path-detected",
|
|
desc: "pattern error incorrect start",
|
|
glob: "**",
|
|
expected: 1,
|
|
exclusions: []string{"empty"},
|
|
err: true,
|
|
},
|
|
{
|
|
input: "test-fixtures/path-detected",
|
|
desc: "pattern error starting with /",
|
|
glob: "**",
|
|
expected: 1,
|
|
exclusions: []string{"/empty"},
|
|
err: true,
|
|
},
|
|
}
|
|
registryOpts := &image.RegistryOptions{}
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
sourceInput, err := ParseInput("dir:"+test.input, "", false)
|
|
require.NoError(t, err)
|
|
src, fn, err := New(*sourceInput, registryOpts, test.exclusions)
|
|
defer fn()
|
|
|
|
if test.err {
|
|
_, err = src.FileResolver(SquashedScope)
|
|
if err == nil {
|
|
t.Errorf("expected an error for patterns: %s", strings.Join(test.exclusions, " or "))
|
|
}
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
t.Errorf("could not create NewDirScope: %+v", err)
|
|
}
|
|
resolver, err := src.FileResolver(SquashedScope)
|
|
if err != nil {
|
|
t.Errorf("could not get resolver error: %+v", err)
|
|
}
|
|
contents, err := resolver.FilesByGlob(test.glob)
|
|
if err != nil {
|
|
t.Errorf("could not get files by glob: %s+v", err)
|
|
}
|
|
if len(contents) != test.expected {
|
|
t.Errorf("wrong number of files after exclusions (%s): %d != %d", test.glob, len(contents), test.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestImageExclusions(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
input string
|
|
glob string
|
|
expected int
|
|
exclusions []string
|
|
}{
|
|
// NOTE: in the Dockerfile, /target is moved to /, which makes /really a top-level dir
|
|
{
|
|
input: "image-simple",
|
|
desc: "a single path excluded",
|
|
glob: "**",
|
|
expected: 2,
|
|
exclusions: []string{"/really/**"},
|
|
},
|
|
{
|
|
input: "image-simple",
|
|
desc: "a directly referenced directory is excluded",
|
|
glob: "**",
|
|
expected: 2,
|
|
exclusions: []string{"/really"},
|
|
},
|
|
{
|
|
input: "image-simple",
|
|
desc: "a partial directory is not excluded",
|
|
glob: "**",
|
|
expected: 3,
|
|
exclusions: []string{"/reall"},
|
|
},
|
|
{
|
|
input: "image-simple",
|
|
desc: "exclude files deeper",
|
|
glob: "**",
|
|
expected: 2,
|
|
exclusions: []string{"**/nested/**"},
|
|
},
|
|
{
|
|
input: "image-simple",
|
|
desc: "files excluded with extension",
|
|
glob: "**",
|
|
expected: 2,
|
|
exclusions: []string{"**/*1.txt"},
|
|
},
|
|
{
|
|
input: "image-simple",
|
|
desc: "keep files with different extensions",
|
|
glob: "**",
|
|
expected: 3,
|
|
exclusions: []string{"**/target/**/*.jar"},
|
|
},
|
|
{
|
|
input: "image-simple",
|
|
desc: "file directly excluded",
|
|
glob: "**",
|
|
expected: 2,
|
|
exclusions: []string{"**/somefile-1.txt"}, // file-1 renamed to somefile-1 in Dockerfile
|
|
},
|
|
}
|
|
registryOpts := &image.RegistryOptions{}
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
archiveLocation := imagetest.PrepareFixtureImage(t, "docker-archive", test.input)
|
|
sourceInput, err := ParseInput(archiveLocation, "", false)
|
|
require.NoError(t, err)
|
|
src, fn, err := New(*sourceInput, registryOpts, test.exclusions)
|
|
defer fn()
|
|
|
|
if err != nil {
|
|
t.Errorf("could not create NewDirScope: %+v", err)
|
|
}
|
|
resolver, err := src.FileResolver(SquashedScope)
|
|
if err != nil {
|
|
t.Errorf("could not get resolver error: %+v", err)
|
|
}
|
|
contents, err := resolver.FilesByGlob(test.glob)
|
|
if err != nil {
|
|
t.Errorf("could not get files by glob: %s+v", err)
|
|
}
|
|
if len(contents) != test.expected {
|
|
t.Errorf("wrong number of files after exclusions (%s): %d != %d", test.glob, len(contents), test.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_crossPlatformExclusions(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
root string
|
|
path string
|
|
exclude string
|
|
match bool
|
|
}{
|
|
{
|
|
desc: "linux doublestar",
|
|
root: "/usr",
|
|
path: "/usr/var/lib/etc.txt",
|
|
exclude: "**/*.txt",
|
|
match: true,
|
|
},
|
|
{
|
|
desc: "linux relative",
|
|
root: "/usr/var/lib",
|
|
path: "/usr/var/lib/etc.txt",
|
|
exclude: "./*.txt",
|
|
match: true,
|
|
},
|
|
{
|
|
desc: "linux one level",
|
|
root: "/usr",
|
|
path: "/usr/var/lib/etc.txt",
|
|
exclude: "*/*.txt",
|
|
match: false,
|
|
},
|
|
// NOTE: since these tests will run in linux and macOS, the windows paths will be
|
|
// considered relative if they do not start with a forward slash and paths with backslashes
|
|
// won't be modified by the filepath.ToSlash call, so these are emulating the result of
|
|
// filepath.ToSlash usage
|
|
{
|
|
desc: "windows doublestar",
|
|
root: "/C:/User/stuff",
|
|
path: "/C:/User/stuff/thing.txt",
|
|
exclude: "**/*.txt",
|
|
match: true,
|
|
},
|
|
{
|
|
desc: "windows relative",
|
|
root: "/C:/User/stuff",
|
|
path: "/C:/User/stuff/thing.txt",
|
|
exclude: "./*.txt",
|
|
match: true,
|
|
},
|
|
{
|
|
desc: "windows one level",
|
|
root: "/C:/User/stuff",
|
|
path: "/C:/User/stuff/thing.txt",
|
|
exclude: "*/*.txt",
|
|
match: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
fns, err := getDirectoryExclusionFunctions(test.root, []string{test.exclude})
|
|
require.NoError(t, err)
|
|
|
|
for _, f := range fns {
|
|
result := f(test.path, nil)
|
|
require.Equal(t, test.match, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// createArchive creates a new archive file at destinationArchivePath based on the directory found at sourceDirPath.
|
|
func createArchive(t testing.TB, sourceDirPath, destinationArchivePath string) {
|
|
t.Helper()
|
|
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
t.Fatalf("unable to get cwd: %+v", err)
|
|
}
|
|
|
|
cmd := exec.Command("./generate-tar-fixture-from-source-dir.sh", destinationArchivePath, path.Base(sourceDirPath))
|
|
cmd.Dir = filepath.Join(cwd, "test-fixtures")
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
t.Fatalf("unable to start generate zip fixture script: %+v", err)
|
|
}
|
|
|
|
if err := cmd.Wait(); err != nil {
|
|
if exiterr, ok := err.(*exec.ExitError); ok {
|
|
// The program has exited with an exit code != 0
|
|
|
|
// This works on both Unix and Windows. Although package
|
|
// syscall is generally platform dependent, WaitStatus is
|
|
// defined for both Unix and Windows and in both cases has
|
|
// an ExitStatus() method with the same signature.
|
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
|
if status.ExitStatus() != 0 {
|
|
t.Fatalf("failed to generate fixture: rc=%d", status.ExitStatus())
|
|
}
|
|
}
|
|
} else {
|
|
t.Fatalf("unable to get generate fixture script result: %+v", err)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// setupArchiveTest encapsulates common test setup work for tar file tests. It returns a cleanup function,
|
|
// which should be called (typically deferred) by the caller, the path of the created tar archive, and an error,
|
|
// which should trigger a fatal test failure in the consuming test. The returned cleanup function will never be nil
|
|
// (even if there's an error), and it should always be called.
|
|
func setupArchiveTest(t testing.TB, sourceDirPath string) string {
|
|
t.Helper()
|
|
|
|
archivePrefix, err := ioutil.TempFile("", "syft-archive-TEST-")
|
|
require.NoError(t, err)
|
|
|
|
t.Cleanup(
|
|
assertNoError(t,
|
|
func() error {
|
|
return os.Remove(archivePrefix.Name())
|
|
},
|
|
),
|
|
)
|
|
|
|
destinationArchiveFilePath := archivePrefix.Name() + ".tar"
|
|
t.Logf("archive path: %s", destinationArchiveFilePath)
|
|
createArchive(t, sourceDirPath, destinationArchiveFilePath)
|
|
|
|
t.Cleanup(
|
|
assertNoError(t,
|
|
func() error {
|
|
return os.Remove(destinationArchiveFilePath)
|
|
},
|
|
),
|
|
)
|
|
|
|
cwd, err := os.Getwd()
|
|
require.NoError(t, err)
|
|
|
|
t.Logf("running from: %s", cwd)
|
|
|
|
return destinationArchiveFilePath
|
|
}
|
|
|
|
func assertNoError(t testing.TB, fn func() error) func() {
|
|
return func() {
|
|
assert.NoError(t, fn())
|
|
}
|
|
}
|