add tests for content requester object

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2020-12-14 21:03:49 -05:00
parent 45fed7c69b
commit d94d7a7d80
No known key found for this signature in database
GPG Key ID: 5CB45AE22BAB7EA7
7 changed files with 99 additions and 12 deletions

View File

@ -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

View 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)
}
})
}
}

View File

@ -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 {

View 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 /

View File

@ -0,0 +1 @@
this file has contents

View File

@ -0,0 +1 @@
file-2 contents!

View File

@ -0,0 +1,2 @@
another file!
with lines...