Add content test suite run to client

Fix bugs in content deletion and upload status

Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
Derek McGowan 2017-08-09 13:30:21 -07:00
parent edc51c86f2
commit c4387a159e
No known key found for this signature in database
GPG Key ID: F58C5D0A4405ACDB
6 changed files with 73 additions and 22 deletions

View File

@ -24,12 +24,14 @@ import (
) )
func TestContent(t *testing.T) { 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) cs, err := NewStore(root)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
return cs, func() {}, nil return cs, func() error {
return nil
}, nil
}) })
} }

View File

@ -17,13 +17,13 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// ContentSuite runs a test suite on the snapshotter given a factory function. // 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)) { 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("Writer", makeTest(t, name, storeFn, checkContentStoreWriter))
t.Run("UploadStatus", makeTest(t, name, storeFn, checkUploadStatus)) 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) { return func(t *testing.T) {
ctx := namespaces.WithNamespace(context.Background(), name) 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 { if err != nil {
t.Fatal(err) 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) defer testutil.DumpDir(t, tmpDir)
fn(ctx, t, cs) fn(ctx, t, cs)

42
content_test.go Normal file
View File

@ -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)
}

View File

@ -170,7 +170,7 @@ func (cs *contentStore) Delete(ctx context.Context, dgst digest.Digest) error {
// Just remove local reference, garbage collector is responsible for // Just remove local reference, garbage collector is responsible for
// cleaning up on disk content // cleaning up on disk content
return getBlobsBucket(tx, ns).Delete([]byte(dgst.String())) return getBlobsBucket(tx, ns).DeleteBucket([]byte(dgst.String()))
}) })
} }

View File

@ -11,21 +11,23 @@ import (
"github.com/containerd/containerd/content/testsuite" "github.com/containerd/containerd/content/testsuite"
) )
func TestContent(t *testing.T) { func createContentStore(ctx context.Context, root string) (content.Store, func() error, error) {
testsuite.ContentSuite(t, "metadata", func(ctx context.Context, root string) (content.Store, func(), error) { // TODO: Use mocked or in-memory store
// TODO: Use mocked or in-memory store cs, err := local.NewStore(root)
cs, err := local.NewStore(root) if err != nil {
if err != nil { return nil, nil, err
return nil, nil, err }
}
db, err := bolt.Open(filepath.Join(root, "metadata.db"), 0660, nil) db, err := bolt.Open(filepath.Join(root, "metadata.db"), 0660, nil)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
return NewContentStore(db, cs), func() { return NewContentStore(db, cs), func() error {
db.Close() return db.Close()
}, nil }, nil
}) }
func TestContent(t *testing.T) {
testsuite.ContentSuite(t, "metadata", createContentStore)
} }

View File

@ -46,6 +46,7 @@ func (rw *remoteWriter) Status() (content.Status, error) {
return content.Status{ return content.Status{
Ref: rw.ref, Ref: rw.ref,
Offset: resp.Offset, Offset: resp.Offset,
Total: resp.Total,
StartedAt: resp.StartedAt, StartedAt: resp.StartedAt,
UpdatedAt: resp.UpdatedAt, UpdatedAt: resp.UpdatedAt,
}, nil }, nil