diff --git a/registry/handlers/api_test.go b/registry/handlers/api_test.go index dcbc1de6..07355bb1 100644 --- a/registry/handlers/api_test.go +++ b/registry/handlers/api_test.go @@ -30,7 +30,7 @@ import ( v2 "github.com/distribution/distribution/v3/registry/api/v2" storagedriver "github.com/distribution/distribution/v3/registry/storage/driver" "github.com/distribution/distribution/v3/registry/storage/driver/factory" - _ "github.com/distribution/distribution/v3/registry/storage/driver/testdriver" + _ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" "github.com/distribution/distribution/v3/testutil" "github.com/docker/libtrust" "github.com/gorilla/handlers" @@ -385,7 +385,7 @@ func contains(elems []string, e string) bool { func TestURLPrefix(t *testing.T) { config := configuration.Configuration{ Storage: configuration.Storage{ - "testdriver": configuration.Parameters{}, + "inmemory": configuration.Parameters{}, "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ "enabled": false, }}, @@ -468,7 +468,7 @@ func TestBlobDelete(t *testing.T) { func TestRelativeURL(t *testing.T) { config := configuration.Configuration{ Storage: configuration.Storage{ - "testdriver": configuration.Parameters{}, + "inmemory": configuration.Parameters{}, "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ "enabled": false, }}, @@ -2290,8 +2290,8 @@ func newTestEnvMirror(t *testing.T, deleteEnabled bool) *testEnv { upstreamEnv := newTestEnv(t, deleteEnabled) config := configuration.Configuration{ Storage: configuration.Storage{ - "testdriver": configuration.Parameters{}, - "delete": configuration.Parameters{"enabled": deleteEnabled}, + "inmemory": configuration.Parameters{}, + "delete": configuration.Parameters{"enabled": deleteEnabled}, "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ "enabled": false, }}, @@ -2308,8 +2308,8 @@ func newTestEnvMirror(t *testing.T, deleteEnabled bool) *testEnv { func newTestEnv(t *testing.T, deleteEnabled bool) *testEnv { config := configuration.Configuration{ Storage: configuration.Storage{ - "testdriver": configuration.Parameters{}, - "delete": configuration.Parameters{"enabled": deleteEnabled}, + "inmemory": configuration.Parameters{}, + "delete": configuration.Parameters{"enabled": deleteEnabled}, "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ "enabled": false, }}, @@ -2830,7 +2830,7 @@ func TestRegistryAsCacheMutationAPIs(t *testing.T) { func TestProxyManifestGetByTag(t *testing.T) { truthConfig := configuration.Configuration{ Storage: configuration.Storage{ - "testdriver": configuration.Parameters{}, + "inmemory": configuration.Parameters{}, "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ "enabled": false, }}, @@ -2849,7 +2849,7 @@ func TestProxyManifestGetByTag(t *testing.T) { proxyConfig := configuration.Configuration{ Storage: configuration.Storage{ - "testdriver": configuration.Parameters{}, + "inmemory": configuration.Parameters{}, }, Proxy: configuration.Proxy{ RemoteURL: truthEnv.server.URL, diff --git a/registry/handlers/app_test.go b/registry/handlers/app_test.go index 09a5d7e8..408d76b9 100644 --- a/registry/handlers/app_test.go +++ b/registry/handlers/app_test.go @@ -16,7 +16,7 @@ import ( _ "github.com/distribution/distribution/v3/registry/auth/silly" "github.com/distribution/distribution/v3/registry/storage" memorycache "github.com/distribution/distribution/v3/registry/storage/cache/memory" - "github.com/distribution/distribution/v3/registry/storage/driver/testdriver" + "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" ) // TestAppDispatcher builds an application with a test dispatcher and ensures @@ -24,7 +24,7 @@ import ( // This only tests the dispatch mechanism. The underlying dispatchers must be // tested individually. func TestAppDispatcher(t *testing.T) { - driver := testdriver.New() + driver := inmemory.New() ctx := context.Background() registry, err := storage.NewRegistry(ctx, driver, storage.BlobDescriptorCacheProvider(memorycache.NewInMemoryBlobDescriptorCacheProvider(0)), storage.EnableDelete, storage.EnableRedirect) if err != nil { @@ -141,7 +141,7 @@ func TestNewApp(t *testing.T) { ctx := context.Background() config := configuration.Configuration{ Storage: configuration.Storage{ - "testdriver": nil, + "inmemory": nil, "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ "enabled": false, }}, diff --git a/registry/storage/blob_test.go b/registry/storage/blob_test.go index 6df9e700..01158255 100644 --- a/registry/storage/blob_test.go +++ b/registry/storage/blob_test.go @@ -13,7 +13,7 @@ import ( "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/testdriver" + "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" "github.com/distribution/distribution/v3/testutil" "github.com/opencontainers/go-digest" ) @@ -23,7 +23,7 @@ import ( func TestWriteSeek(t *testing.T) { ctx := context.Background() imageName, _ := reference.WithName("foo/bar") - driver := testdriver.New() + driver := inmemory.New() registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect) if err != nil { t.Fatalf("error creating registry: %v", err) @@ -57,7 +57,7 @@ func TestSimpleBlobUpload(t *testing.T) { ctx := context.Background() imageName, _ := reference.WithName("foo/bar") - driver := testdriver.New() + driver := inmemory.New() registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect) if err != nil { t.Fatalf("error creating registry: %v", err) @@ -251,7 +251,7 @@ func TestSimpleBlobUpload(t *testing.T) { func TestSimpleBlobRead(t *testing.T) { ctx := context.Background() imageName, _ := reference.WithName("foo/bar") - driver := testdriver.New() + driver := inmemory.New() registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect) if err != nil { t.Fatalf("error creating registry: %v", err) @@ -363,7 +363,7 @@ func TestBlobMount(t *testing.T) { ctx := context.Background() imageName, _ := reference.WithName("foo/bar") sourceImageName, _ := reference.WithName("foo/source") - driver := testdriver.New() + driver := inmemory.New() registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect) if err != nil { t.Fatalf("error creating registry: %v", err) @@ -513,7 +513,7 @@ func TestBlobMount(t *testing.T) { func TestLayerUploadZeroLength(t *testing.T) { ctx := context.Background() imageName, _ := reference.WithName("foo/bar") - driver := testdriver.New() + driver := inmemory.New() registry, err := NewRegistry(ctx, driver, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider(memory.UnlimitedSize)), EnableDelete, EnableRedirect) if err != nil { t.Fatalf("error creating registry: %v", err) diff --git a/registry/storage/driver/inmemory/driver.go b/registry/storage/driver/inmemory/driver.go index f112fadc..6370ca63 100644 --- a/registry/storage/driver/inmemory/driver.go +++ b/registry/storage/driver/inmemory/driver.go @@ -251,6 +251,8 @@ func (d *driver) Walk(ctx context.Context, path string, f storagedriver.WalkFn) type writer struct { d *driver f *file + buffer []byte + buffSize int closed bool committed bool cancelled bool @@ -274,8 +276,17 @@ func (w *writer) Write(p []byte) (int, error) { w.d.mutex.Lock() defer w.d.mutex.Unlock() + if cap(w.buffer) < len(p)+w.buffSize { + data := make([]byte, len(w.buffer), len(p)+w.buffSize) + copy(data, w.buffer) + w.buffer = data + } - return w.f.WriteAt(p, int64(len(w.f.data))) + w.buffer = w.buffer[:w.buffSize+len(p)] + n := copy(w.buffer[w.buffSize:w.buffSize+len(p)], p) + w.buffSize += n + + return n, nil } func (w *writer) Size() int64 { @@ -290,6 +301,8 @@ func (w *writer) Close() error { return fmt.Errorf("already closed") } w.closed = true + w.flush() + return nil } @@ -316,5 +329,16 @@ func (w *writer) Commit() error { return fmt.Errorf("already cancelled") } w.committed = true + w.flush() + return nil } + +func (w *writer) flush() { + w.d.mutex.Lock() + defer w.d.mutex.Unlock() + + w.f.WriteAt(w.buffer, int64(len(w.f.data))) + w.buffer = []byte{} + w.buffSize = 0 +} diff --git a/registry/storage/driver/testdriver/testdriver.go b/registry/storage/driver/testdriver/testdriver.go deleted file mode 100644 index 63ed3e68..00000000 --- a/registry/storage/driver/testdriver/testdriver.go +++ /dev/null @@ -1,72 +0,0 @@ -package testdriver - -import ( - "context" - - storagedriver "github.com/distribution/distribution/v3/registry/storage/driver" - "github.com/distribution/distribution/v3/registry/storage/driver/factory" - "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" -) - -const driverName = "testdriver" - -func init() { - factory.Register(driverName, &testDriverFactory{}) -} - -// testDriverFactory implements the factory.StorageDriverFactory interface. -type testDriverFactory struct{} - -func (factory *testDriverFactory) Create(parameters map[string]interface{}) (storagedriver.StorageDriver, error) { - return New(), nil -} - -// TestDriver is a StorageDriver for testing purposes. The Writer returned by this driver -// simulates the case where Write operations are buffered. This causes the value returned by Size to lag -// behind until Close (or Commit, or Cancel) is called. -type TestDriver struct { - storagedriver.StorageDriver -} - -type testFileWriter struct { - storagedriver.FileWriter - prevchunk []byte -} - -var _ storagedriver.StorageDriver = &TestDriver{} - -// New constructs a new StorageDriver for testing purposes. The Writer returned by this driver -// simulates the case where Write operations are buffered. This causes the value returned by Size to lag -// behind until Close (or Commit, or Cancel) is called. -func New() *TestDriver { - return &TestDriver{StorageDriver: inmemory.New()} -} - -// Writer returns a FileWriter which will store the content written to it -// at the location designated by "path" after the call to Commit. -func (td *TestDriver) Writer(ctx context.Context, path string, append bool) (storagedriver.FileWriter, error) { - fw, err := td.StorageDriver.Writer(ctx, path, append) - return &testFileWriter{FileWriter: fw}, err -} - -func (tfw *testFileWriter) Write(p []byte) (int, error) { - _, err := tfw.FileWriter.Write(tfw.prevchunk) - tfw.prevchunk = make([]byte, len(p)) - copy(tfw.prevchunk, p) - return len(p), err -} - -func (tfw *testFileWriter) Close() error { - tfw.Write(nil) - return tfw.FileWriter.Close() -} - -func (tfw *testFileWriter) Cancel(ctx context.Context) error { - tfw.Write(nil) - return tfw.FileWriter.Cancel(ctx) -} - -func (tfw *testFileWriter) Commit() error { - tfw.Write(nil) - return tfw.FileWriter.Commit() -}