Skip to content

Commit

Permalink
test: port various other fetcher abstractions to `claircore.LayerDesc…
Browse files Browse the repository at this point in the history
…ription`

There's too many of these things.

Signed-off-by: Hank Donnay <[email protected]>
  • Loading branch information
hdonnay committed Oct 12, 2023
1 parent 957a02b commit 6f27cfc
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 45 deletions.
75 changes: 50 additions & 25 deletions test/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"crypto/rand"
"crypto/sha256"
"fmt"
"io"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -51,14 +52,14 @@ func (l *layerserver) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}

// ServeLayers constructs "n" random layers, arranges to serve them, and returns
// a slice of filled Layer structs.
func ServeLayers(t *testing.T, n int) (*http.Client, []*claircore.Layer) {
// corresponding LayerDescriptions.
func ServeLayers(t *testing.T, n int) (*http.Client, []claircore.LayerDescription) {
const filesize = 32
lsrv := &layerserver{
now: time.Now(),
blobs: make([]*bytes.Reader, n),
}
ls := make([]*claircore.Layer, n)
descs := make([]claircore.LayerDescription, n)
srv := httptest.NewServer(lsrv)
t.Cleanup(func() {
srv.CloseClientConnections()
Expand Down Expand Up @@ -97,52 +98,76 @@ func ServeLayers(t *testing.T, n int) (*http.Client, []*claircore.Layer) {
}

lsrv.blobs[i] = bytes.NewReader(buf.Bytes())
ls[i] = &claircore.Layer{
URI: u.String(),
}
ls[i].Hash, err = claircore.NewDigest("sha256", h.Sum(nil))
if err != nil {
t.Fatal(err)
}
d := &descs[i]
d.MediaType = "application/vnd.oci.image.layer.v1.tar"
d.Headers = make(http.Header)
d.URI = u.String()
d.Digest = fmt.Sprintf("sha256:%x", h.Sum(nil))
}

return srv.Client(), ls
}

type LayerSpec struct {
Domain, Repo string
ID claircore.Digest
return srv.Client(), descs
}

// RealizeLayers uses fetch.Layer to populate a directory and returns a slice of Layers describing them.
func RealizeLayers(ctx context.Context, t *testing.T, spec ...LayerSpec) []claircore.Layer {
ret := make([]claircore.Layer, len(spec))
//
// Any needed cleanup is handled via the passed [testing.T].
func RealizeLayers(ctx context.Context, t *testing.T, refs ...LayerRef) []claircore.Layer {
ret := make([]claircore.Layer, len(refs))
fetchCh := make(chan int)
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for n := range fetchCh {
id := spec[n].ID
f, err := fetch.Layer(ctx, t, nil, spec[n].Domain, spec[n].Repo, id)
id, err := claircore.ParseDigest(refs[n].Digest)
if err != nil {
t.Error(err)
continue
}
ret[n].URI = "file:///dev/null"
ret[n].Hash = id
ret[n].SetLocal(f.Name())
if err := f.Close(); err != nil {
f, err := fetch.Layer(ctx, t, nil, refs[n].Registry, refs[n].Name, id)
if err != nil {
t.Error(err)
continue
}
t.Cleanup(func() {
if err := f.Close(); err != nil {
t.Errorf("closing %q: %v", f.Name(), err)
}
})
desc := claircore.LayerDescription{
URI: "file:///dev/null",
Digest: id.String(),
// Bit of bad coupling seeping in here: all tar-based layers
// are handled the same, so this doesn't matter as long as
// it's a tar.
MediaType: MediaType,
}
if err := ret[n].Init(ctx, &desc, f); err != nil {
t.Error(err)
}
t.Cleanup(func() {
l := &ret[n]
if err := l.Close(); err != nil {
t.Errorf("closing %q: %v", l.Hash, err)
}
})
}
}()
}
for n := 0; n < len(spec); n++ {
for n := 0; n < len(refs); n++ {
fetchCh <- n
}
close(fetchCh)
wg.Wait()
return ret
}

// RealizeLayer is a helper around [RealizeLayers] for a single layer.
//
// This is useful for testing a Scanner implementation.
func RealizeLayer(ctx context.Context, t *testing.T, ref LayerRef) *claircore.Layer {
t.Helper()
ls := RealizeLayers(ctx, t, ref)
return &ls[0]
}
54 changes: 34 additions & 20 deletions test/packagescanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,7 @@ func (tc ScannerTestcase) Run(ctx context.Context) func(*testing.T) {
sort.Slice(tc.Want, pkgSort(tc.Want))
return func(t *testing.T) {
ctx := zlog.Test(ctx, t)
d := tc.Digest()
n, err := fetch.Layer(ctx, t, http.DefaultClient, tc.Domain, tc.Name, d)
if err != nil {
t.Fatal(err)
}
defer n.Close()
l := &claircore.Layer{
Hash: d,
}
l.SetLocal(n.Name())
l := tc.getLayer(ctx, t)

got, err := tc.Scanner.Scan(ctx, l)
if err != nil {
Expand All @@ -80,16 +71,7 @@ func (tc ScannerTestcase) RunSubset(ctx context.Context, n int) func(*testing.T)
sort.Slice(tc.Want, pkgSort(tc.Want))
return func(t *testing.T) {
ctx := zlog.Test(ctx, t)
d := tc.Digest()
f, err := fetch.Layer(ctx, t, http.DefaultClient, tc.Domain, tc.Name, d)
if err != nil {
t.Fatal(err)
}
defer f.Close()
l := &claircore.Layer{
Hash: d,
}
l.SetLocal(f.Name())
l := tc.getLayer(ctx, t)

got, err := tc.Scanner.Scan(ctx, l)
if err != nil {
Expand Down Expand Up @@ -129,6 +111,38 @@ func (tc ScannerTestcase) RunSubset(ctx context.Context, n int) func(*testing.T)
}
}

func (tc *ScannerTestcase) getLayer(ctx context.Context, t *testing.T) *claircore.Layer {
d := tc.Digest()
n, err := fetch.Layer(ctx, t, http.DefaultClient, tc.Domain, tc.Name, d)
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
if err := n.Close(); err != nil {
t.Errorf("closing %q: %v", n.Name(), err)
}
})
desc := claircore.LayerDescription{
URI: "file:///dev/null",
Digest: d.String(),
// Bit of bad coupling seeping in here: all tar-based layers
// are handled the same, so this doesn't matter as long as
// it's a tar.
MediaType: MediaType,
}
var l claircore.Layer
if err := l.Init(ctx, &desc, n); err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
if err := l.Close(); err != nil {
t.Errorf("closing Layer %q: %v", l.Hash, err)
}
})

return &l
}

func pkgSort(s []*claircore.Package) func(i, j int) bool {
return func(i, j int) bool {
switch strings.Compare(s[i].Name, s[j].Name) {
Expand Down

0 comments on commit 6f27cfc

Please sign in to comment.