mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
add tests for content requester object
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
45fed7c69b
commit
d94d7a7d80
@ -2,11 +2,14 @@ package source
|
||||
|
||||
import "sync"
|
||||
|
||||
// ContentRequester is an object tailored for taking source.Location objects which file contents will be resolved
|
||||
// upon invoking Execute().
|
||||
type ContentRequester struct {
|
||||
request map[Location][]*FileData
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// NewContentRequester creates a new ContentRequester object with the given initial request data.
|
||||
func NewContentRequester(data ...*FileData) *ContentRequester {
|
||||
requester := &ContentRequester{
|
||||
request: make(map[Location][]*FileData),
|
||||
@ -17,19 +20,24 @@ func NewContentRequester(data ...*FileData) *ContentRequester {
|
||||
return requester
|
||||
}
|
||||
|
||||
func (b *ContentRequester) Add(data *FileData) {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
b.request[data.Location] = append(b.request[data.Location], data)
|
||||
// Add appends a new single FileData containing a source.Location to later have the contents fetched and stored within
|
||||
// the given FileData object.
|
||||
func (r *ContentRequester) Add(data *FileData) {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
r.request[data.Location] = append(r.request[data.Location], data)
|
||||
}
|
||||
|
||||
func (b *ContentRequester) Execute(resolver ContentResolver) error {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
// Execute takes the previously provided source.Location's and resolves the file contents, storing the results within
|
||||
// the previously provided FileData objects.
|
||||
func (r *ContentRequester) Execute(resolver ContentResolver) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
var locations = make([]Location, len(b.request))
|
||||
var locations = make([]Location, len(r.request))
|
||||
idx := 0
|
||||
for l := range b.request {
|
||||
for l := range r.request {
|
||||
locations[idx] = l
|
||||
idx++
|
||||
}
|
||||
@ -40,8 +48,8 @@ func (b *ContentRequester) Execute(resolver ContentResolver) error {
|
||||
}
|
||||
|
||||
for l, contents := range response {
|
||||
for i := range b.request[l] {
|
||||
b.request[l][i].Contents = contents
|
||||
for i := range r.request[l] {
|
||||
r.request[l][i].Contents = contents
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
69
syft/source/content_requester_test.go
Normal file
69
syft/source/content_requester_test.go
Normal file
@ -0,0 +1,69 @@
|
||||
package source
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/stereoscope/pkg/imagetest"
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
)
|
||||
|
||||
func TestContentRequester(t *testing.T) {
|
||||
tests := []struct {
|
||||
fixture string
|
||||
expectedContents map[string]string
|
||||
}{
|
||||
{
|
||||
fixture: "image-simple",
|
||||
expectedContents: map[string]string{
|
||||
"/somefile-1.txt": "this file has contents",
|
||||
"/somefile-2.txt": "file-2 contents!",
|
||||
"/really/nested/file-3.txt": "another file!\nwith lines...",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.fixture, func(t *testing.T) {
|
||||
img, cleanup := imagetest.GetFixtureImage(t, "docker-archive", "image-simple")
|
||||
defer cleanup()
|
||||
|
||||
resolver, err := NewAllLayersResolver(img)
|
||||
if err != nil {
|
||||
t.Fatalf("could not create resolver: %+v", err)
|
||||
}
|
||||
|
||||
var data []*FileData
|
||||
for path := range test.expectedContents {
|
||||
|
||||
locations, err := resolver.FilesByPath(path)
|
||||
if err != nil {
|
||||
t.Fatalf("could not build request: %+v", err)
|
||||
}
|
||||
if len(locations) != 1 {
|
||||
t.Fatalf("bad resolver paths: %+v", locations)
|
||||
}
|
||||
|
||||
data = append(data, &FileData{
|
||||
Location: locations[0],
|
||||
})
|
||||
}
|
||||
|
||||
if err := NewContentRequester(data...).Execute(resolver); err != nil {
|
||||
t.Fatalf("could not execute request: %+v", err)
|
||||
}
|
||||
|
||||
for _, entry := range data {
|
||||
if expected, ok := test.expectedContents[entry.Location.Path]; ok {
|
||||
for expected != entry.Contents {
|
||||
t.Errorf("mismatched contents for %q", entry.Location.Path)
|
||||
dmp := diffmatchpatch.New()
|
||||
diffs := dmp.DiffMain(expected, entry.Contents, true)
|
||||
t.Errorf("diff: %s", dmp.DiffPrettyText(diffs))
|
||||
}
|
||||
continue
|
||||
}
|
||||
t.Errorf("could not find %q", entry.Location.Path)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -180,7 +180,7 @@ 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"}
|
||||
resolver := DirectoryResolver{"test-fixtures/image-symlinks"}
|
||||
refs, err := resolver.FilesByGlob("**/*.txt")
|
||||
|
||||
if err != nil {
|
||||
|
||||
6
syft/source/test-fixtures/image-simple/Dockerfile
Normal file
6
syft/source/test-fixtures/image-simple/Dockerfile
Normal file
@ -0,0 +1,6 @@
|
||||
# Note: changes to this file will result in updating several test values. Consider making a new image fixture instead of editing this one.
|
||||
FROM scratch
|
||||
ADD file-1.txt /somefile-1.txt
|
||||
ADD file-2.txt /somefile-2.txt
|
||||
# note: adding a directory will behave differently on docker engine v18 vs v19
|
||||
ADD target /
|
||||
1
syft/source/test-fixtures/image-simple/file-1.txt
Normal file
1
syft/source/test-fixtures/image-simple/file-1.txt
Normal file
@ -0,0 +1 @@
|
||||
this file has contents
|
||||
1
syft/source/test-fixtures/image-simple/file-2.txt
Normal file
1
syft/source/test-fixtures/image-simple/file-2.txt
Normal file
@ -0,0 +1 @@
|
||||
file-2 contents!
|
||||
@ -0,0 +1,2 @@
|
||||
another file!
|
||||
with lines...
|
||||
Loading…
x
Reference in New Issue
Block a user