1// +build !windows
2
3package mount // import "github.com/docker/docker/pkg/mount"
4
5import (
6	"os"
7	"path"
8	"testing"
9)
10
11func TestMountOptionsParsing(t *testing.T) {
12	options := "noatime,ro,size=10k"
13
14	flag, data := parseOptions(options)
15
16	if data != "size=10k" {
17		t.Fatalf("Expected size=10 got %s", data)
18	}
19
20	expectedFlag := NOATIME | RDONLY
21
22	if flag != expectedFlag {
23		t.Fatalf("Expected %d got %d", expectedFlag, flag)
24	}
25}
26
27func TestMounted(t *testing.T) {
28	if os.Getuid() != 0 {
29		t.Skip("root required")
30	}
31
32	tmp := path.Join(os.TempDir(), "mount-tests")
33	if err := os.MkdirAll(tmp, 0777); err != nil {
34		t.Fatal(err)
35	}
36	defer os.RemoveAll(tmp)
37
38	var (
39		sourceDir  = path.Join(tmp, "source")
40		targetDir  = path.Join(tmp, "target")
41		sourcePath = path.Join(sourceDir, "file.txt")
42		targetPath = path.Join(targetDir, "file.txt")
43	)
44
45	os.Mkdir(sourceDir, 0777)
46	os.Mkdir(targetDir, 0777)
47
48	f, err := os.Create(sourcePath)
49	if err != nil {
50		t.Fatal(err)
51	}
52	f.WriteString("hello")
53	f.Close()
54
55	f, err = os.Create(targetPath)
56	if err != nil {
57		t.Fatal(err)
58	}
59	f.Close()
60
61	if err := Mount(sourceDir, targetDir, "none", "bind,rw"); err != nil {
62		t.Fatal(err)
63	}
64	defer func() {
65		if err := Unmount(targetDir); err != nil {
66			t.Fatal(err)
67		}
68	}()
69
70	mounted, err := Mounted(targetDir)
71	if err != nil {
72		t.Fatal(err)
73	}
74	if !mounted {
75		t.Fatalf("Expected %s to be mounted", targetDir)
76	}
77	if _, err := os.Stat(targetDir); err != nil {
78		t.Fatal(err)
79	}
80}
81
82func TestMountReadonly(t *testing.T) {
83	if os.Getuid() != 0 {
84		t.Skip("root required")
85	}
86
87	tmp := path.Join(os.TempDir(), "mount-tests")
88	if err := os.MkdirAll(tmp, 0777); err != nil {
89		t.Fatal(err)
90	}
91	defer os.RemoveAll(tmp)
92
93	var (
94		sourceDir  = path.Join(tmp, "source")
95		targetDir  = path.Join(tmp, "target")
96		sourcePath = path.Join(sourceDir, "file.txt")
97		targetPath = path.Join(targetDir, "file.txt")
98	)
99
100	os.Mkdir(sourceDir, 0777)
101	os.Mkdir(targetDir, 0777)
102
103	f, err := os.Create(sourcePath)
104	if err != nil {
105		t.Fatal(err)
106	}
107	f.WriteString("hello")
108	f.Close()
109
110	f, err = os.Create(targetPath)
111	if err != nil {
112		t.Fatal(err)
113	}
114	f.Close()
115
116	if err := Mount(sourceDir, targetDir, "none", "bind,ro"); err != nil {
117		t.Fatal(err)
118	}
119	defer func() {
120		if err := Unmount(targetDir); err != nil {
121			t.Fatal(err)
122		}
123	}()
124
125	f, err = os.OpenFile(targetPath, os.O_RDWR, 0777)
126	if err == nil {
127		t.Fatal("Should not be able to open a ro file as rw")
128	}
129}
130
131func TestGetMounts(t *testing.T) {
132	mounts, err := GetMounts(nil)
133	if err != nil {
134		t.Fatal(err)
135	}
136
137	root := false
138	for _, entry := range mounts {
139		if entry.Mountpoint == "/" {
140			root = true
141		}
142	}
143
144	if !root {
145		t.Fatal("/ should be mounted at least")
146	}
147}
148
149func TestMergeTmpfsOptions(t *testing.T) {
150	options := []string{"noatime", "ro", "size=10k", "defaults", "atime", "defaults", "rw", "rprivate", "size=1024k", "slave"}
151	expected := []string{"atime", "rw", "size=1024k", "slave"}
152	merged, err := MergeTmpfsOptions(options)
153	if err != nil {
154		t.Fatal(err)
155	}
156	if len(expected) != len(merged) {
157		t.Fatalf("Expected %s got %s", expected, merged)
158	}
159	for index := range merged {
160		if merged[index] != expected[index] {
161			t.Fatalf("Expected %s for the %dth option, got %s", expected, index, merged)
162		}
163	}
164
165	options = []string{"noatime", "ro", "size=10k", "atime", "rw", "rprivate", "size=1024k", "slave", "size"}
166	_, err = MergeTmpfsOptions(options)
167	if err == nil {
168		t.Fatal("Expected error got nil")
169	}
170}
171