2020-10-30 15:47:06 -04:00
|
|
|
package images
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/containerd/containerd/content"
|
|
|
|
"github.com/containerd/containerd/content/local"
|
|
|
|
c8derrdefs "github.com/containerd/containerd/errdefs"
|
|
|
|
"github.com/containerd/containerd/leases"
|
|
|
|
"github.com/containerd/containerd/metadata"
|
|
|
|
"github.com/containerd/containerd/namespaces"
|
|
|
|
"github.com/docker/docker/image"
|
|
|
|
digest "github.com/opencontainers/go-digest"
|
|
|
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
|
|
|
"go.etcd.io/bbolt"
|
|
|
|
"gotest.tools/v3/assert"
|
|
|
|
"gotest.tools/v3/assert/cmp"
|
|
|
|
)
|
|
|
|
|
|
|
|
func setupTestStores(t *testing.T) (context.Context, content.Store, *imageStoreWithLease, func(t *testing.T)) {
|
2021-08-24 06:10:50 -04:00
|
|
|
dir, err := os.MkdirTemp("", t.Name())
|
2020-10-30 15:47:06 -04:00
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
backend, err := image.NewFSStoreBackend(filepath.Join(dir, "images"))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
is, err := image.NewImageStore(backend, nil)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
db, err := bbolt.Open(filepath.Join(dir, "metadata.db"), 0600, nil)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
cs, err := local.NewStore(filepath.Join(dir, "content"))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
mdb := metadata.NewDB(db, cs, nil)
|
|
|
|
|
|
|
|
cleanup := func(t *testing.T) {
|
|
|
|
assert.Check(t, db.Close())
|
|
|
|
assert.Check(t, os.RemoveAll(dir))
|
|
|
|
}
|
|
|
|
ctx := namespaces.WithNamespace(context.Background(), t.Name())
|
|
|
|
images := &imageStoreWithLease{Store: is, ns: t.Name(), leases: metadata.NewLeaseManager(mdb)}
|
|
|
|
|
|
|
|
return ctx, cs, images, cleanup
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestImageDelete(t *testing.T) {
|
|
|
|
ctx, _, images, cleanup := setupTestStores(t)
|
|
|
|
defer cleanup(t)
|
|
|
|
|
|
|
|
t.Run("no lease", func(t *testing.T) {
|
|
|
|
id, err := images.Create([]byte(`{"rootFS": {}}`))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
defer images.Delete(id)
|
|
|
|
|
|
|
|
ls, err := images.leases.List(ctx)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
assert.Equal(t, len(ls), 0, ls)
|
|
|
|
|
|
|
|
_, err = images.Delete(id)
|
|
|
|
assert.NilError(t, err, "should not error when there is no lease")
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("lease exists", func(t *testing.T) {
|
|
|
|
id, err := images.Create([]byte(`{"rootFS": {}}`))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
defer images.Delete(id)
|
|
|
|
|
|
|
|
leaseID := imageKey(digest.Digest(id))
|
|
|
|
_, err = images.leases.Create(ctx, leases.WithID(leaseID))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
defer images.leases.Delete(ctx, leases.Lease{ID: leaseID})
|
|
|
|
|
|
|
|
ls, err := images.leases.List(ctx)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
assert.Check(t, cmp.Equal(len(ls), 1), ls)
|
|
|
|
|
|
|
|
_, err = images.Delete(id)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
ls, err = images.leases.List(ctx)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
assert.Check(t, cmp.Equal(len(ls), 0), ls)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestContentStoreForPull(t *testing.T) {
|
|
|
|
ctx, cs, is, cleanup := setupTestStores(t)
|
|
|
|
defer cleanup(t)
|
|
|
|
|
|
|
|
csP := &contentStoreForPull{
|
|
|
|
ContentStore: cs,
|
|
|
|
leases: is.leases,
|
|
|
|
}
|
|
|
|
|
|
|
|
data := []byte(`{}`)
|
|
|
|
desc := v1.Descriptor{
|
|
|
|
Digest: digest.Canonical.FromBytes(data),
|
|
|
|
Size: int64(len(data)),
|
|
|
|
}
|
|
|
|
|
|
|
|
w, err := csP.Writer(ctx, content.WithRef(t.Name()), content.WithDescriptor(desc))
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
_, err = w.Write(data)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
defer w.Close()
|
|
|
|
|
|
|
|
err = w.Commit(ctx, desc.Size, desc.Digest)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, len(csP.digested), 1)
|
|
|
|
assert.Check(t, cmp.Equal(csP.digested[0], desc.Digest))
|
|
|
|
|
|
|
|
// Test already exists
|
|
|
|
csP.digested = nil
|
|
|
|
_, err = csP.Writer(ctx, content.WithRef(t.Name()), content.WithDescriptor(desc))
|
|
|
|
assert.Check(t, c8derrdefs.IsAlreadyExists(err))
|
|
|
|
assert.Equal(t, len(csP.digested), 1)
|
|
|
|
assert.Check(t, cmp.Equal(csP.digested[0], desc.Digest))
|
|
|
|
}
|