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