diff --git a/content/local/store_test.go b/content/local/store_test.go index 47bb77a1f..4d7afe070 100644 --- a/content/local/store_test.go +++ b/content/local/store_test.go @@ -24,12 +24,14 @@ import ( ) func TestContent(t *testing.T) { - testsuite.ContentSuite(t, "fs", func(ctx context.Context, root string) (content.Store, func(), error) { + testsuite.ContentSuite(t, "fs", func(ctx context.Context, root string) (content.Store, func() error, error) { cs, err := NewStore(root) if err != nil { return nil, nil, err } - return cs, func() {}, nil + return cs, func() error { + return nil + }, nil }) } diff --git a/content/testsuite/testsuite.go b/content/testsuite/testsuite.go index c9f7de52d..afeb4d918 100644 --- a/content/testsuite/testsuite.go +++ b/content/testsuite/testsuite.go @@ -17,13 +17,13 @@ import ( "github.com/pkg/errors" ) -// ContentSuite runs a test suite on the snapshotter given a factory function. -func ContentSuite(t *testing.T, name string, storeFn func(ctx context.Context, root string) (content.Store, func(), error)) { +// ContentSuite runs a test suite on the content store given a factory function. +func ContentSuite(t *testing.T, name string, storeFn func(ctx context.Context, root string) (content.Store, func() error, error)) { t.Run("Writer", makeTest(t, name, storeFn, checkContentStoreWriter)) t.Run("UploadStatus", makeTest(t, name, storeFn, checkUploadStatus)) } -func makeTest(t *testing.T, name string, storeFn func(ctx context.Context, root string) (content.Store, func(), error), fn func(ctx context.Context, t *testing.T, cs content.Store)) func(t *testing.T) { +func makeTest(t *testing.T, name string, storeFn func(ctx context.Context, root string) (content.Store, func() error, error), fn func(ctx context.Context, t *testing.T, cs content.Store)) func(t *testing.T) { return func(t *testing.T) { ctx := namespaces.WithNamespace(context.Background(), name) @@ -37,7 +37,11 @@ func makeTest(t *testing.T, name string, storeFn func(ctx context.Context, root if err != nil { t.Fatal(err) } - defer cleanup() + defer func() { + if err := cleanup(); err != nil && !t.Failed() { + t.Fatalf("Cleanup failed: %+v", err) + } + }() defer testutil.DumpDir(t, tmpDir) fn(ctx, t, cs) diff --git a/content_test.go b/content_test.go new file mode 100644 index 000000000..6fc7818ae --- /dev/null +++ b/content_test.go @@ -0,0 +1,42 @@ +package containerd + +import ( + "context" + "testing" + + "github.com/containerd/containerd/content" + "github.com/containerd/containerd/content/testsuite" + "github.com/pkg/errors" +) + +func newContentStore(ctx context.Context, root string) (content.Store, func() error, error) { + client, err := New(address) + if err != nil { + return nil, nil, err + } + + cs := client.ContentStore() + + return cs, func() error { + statuses, err := cs.ListStatuses(ctx) + if err != nil { + return err + } + for _, st := range statuses { + if err := cs.Abort(ctx, st.Ref); err != nil { + return errors.Wrapf(err, "failed to abort %s", st.Ref) + } + } + return cs.Walk(ctx, func(info content.Info) error { + return cs.Delete(ctx, info.Digest) + }) + + }, nil +} + +func TestContentClient(t *testing.T) { + if testing.Short() { + t.Skip() + } + testsuite.ContentSuite(t, "ContentClient", newContentStore) +} diff --git a/metadata/content.go b/metadata/content.go index 8ad847f83..c0b3fc795 100644 --- a/metadata/content.go +++ b/metadata/content.go @@ -170,7 +170,7 @@ func (cs *contentStore) Delete(ctx context.Context, dgst digest.Digest) error { // Just remove local reference, garbage collector is responsible for // cleaning up on disk content - return getBlobsBucket(tx, ns).Delete([]byte(dgst.String())) + return getBlobsBucket(tx, ns).DeleteBucket([]byte(dgst.String())) }) } diff --git a/metadata/content_test.go b/metadata/content_test.go index 77ef293ce..093736833 100644 --- a/metadata/content_test.go +++ b/metadata/content_test.go @@ -11,21 +11,23 @@ import ( "github.com/containerd/containerd/content/testsuite" ) -func TestContent(t *testing.T) { - testsuite.ContentSuite(t, "metadata", func(ctx context.Context, root string) (content.Store, func(), error) { - // TODO: Use mocked or in-memory store - cs, err := local.NewStore(root) - if err != nil { - return nil, nil, err - } +func createContentStore(ctx context.Context, root string) (content.Store, func() error, error) { + // TODO: Use mocked or in-memory store + cs, err := local.NewStore(root) + if err != nil { + return nil, nil, err + } - db, err := bolt.Open(filepath.Join(root, "metadata.db"), 0660, nil) - if err != nil { - return nil, nil, err - } + db, err := bolt.Open(filepath.Join(root, "metadata.db"), 0660, nil) + if err != nil { + return nil, nil, err + } - return NewContentStore(db, cs), func() { - db.Close() - }, nil - }) + return NewContentStore(db, cs), func() error { + return db.Close() + }, nil +} + +func TestContent(t *testing.T) { + testsuite.ContentSuite(t, "metadata", createContentStore) } diff --git a/services/content/writer.go b/services/content/writer.go index eeb1fca3d..9a9c69a66 100644 --- a/services/content/writer.go +++ b/services/content/writer.go @@ -46,6 +46,7 @@ func (rw *remoteWriter) Status() (content.Status, error) { return content.Status{ Ref: rw.ref, Offset: resp.Offset, + Total: resp.Total, StartedAt: resp.StartedAt, UpdatedAt: resp.UpdatedAt, }, nil