Files

110 lines
2.9 KiB
Go

package store_test
import (
"context"
"net/http/httptest"
"strings"
"testing"
gname "github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/registry"
"github.com/google/go-containerregistry/pkg/v1/random"
"github.com/google/go-containerregistry/pkg/v1/remote"
"hauler.dev/go/hauler/v2/pkg/store"
)
// TestAddImage_ImageStatsAccumulation proves that attaching an *ImageStats
// to the context via WithImageStats before calling AddImage causes
// writeImageBlobs to record the image's layer count and total blob bytes,
// for cosmetic completion-line reporting in the CLI.
func TestAddImage_ImageStatsAccumulation(t *testing.T) {
srv := httptest.NewServer(registry.New())
t.Cleanup(srv.Close)
host := strings.TrimPrefix(srv.URL, "http://")
remoteOpts := []remote.Option{
remote.WithTransport(srv.Client().Transport),
}
const numLayers = 3
img, err := random.Image(512, numLayers)
if err != nil {
t.Fatalf("random.Image: %v", err)
}
layers, err := img.Layers()
if err != nil {
t.Fatalf("img.Layers: %v", err)
}
var wantBytes int64
for _, l := range layers {
size, err := l.Size()
if err != nil {
t.Fatalf("layer.Size: %v", err)
}
wantBytes += size
}
tag, err := gname.NewTag(host+"/test/image:v1", gname.Insecure)
if err != nil {
t.Fatalf("new tag: %v", err)
}
if err := remote.Write(tag, img, remoteOpts...); err != nil {
t.Fatalf("push image: %v", err)
}
s, err := store.NewLayout(t.TempDir())
if err != nil {
t.Fatalf("new layout: %v", err)
}
stats := &store.ImageStats{}
ctx := store.WithImageStats(context.Background(), stats)
if _, err := s.AddImage(ctx, tag.Name(), "", false, "", false, "", remoteOpts...); err != nil {
t.Fatalf("AddImage: %v", err)
}
if got := stats.Layers.Load(); got != int64(numLayers) {
t.Errorf("stats.Layers = %d, want %d", got, numLayers)
}
if got := stats.Bytes.Load(); got != wantBytes {
t.Errorf("stats.Bytes = %d, want %d", got, wantBytes)
}
}
// TestAddImage_NoImageStatsInContext proves AddImage works fine (no panic)
// when the context has no ImageStats attached -- the common case for every
// call site that doesn't care about stats.
func TestAddImage_NoImageStatsInContext(t *testing.T) {
srv := httptest.NewServer(registry.New())
t.Cleanup(srv.Close)
host := strings.TrimPrefix(srv.URL, "http://")
remoteOpts := []remote.Option{
remote.WithTransport(srv.Client().Transport),
}
img, err := random.Image(512, 1)
if err != nil {
t.Fatalf("random.Image: %v", err)
}
tag, err := gname.NewTag(host+"/test/image:v1", gname.Insecure)
if err != nil {
t.Fatalf("new tag: %v", err)
}
if err := remote.Write(tag, img, remoteOpts...); err != nil {
t.Fatalf("push image: %v", err)
}
s, err := store.NewLayout(t.TempDir())
if err != nil {
t.Fatalf("new layout: %v", err)
}
if _, err := s.AddImage(context.Background(), tag.Name(), "", false, "", false, "", remoteOpts...); err != nil {
t.Fatalf("AddImage: %v", err)
}
}