forked from TrueCloudLab/distribution
230cc72a8b
Signed-off-by: Milos Gajdos <milosgajdos83@gmail.com> Signed-off-by: David van der Spek <vanderspek.david@gmail.com>
242 lines
5.5 KiB
Go
242 lines
5.5 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"testing"
|
|
|
|
"github.com/distribution/distribution/v3"
|
|
"github.com/distribution/distribution/v3/reference"
|
|
"github.com/distribution/distribution/v3/registry/storage/cache/memory"
|
|
"github.com/distribution/distribution/v3/registry/storage/driver"
|
|
"github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
|
|
"github.com/distribution/distribution/v3/testutil"
|
|
"github.com/opencontainers/go-digest"
|
|
)
|
|
|
|
type setupEnv struct {
|
|
ctx context.Context
|
|
driver driver.StorageDriver
|
|
expected []string
|
|
registry distribution.Namespace
|
|
}
|
|
|
|
func setupFS(t *testing.T) *setupEnv {
|
|
d := inmemory.New()
|
|
ctx := context.Background()
|
|
registry, err := NewRegistry(ctx, d, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableRedirect, EnableSchema1)
|
|
if err != nil {
|
|
t.Fatalf("error creating registry: %v", err)
|
|
}
|
|
|
|
repos := []string{
|
|
"foo/a",
|
|
"foo/b",
|
|
"foo-bar/a",
|
|
"bar/c",
|
|
"bar/d",
|
|
"bar/e",
|
|
"foo/d/in",
|
|
"foo-bar/b",
|
|
"test",
|
|
}
|
|
|
|
for _, repo := range repos {
|
|
makeRepo(ctx, t, repo, registry)
|
|
}
|
|
|
|
expected := []string{
|
|
"bar/c",
|
|
"bar/d",
|
|
"bar/e",
|
|
"foo/a",
|
|
"foo/b",
|
|
"foo/d/in",
|
|
"foo-bar/a",
|
|
"foo-bar/b",
|
|
"test",
|
|
}
|
|
|
|
return &setupEnv{
|
|
ctx: ctx,
|
|
driver: d,
|
|
expected: expected,
|
|
registry: registry,
|
|
}
|
|
}
|
|
|
|
func makeRepo(ctx context.Context, t *testing.T, name string, reg distribution.Namespace) {
|
|
named, err := reference.WithName(name)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
repo, _ := reg.Repository(ctx, named)
|
|
manifests, _ := repo.Manifests(ctx)
|
|
|
|
layers, err := testutil.CreateRandomLayers(1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = testutil.UploadBlobs(repo, layers)
|
|
if err != nil {
|
|
t.Fatalf("failed to upload layers: %v", err)
|
|
}
|
|
|
|
getKeys := func(digests map[digest.Digest]io.ReadSeeker) (ds []digest.Digest) {
|
|
for d := range digests {
|
|
ds = append(ds, d)
|
|
}
|
|
return
|
|
}
|
|
|
|
manifest, err := testutil.MakeSchema1Manifest(getKeys(layers)) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err = manifests.Put(ctx, manifest)
|
|
if err != nil {
|
|
t.Fatalf("manifest upload failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCatalog(t *testing.T) {
|
|
env := setupFS(t)
|
|
|
|
p := make([]string, 50)
|
|
|
|
numFilled, err := env.registry.Repositories(env.ctx, p, "")
|
|
if numFilled != len(env.expected) {
|
|
t.Errorf("missing items in catalog")
|
|
}
|
|
|
|
if !testEq(p, env.expected, len(env.expected)) {
|
|
t.Errorf("Expected catalog repos err")
|
|
}
|
|
|
|
if err != io.EOF {
|
|
t.Errorf("Catalog has more values which we aren't expecting")
|
|
}
|
|
}
|
|
|
|
func TestCatalogInParts(t *testing.T) {
|
|
env := setupFS(t)
|
|
|
|
chunkLen := 3
|
|
p := make([]string, chunkLen)
|
|
|
|
numFilled, err := env.registry.Repositories(env.ctx, p, "")
|
|
if err == io.EOF || numFilled != len(p) {
|
|
t.Errorf("Expected more values in catalog")
|
|
}
|
|
|
|
if !testEq(p, env.expected[0:chunkLen], numFilled) {
|
|
t.Errorf("Expected catalog first chunk err")
|
|
}
|
|
|
|
lastRepo := p[len(p)-1]
|
|
numFilled, err = env.registry.Repositories(env.ctx, p, lastRepo)
|
|
|
|
if err == io.EOF || numFilled != len(p) {
|
|
t.Errorf("Expected more values in catalog")
|
|
}
|
|
|
|
if !testEq(p, env.expected[chunkLen:chunkLen*2], numFilled) {
|
|
t.Errorf("Expected catalog second chunk err")
|
|
}
|
|
|
|
lastRepo = p[len(p)-1]
|
|
numFilled, err = env.registry.Repositories(env.ctx, p, lastRepo)
|
|
|
|
if err != io.EOF || numFilled != len(p) {
|
|
t.Errorf("Expected end of catalog")
|
|
}
|
|
|
|
if !testEq(p, env.expected[chunkLen*2:chunkLen*3], numFilled) {
|
|
t.Errorf("Expected catalog third chunk err")
|
|
}
|
|
|
|
lastRepo = p[len(p)-1]
|
|
numFilled, err = env.registry.Repositories(env.ctx, p, lastRepo)
|
|
|
|
if err != io.EOF {
|
|
t.Errorf("Catalog has more values which we aren't expecting")
|
|
}
|
|
|
|
if numFilled != 0 {
|
|
t.Errorf("Expected catalog fourth chunk err")
|
|
}
|
|
}
|
|
|
|
func TestCatalogEnumerate(t *testing.T) {
|
|
env := setupFS(t)
|
|
|
|
var repos []string
|
|
repositoryEnumerator := env.registry.(distribution.RepositoryEnumerator)
|
|
err := repositoryEnumerator.Enumerate(env.ctx, func(repoName string) error {
|
|
repos = append(repos, repoName)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Errorf("Expected catalog enumerate err")
|
|
}
|
|
|
|
if len(repos) != len(env.expected) {
|
|
t.Errorf("Expected catalog enumerate doesn't have correct number of values")
|
|
}
|
|
|
|
if !testEq(repos, env.expected, len(env.expected)) {
|
|
t.Errorf("Expected catalog enumerate not over all values")
|
|
}
|
|
}
|
|
|
|
func testEq(a, b []string, size int) bool {
|
|
for cnt := 0; cnt < size-1; cnt++ {
|
|
if a[cnt] != b[cnt] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func setupBadWalkEnv(t *testing.T) *setupEnv {
|
|
d := newBadListDriver()
|
|
ctx := context.Background()
|
|
registry, err := NewRegistry(ctx, d, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableRedirect, EnableSchema1)
|
|
if err != nil {
|
|
t.Fatalf("error creating registry: %v", err)
|
|
}
|
|
|
|
return &setupEnv{
|
|
ctx: ctx,
|
|
driver: d,
|
|
registry: registry,
|
|
}
|
|
}
|
|
|
|
type badListDriver struct {
|
|
driver.StorageDriver
|
|
}
|
|
|
|
var _ driver.StorageDriver = &badListDriver{}
|
|
|
|
func newBadListDriver() *badListDriver {
|
|
return &badListDriver{StorageDriver: inmemory.New()}
|
|
}
|
|
|
|
func (d *badListDriver) List(ctx context.Context, path string) ([]string, error) {
|
|
return nil, fmt.Errorf("List error")
|
|
}
|
|
|
|
func TestCatalogWalkError(t *testing.T) {
|
|
env := setupBadWalkEnv(t)
|
|
p := make([]string, 1)
|
|
|
|
_, err := env.registry.Repositories(env.ctx, p, "")
|
|
if err == io.EOF {
|
|
t.Errorf("Expected catalog driver list error")
|
|
}
|
|
}
|