Browse code

volume/local: add tests for size quota

Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>

Timo Rothenpieler authored on 2020/08/11 06:05:07
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,97 @@
0
+// +build linux
1
+
2
+package local // import "github.com/docker/docker/volume/local"
3
+
4
+import (
5
+	"io/ioutil"
6
+	"os"
7
+	"path/filepath"
8
+	"testing"
9
+
10
+	"github.com/docker/docker/pkg/idtools"
11
+	"github.com/docker/docker/quota"
12
+	"gotest.tools/v3/assert"
13
+	is "gotest.tools/v3/assert/cmp"
14
+)
15
+
16
+const quotaSize = 1024 * 1024
17
+const quotaSizeLiteral = "1M"
18
+
19
+func TestQuota(t *testing.T) {
20
+	if msg, ok := quota.CanTestQuota(); !ok {
21
+		t.Skip(msg)
22
+	}
23
+
24
+	// get sparse xfs test image
25
+	imageFileName, err := quota.PrepareQuotaTestImage(t)
26
+	if err != nil {
27
+		t.Fatal(err)
28
+	}
29
+	defer os.Remove(imageFileName)
30
+
31
+	t.Run("testVolWithQuota", quota.WrapMountTest(imageFileName, true, testVolWithQuota))
32
+	t.Run("testVolQuotaUnsupported", quota.WrapMountTest(imageFileName, false, testVolQuotaUnsupported))
33
+}
34
+
35
+func testVolWithQuota(t *testing.T, mountPoint, backingFsDev, testDir string) {
36
+	r, err := New(testDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
37
+	if err != nil {
38
+		t.Fatal(err)
39
+	}
40
+	assert.Assert(t, r.quotaCtl != nil)
41
+
42
+	vol, err := r.Create("testing", map[string]string{"size": quotaSizeLiteral})
43
+	if err != nil {
44
+		t.Fatal(err)
45
+	}
46
+
47
+	dir, err := vol.Mount("1234")
48
+	if err != nil {
49
+		t.Fatal(err)
50
+	}
51
+	defer func() {
52
+		if err := vol.Unmount("1234"); err != nil {
53
+			t.Fatal(err)
54
+		}
55
+	}()
56
+
57
+	testfile := filepath.Join(dir, "testfile")
58
+
59
+	// test writing file smaller than quota
60
+	assert.NilError(t, ioutil.WriteFile(testfile, make([]byte, quotaSize/2), 0644))
61
+	assert.NilError(t, os.Remove(testfile))
62
+
63
+	// test writing fiel larger than quota
64
+	err = ioutil.WriteFile(testfile, make([]byte, quotaSize+1), 0644)
65
+	assert.ErrorContains(t, err, "")
66
+	if _, err := os.Stat(testfile); err == nil {
67
+		assert.NilError(t, os.Remove(testfile))
68
+	}
69
+}
70
+
71
+func testVolQuotaUnsupported(t *testing.T, mountPoint, backingFsDev, testDir string) {
72
+	r, err := New(testDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
73
+	if err != nil {
74
+		t.Fatal(err)
75
+	}
76
+	assert.Assert(t, is.Nil(r.quotaCtl))
77
+
78
+	_, err = r.Create("testing", map[string]string{"size": quotaSizeLiteral})
79
+	assert.ErrorContains(t, err, "no quota support")
80
+
81
+	vol, err := r.Create("testing", nil)
82
+	if err != nil {
83
+		t.Fatal(err)
84
+	}
85
+
86
+	// this could happen if someone moves volumes from storage with
87
+	// quota support to some place without
88
+	lv, ok := vol.(*localVolume)
89
+	assert.Assert(t, ok)
90
+	lv.opts = &optsConfig{
91
+		Quota: quota.Quota{Size: quotaSize},
92
+	}
93
+
94
+	_, err = vol.Mount("1234")
95
+	assert.ErrorContains(t, err, "no quota support")
96
+}