Browse code

Add some tests to the volume store

Signed-off-by: Brian Goff <cpuguy83@gmail.com>

Brian Goff authored on 2018/03/14 04:39:23
Showing 6 changed files
... ...
@@ -34,7 +34,6 @@ func TestVolumesCreateAndList(t *testing.T) {
34 34
 		Driver:     "local",
35 35
 		Scope:      "local",
36 36
 		Name:       name,
37
-		Options:    map[string]string{},
38 37
 		Mountpoint: fmt.Sprintf("%s/volumes/%s/_data", testEnv.DaemonInfo.DockerRootDir, name),
39 38
 	}
40 39
 	assert.Equal(t, vol, expected)
... ...
@@ -95,7 +94,6 @@ func TestVolumesInspect(t *testing.T) {
95 95
 		Driver:     "local",
96 96
 		Scope:      "local",
97 97
 		Name:       name,
98
-		Options:    map[string]string{},
99 98
 		Mountpoint: fmt.Sprintf("%s/volumes/%s/_data", testEnv.DaemonInfo.DockerRootDir, name),
100 99
 	}
101 100
 	assert.Equal(t, vol, expected)
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"encoding/json"
5 5
 
6 6
 	"github.com/boltdb/bolt"
7
+	"github.com/docker/docker/errdefs"
7 8
 	"github.com/pkg/errors"
8 9
 	"github.com/sirupsen/logrus"
9 10
 )
... ...
@@ -28,7 +29,10 @@ func setMeta(tx *bolt.Tx, name string, meta volumeMetadata) error {
28 28
 	if err != nil {
29 29
 		return err
30 30
 	}
31
-	b := tx.Bucket(volumeBucketName)
31
+	b, err := tx.CreateBucketIfNotExists(volumeBucketName)
32
+	if err != nil {
33
+		return errors.Wrap(err, "error creating volume bucket")
34
+	}
32 35
 	return errors.Wrap(b.Put([]byte(name), metaJSON), "error setting volume metadata")
33 36
 }
34 37
 
... ...
@@ -42,8 +46,11 @@ func (s *VolumeStore) getMeta(name string) (volumeMetadata, error) {
42 42
 
43 43
 func getMeta(tx *bolt.Tx, name string, meta *volumeMetadata) error {
44 44
 	b := tx.Bucket(volumeBucketName)
45
+	if b == nil {
46
+		return errdefs.NotFound(errors.New("volume bucket does not exist"))
47
+	}
45 48
 	val := b.Get([]byte(name))
46
-	if string(val) == "" {
49
+	if len(val) == 0 {
47 50
 		return nil
48 51
 	}
49 52
 	if err := json.Unmarshal(val, meta); err != nil {
50 53
new file mode 100644
... ...
@@ -0,0 +1,51 @@
0
+package store
1
+
2
+import (
3
+	"io/ioutil"
4
+	"os"
5
+	"path/filepath"
6
+	"testing"
7
+	"time"
8
+
9
+	"github.com/boltdb/bolt"
10
+	"github.com/stretchr/testify/require"
11
+)
12
+
13
+func TestSetGetMeta(t *testing.T) {
14
+	t.Parallel()
15
+
16
+	dir, err := ioutil.TempDir("", "test-set-get")
17
+	require.NoError(t, err)
18
+	defer os.RemoveAll(dir)
19
+
20
+	db, err := bolt.Open(filepath.Join(dir, "db"), 0600, &bolt.Options{Timeout: 1 * time.Second})
21
+	require.NoError(t, err)
22
+
23
+	store := &VolumeStore{db: db}
24
+
25
+	_, err = store.getMeta("test")
26
+	require.Error(t, err)
27
+
28
+	err = db.Update(func(tx *bolt.Tx) error {
29
+		_, err := tx.CreateBucket(volumeBucketName)
30
+		return err
31
+	})
32
+	require.NoError(t, err)
33
+
34
+	meta, err := store.getMeta("test")
35
+	require.NoError(t, err)
36
+	require.Equal(t, volumeMetadata{}, meta)
37
+
38
+	testMeta := volumeMetadata{
39
+		Name:    "test",
40
+		Driver:  "fake",
41
+		Labels:  map[string]string{"a": "1", "b": "2"},
42
+		Options: map[string]string{"foo": "bar"},
43
+	}
44
+	err = store.setMeta("test", testMeta)
45
+	require.NoError(t, err)
46
+
47
+	meta, err = store.getMeta("test")
48
+	require.NoError(t, err)
49
+	require.Equal(t, testMeta, meta)
50
+}
0 51
new file mode 100644
... ...
@@ -0,0 +1,55 @@
0
+package store
1
+
2
+import (
3
+	"io/ioutil"
4
+	"os"
5
+	"testing"
6
+
7
+	"github.com/docker/docker/volume"
8
+	volumedrivers "github.com/docker/docker/volume/drivers"
9
+	volumetestutils "github.com/docker/docker/volume/testutils"
10
+	"github.com/stretchr/testify/require"
11
+)
12
+
13
+func TestRestore(t *testing.T) {
14
+	t.Parallel()
15
+
16
+	dir, err := ioutil.TempDir("", "test-restore")
17
+	require.NoError(t, err)
18
+	defer os.RemoveAll(dir)
19
+
20
+	driverName := "test-restore"
21
+	volumedrivers.Register(volumetestutils.NewFakeDriver(driverName), driverName)
22
+	defer volumedrivers.Unregister("test-restore")
23
+
24
+	s, err := New(dir)
25
+	require.NoError(t, err)
26
+	defer s.Shutdown()
27
+
28
+	_, err = s.Create("test1", driverName, nil, nil)
29
+	require.NoError(t, err)
30
+
31
+	testLabels := map[string]string{"a": "1"}
32
+	testOpts := map[string]string{"foo": "bar"}
33
+	_, err = s.Create("test2", driverName, testOpts, testLabels)
34
+	require.NoError(t, err)
35
+
36
+	s.Shutdown()
37
+
38
+	s, err = New(dir)
39
+	require.NoError(t, err)
40
+
41
+	v, err := s.Get("test1")
42
+	require.NoError(t, err)
43
+
44
+	dv := v.(volume.DetailedVolume)
45
+	var nilMap map[string]string
46
+	require.Equal(t, nilMap, dv.Options())
47
+	require.Equal(t, nilMap, dv.Labels())
48
+
49
+	v, err = s.Get("test2")
50
+	require.NoError(t, err)
51
+	dv = v.(volume.DetailedVolume)
52
+	require.Equal(t, testOpts, dv.Options())
53
+	require.Equal(t, testLabels, dv.Labels())
54
+}
... ...
@@ -29,7 +29,10 @@ type volumeWrapper struct {
29 29
 }
30 30
 
31 31
 func (v volumeWrapper) Options() map[string]string {
32
-	options := map[string]string{}
32
+	if v.options == nil {
33
+		return nil
34
+	}
35
+	options := make(map[string]string, len(v.options))
33 36
 	for key, value := range v.options {
34 37
 		options[key] = value
35 38
 	}
... ...
@@ -37,7 +40,15 @@ func (v volumeWrapper) Options() map[string]string {
37 37
 }
38 38
 
39 39
 func (v volumeWrapper) Labels() map[string]string {
40
-	return v.labels
40
+	if v.labels == nil {
41
+		return nil
42
+	}
43
+
44
+	labels := make(map[string]string, len(v.labels))
45
+	for key, value := range v.labels {
46
+		labels[key] = value
47
+	}
48
+	return labels
41 49
 }
42 50
 
43 51
 func (v volumeWrapper) Scope() string {
... ...
@@ -12,6 +12,8 @@ import (
12 12
 	"github.com/docker/docker/volume"
13 13
 	"github.com/docker/docker/volume/drivers"
14 14
 	volumetestutils "github.com/docker/docker/volume/testutils"
15
+	"github.com/stretchr/testify/assert"
16
+	"github.com/stretchr/testify/require"
15 17
 )
16 18
 
17 19
 func TestCreate(t *testing.T) {
... ...
@@ -291,6 +293,7 @@ func TestDefererencePluginOnCreateError(t *testing.T) {
291 291
 
292 292
 	pg := volumetestutils.NewFakePluginGetter(p)
293 293
 	volumedrivers.RegisterPluginGetter(pg)
294
+	defer volumedrivers.RegisterPluginGetter(nil)
294 295
 
295 296
 	dir, err := ioutil.TempDir("", "test-plugin-deref-err")
296 297
 	if err != nil {
... ...
@@ -320,3 +323,103 @@ func TestDefererencePluginOnCreateError(t *testing.T) {
320 320
 		t.Fatalf("expected 1 plugin reference, got: %d", refs)
321 321
 	}
322 322
 }
323
+
324
+func TestRefDerefRemove(t *testing.T) {
325
+	t.Parallel()
326
+
327
+	driverName := "test-ref-deref-remove"
328
+	s, cleanup := setupTest(t, driverName)
329
+	defer cleanup(t)
330
+
331
+	v, err := s.CreateWithRef("test", driverName, "test-ref", nil, nil)
332
+	require.NoError(t, err)
333
+
334
+	err = s.Remove(v)
335
+	require.Error(t, err)
336
+	require.Equal(t, errVolumeInUse, err.(*OpErr).Err)
337
+
338
+	s.Dereference(v, "test-ref")
339
+	err = s.Remove(v)
340
+	require.NoError(t, err)
341
+}
342
+
343
+func TestGet(t *testing.T) {
344
+	t.Parallel()
345
+
346
+	driverName := "test-get"
347
+	s, cleanup := setupTest(t, driverName)
348
+	defer cleanup(t)
349
+
350
+	_, err := s.Get("not-exist")
351
+	require.Error(t, err)
352
+	require.Equal(t, errNoSuchVolume, err.(*OpErr).Err)
353
+
354
+	v1, err := s.Create("test", driverName, nil, map[string]string{"a": "1"})
355
+	require.NoError(t, err)
356
+
357
+	v2, err := s.Get("test")
358
+	require.NoError(t, err)
359
+	require.Equal(t, v1, v2)
360
+
361
+	dv := v2.(volume.DetailedVolume)
362
+	require.Equal(t, "1", dv.Labels()["a"])
363
+
364
+	err = s.Remove(v1)
365
+	require.NoError(t, err)
366
+}
367
+
368
+func TestGetWithRef(t *testing.T) {
369
+	t.Parallel()
370
+
371
+	driverName := "test-get-with-ref"
372
+	s, cleanup := setupTest(t, driverName)
373
+	defer cleanup(t)
374
+
375
+	_, err := s.GetWithRef("not-exist", driverName, "test-ref")
376
+	require.Error(t, err)
377
+
378
+	v1, err := s.Create("test", driverName, nil, map[string]string{"a": "1"})
379
+	require.NoError(t, err)
380
+
381
+	v2, err := s.GetWithRef("test", driverName, "test-ref")
382
+	require.NoError(t, err)
383
+	require.Equal(t, v1, v2)
384
+
385
+	err = s.Remove(v2)
386
+	require.Error(t, err)
387
+	require.Equal(t, errVolumeInUse, err.(*OpErr).Err)
388
+
389
+	s.Dereference(v2, "test-ref")
390
+	err = s.Remove(v2)
391
+	require.NoError(t, err)
392
+}
393
+
394
+func setupTest(t *testing.T, name string) (*VolumeStore, func(*testing.T)) {
395
+	t.Helper()
396
+	s, cleanup := newTestStore(t)
397
+
398
+	volumedrivers.Register(volumetestutils.NewFakeDriver(name), name)
399
+	return s, func(t *testing.T) {
400
+		cleanup(t)
401
+		volumedrivers.Unregister(name)
402
+	}
403
+}
404
+
405
+func newTestStore(t *testing.T) (*VolumeStore, func(*testing.T)) {
406
+	t.Helper()
407
+
408
+	dir, err := ioutil.TempDir("", "store-root")
409
+	require.NoError(t, err)
410
+
411
+	cleanup := func(t *testing.T) {
412
+		err := os.RemoveAll(dir)
413
+		assert.NoError(t, err)
414
+	}
415
+
416
+	s, err := New(dir)
417
+	assert.NoError(t, err)
418
+	return s, func(t *testing.T) {
419
+		s.Shutdown()
420
+		cleanup(t)
421
+	}
422
+}