Przeglądaj źródła

Merge pull request #36584 from cpuguy83/volume_store_tests

Add some tests to the volume store
Vincent Demeester 7 lat temu
rodzic
commit
bbf568e41c

+ 0 - 2
integration/volume/volume_test.go

@@ -34,7 +34,6 @@ func TestVolumesCreateAndList(t *testing.T) {
 		Driver:     "local",
 		Scope:      "local",
 		Name:       name,
-		Options:    map[string]string{},
 		Mountpoint: fmt.Sprintf("%s/volumes/%s/_data", testEnv.DaemonInfo.DockerRootDir, name),
 	}
 	assert.Equal(t, vol, expected)
@@ -95,7 +94,6 @@ func TestVolumesInspect(t *testing.T) {
 		Driver:     "local",
 		Scope:      "local",
 		Name:       name,
-		Options:    map[string]string{},
 		Mountpoint: fmt.Sprintf("%s/volumes/%s/_data", testEnv.DaemonInfo.DockerRootDir, name),
 	}
 	assert.Equal(t, vol, expected)

+ 9 - 2
volume/store/db.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 
 	"github.com/boltdb/bolt"
+	"github.com/docker/docker/errdefs"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 )
@@ -28,7 +29,10 @@ func setMeta(tx *bolt.Tx, name string, meta volumeMetadata) error {
 	if err != nil {
 		return err
 	}
-	b := tx.Bucket(volumeBucketName)
+	b, err := tx.CreateBucketIfNotExists(volumeBucketName)
+	if err != nil {
+		return errors.Wrap(err, "error creating volume bucket")
+	}
 	return errors.Wrap(b.Put([]byte(name), metaJSON), "error setting volume metadata")
 }
 
@@ -42,8 +46,11 @@ func (s *VolumeStore) getMeta(name string) (volumeMetadata, error) {
 
 func getMeta(tx *bolt.Tx, name string, meta *volumeMetadata) error {
 	b := tx.Bucket(volumeBucketName)
+	if b == nil {
+		return errdefs.NotFound(errors.New("volume bucket does not exist"))
+	}
 	val := b.Get([]byte(name))
-	if string(val) == "" {
+	if len(val) == 0 {
 		return nil
 	}
 	if err := json.Unmarshal(val, meta); err != nil {

+ 51 - 0
volume/store/db_test.go

@@ -0,0 +1,51 @@
+package store
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"testing"
+	"time"
+
+	"github.com/boltdb/bolt"
+	"github.com/stretchr/testify/require"
+)
+
+func TestSetGetMeta(t *testing.T) {
+	t.Parallel()
+
+	dir, err := ioutil.TempDir("", "test-set-get")
+	require.NoError(t, err)
+	defer os.RemoveAll(dir)
+
+	db, err := bolt.Open(filepath.Join(dir, "db"), 0600, &bolt.Options{Timeout: 1 * time.Second})
+	require.NoError(t, err)
+
+	store := &VolumeStore{db: db}
+
+	_, err = store.getMeta("test")
+	require.Error(t, err)
+
+	err = db.Update(func(tx *bolt.Tx) error {
+		_, err := tx.CreateBucket(volumeBucketName)
+		return err
+	})
+	require.NoError(t, err)
+
+	meta, err := store.getMeta("test")
+	require.NoError(t, err)
+	require.Equal(t, volumeMetadata{}, meta)
+
+	testMeta := volumeMetadata{
+		Name:    "test",
+		Driver:  "fake",
+		Labels:  map[string]string{"a": "1", "b": "2"},
+		Options: map[string]string{"foo": "bar"},
+	}
+	err = store.setMeta("test", testMeta)
+	require.NoError(t, err)
+
+	meta, err = store.getMeta("test")
+	require.NoError(t, err)
+	require.Equal(t, testMeta, meta)
+}

+ 55 - 0
volume/store/restore_test.go

@@ -0,0 +1,55 @@
+package store
+
+import (
+	"io/ioutil"
+	"os"
+	"testing"
+
+	"github.com/docker/docker/volume"
+	volumedrivers "github.com/docker/docker/volume/drivers"
+	volumetestutils "github.com/docker/docker/volume/testutils"
+	"github.com/stretchr/testify/require"
+)
+
+func TestRestore(t *testing.T) {
+	t.Parallel()
+
+	dir, err := ioutil.TempDir("", "test-restore")
+	require.NoError(t, err)
+	defer os.RemoveAll(dir)
+
+	driverName := "test-restore"
+	volumedrivers.Register(volumetestutils.NewFakeDriver(driverName), driverName)
+	defer volumedrivers.Unregister("test-restore")
+
+	s, err := New(dir)
+	require.NoError(t, err)
+	defer s.Shutdown()
+
+	_, err = s.Create("test1", driverName, nil, nil)
+	require.NoError(t, err)
+
+	testLabels := map[string]string{"a": "1"}
+	testOpts := map[string]string{"foo": "bar"}
+	_, err = s.Create("test2", driverName, testOpts, testLabels)
+	require.NoError(t, err)
+
+	s.Shutdown()
+
+	s, err = New(dir)
+	require.NoError(t, err)
+
+	v, err := s.Get("test1")
+	require.NoError(t, err)
+
+	dv := v.(volume.DetailedVolume)
+	var nilMap map[string]string
+	require.Equal(t, nilMap, dv.Options())
+	require.Equal(t, nilMap, dv.Labels())
+
+	v, err = s.Get("test2")
+	require.NoError(t, err)
+	dv = v.(volume.DetailedVolume)
+	require.Equal(t, testOpts, dv.Options())
+	require.Equal(t, testLabels, dv.Labels())
+}

+ 13 - 2
volume/store/store.go

@@ -29,7 +29,10 @@ type volumeWrapper struct {
 }
 
 func (v volumeWrapper) Options() map[string]string {
-	options := map[string]string{}
+	if v.options == nil {
+		return nil
+	}
+	options := make(map[string]string, len(v.options))
 	for key, value := range v.options {
 		options[key] = value
 	}
@@ -37,7 +40,15 @@ func (v volumeWrapper) Options() map[string]string {
 }
 
 func (v volumeWrapper) Labels() map[string]string {
-	return v.labels
+	if v.labels == nil {
+		return nil
+	}
+
+	labels := make(map[string]string, len(v.labels))
+	for key, value := range v.labels {
+		labels[key] = value
+	}
+	return labels
 }
 
 func (v volumeWrapper) Scope() string {

+ 103 - 0
volume/store/store_test.go

@@ -12,6 +12,8 @@ import (
 	"github.com/docker/docker/volume"
 	"github.com/docker/docker/volume/drivers"
 	volumetestutils "github.com/docker/docker/volume/testutils"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestCreate(t *testing.T) {
@@ -291,6 +293,7 @@ func TestDefererencePluginOnCreateError(t *testing.T) {
 
 	pg := volumetestutils.NewFakePluginGetter(p)
 	volumedrivers.RegisterPluginGetter(pg)
+	defer volumedrivers.RegisterPluginGetter(nil)
 
 	dir, err := ioutil.TempDir("", "test-plugin-deref-err")
 	if err != nil {
@@ -320,3 +323,103 @@ func TestDefererencePluginOnCreateError(t *testing.T) {
 		t.Fatalf("expected 1 plugin reference, got: %d", refs)
 	}
 }
+
+func TestRefDerefRemove(t *testing.T) {
+	t.Parallel()
+
+	driverName := "test-ref-deref-remove"
+	s, cleanup := setupTest(t, driverName)
+	defer cleanup(t)
+
+	v, err := s.CreateWithRef("test", driverName, "test-ref", nil, nil)
+	require.NoError(t, err)
+
+	err = s.Remove(v)
+	require.Error(t, err)
+	require.Equal(t, errVolumeInUse, err.(*OpErr).Err)
+
+	s.Dereference(v, "test-ref")
+	err = s.Remove(v)
+	require.NoError(t, err)
+}
+
+func TestGet(t *testing.T) {
+	t.Parallel()
+
+	driverName := "test-get"
+	s, cleanup := setupTest(t, driverName)
+	defer cleanup(t)
+
+	_, err := s.Get("not-exist")
+	require.Error(t, err)
+	require.Equal(t, errNoSuchVolume, err.(*OpErr).Err)
+
+	v1, err := s.Create("test", driverName, nil, map[string]string{"a": "1"})
+	require.NoError(t, err)
+
+	v2, err := s.Get("test")
+	require.NoError(t, err)
+	require.Equal(t, v1, v2)
+
+	dv := v2.(volume.DetailedVolume)
+	require.Equal(t, "1", dv.Labels()["a"])
+
+	err = s.Remove(v1)
+	require.NoError(t, err)
+}
+
+func TestGetWithRef(t *testing.T) {
+	t.Parallel()
+
+	driverName := "test-get-with-ref"
+	s, cleanup := setupTest(t, driverName)
+	defer cleanup(t)
+
+	_, err := s.GetWithRef("not-exist", driverName, "test-ref")
+	require.Error(t, err)
+
+	v1, err := s.Create("test", driverName, nil, map[string]string{"a": "1"})
+	require.NoError(t, err)
+
+	v2, err := s.GetWithRef("test", driverName, "test-ref")
+	require.NoError(t, err)
+	require.Equal(t, v1, v2)
+
+	err = s.Remove(v2)
+	require.Error(t, err)
+	require.Equal(t, errVolumeInUse, err.(*OpErr).Err)
+
+	s.Dereference(v2, "test-ref")
+	err = s.Remove(v2)
+	require.NoError(t, err)
+}
+
+func setupTest(t *testing.T, name string) (*VolumeStore, func(*testing.T)) {
+	t.Helper()
+	s, cleanup := newTestStore(t)
+
+	volumedrivers.Register(volumetestutils.NewFakeDriver(name), name)
+	return s, func(t *testing.T) {
+		cleanup(t)
+		volumedrivers.Unregister(name)
+	}
+}
+
+func newTestStore(t *testing.T) (*VolumeStore, func(*testing.T)) {
+	t.Helper()
+
+	dir, err := ioutil.TempDir("", "store-root")
+	require.NoError(t, err)
+
+	cleanup := func(t *testing.T) {
+		err := os.RemoveAll(dir)
+		assert.NoError(t, err)
+	}
+
+	s, err := New(dir)
+	assert.NoError(t, err)
+	return s, func(t *testing.T) {
+		s.Shutdown()
+		cleanup(t)
+	}
+}