1
2
3
4
5
6
7
8
9
10
11
12
13 package procfs
14
15 import (
16 "reflect"
17 "testing"
18 )
19
20 func TestMountInfo(t *testing.T) {
21 tests := []struct {
22 name string
23 s string
24 mount *MountInfo
25 invalid bool
26 }{
27 {
28 name: "Regular sysfs mounted at /sys",
29 s: "16 21 0:16 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw",
30 invalid: false,
31 mount: &MountInfo{
32 MountID: 16,
33 ParentID: 21,
34 MajorMinorVer: "0:16",
35 Root: "/",
36 MountPoint: "/sys",
37 Options: map[string]string{"rw": "", "nosuid": "", "nodev": "", "noexec": "", "relatime": ""},
38 OptionalFields: map[string]string{"shared": "7"},
39 FSType: "sysfs",
40 Source: "sysfs",
41 SuperOptions: map[string]string{"rw": ""},
42 },
43 },
44 {
45 name: "Not enough information",
46 s: "hello",
47 invalid: true,
48 },
49 {
50 name: "Tmpfs mounted at /run",
51 s: "225 20 0:39 / /run/user/112 rw,nosuid,nodev,relatime shared:177 - tmpfs tmpfs rw,size=405096k,mode=700,uid=112,gid=116",
52 mount: &MountInfo{
53 MountID: 225,
54 ParentID: 20,
55 MajorMinorVer: "0:39",
56 Root: "/",
57 MountPoint: "/run/user/112",
58 Options: map[string]string{"rw": "", "nosuid": "", "nodev": "", "relatime": ""},
59 OptionalFields: map[string]string{"shared": "177"},
60 FSType: "tmpfs",
61 Source: "tmpfs",
62 SuperOptions: map[string]string{"rw": "", "size": "405096k", "mode": "700", "uid": "112", "gid": "116"},
63 },
64 invalid: false,
65 },
66 {
67 name: "Tmpfs mounted at /run, but no optional values",
68 s: "225 20 0:39 / /run/user/112 rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=405096k,mode=700,uid=112,gid=116",
69 mount: &MountInfo{
70 MountID: 225,
71 ParentID: 20,
72 MajorMinorVer: "0:39",
73 Root: "/",
74 MountPoint: "/run/user/112",
75 Options: map[string]string{"rw": "", "nosuid": "", "nodev": "", "relatime": ""},
76 OptionalFields: nil,
77 FSType: "tmpfs",
78 Source: "tmpfs",
79 SuperOptions: map[string]string{"rw": "", "size": "405096k", "mode": "700", "uid": "112", "gid": "116"},
80 },
81 invalid: false,
82 },
83 {
84 name: "Tmpfs mounted at /run, with multiple optional values",
85 s: "225 20 0:39 / /run/user/112 rw,nosuid,nodev,relatime shared:177 master:8 - tmpfs tmpfs rw,size=405096k,mode=700,uid=112,gid=116",
86 mount: &MountInfo{
87 MountID: 225,
88 ParentID: 20,
89 MajorMinorVer: "0:39",
90 Root: "/",
91 MountPoint: "/run/user/112",
92 Options: map[string]string{"rw": "", "nosuid": "", "nodev": "", "relatime": ""},
93 OptionalFields: map[string]string{"shared": "177", "master": "8"},
94 FSType: "tmpfs",
95 Source: "tmpfs",
96 SuperOptions: map[string]string{"rw": "", "size": "405096k", "mode": "700", "uid": "112", "gid": "116"},
97 },
98 invalid: false,
99 },
100 {
101 name: "Tmpfs mounted at /run, with a mixture of valid and invalid optional values",
102 s: "225 20 0:39 / /run/user/112 rw,nosuid,nodev,relatime shared:177 master:8 foo:bar - tmpfs tmpfs rw,size=405096k,mode=700,uid=112,gid=116",
103 mount: &MountInfo{
104 MountID: 225,
105 ParentID: 20,
106 MajorMinorVer: "0:39",
107 Root: "/",
108 MountPoint: "/run/user/112",
109 Options: map[string]string{"rw": "", "nosuid": "", "nodev": "", "relatime": ""},
110 OptionalFields: map[string]string{"shared": "177", "master": "8"},
111 FSType: "tmpfs",
112 Source: "tmpfs",
113 SuperOptions: map[string]string{"rw": "", "size": "405096k", "mode": "700", "uid": "112", "gid": "116"},
114 },
115 invalid: false,
116 },
117 {
118 name: "CIFS mounted at /with/a-hyphen",
119 s: "454 29 0:87 / /with/a-hyphen rw,relatime shared:255 - cifs //remote-storage/Path rw,vers=3.1.1,cache=strict,username=user,uid=1000,forceuid,gid=0,noforcegid,addr=127.0.0.1,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,echo_interval=60,actimeo=1",
120 mount: &MountInfo{
121 MountID: 454,
122 ParentID: 29,
123 MajorMinorVer: "0:87",
124 Root: "/",
125 MountPoint: "/with/a-hyphen",
126 Options: map[string]string{"rw": "", "relatime": ""},
127 OptionalFields: map[string]string{"shared": "255"},
128 FSType: "cifs",
129 Source: "//remote-storage/Path",
130 SuperOptions: map[string]string{"rw": "", "vers": "3.1.1", "cache": "strict", "username": "user", "uid": "1000", "forceuid": "", "gid": "0", "noforcegid": "", "addr": "127.0.0.1", "file_mode": "0755", "dir_mode": "0755", "soft": "", "nounix": "", "serverino": "", "mapposix": "", "echo_interval": "60", "actimeo": "1"},
131 },
132 invalid: false,
133 },
134 {
135 name: "Docker overlay with 10 fields (no optional fields)",
136 s: "137 45 253:2 /lib/docker/overlay2 /var/lib/docker/overlay2 rw,relatime - ext4 /dev/mapper/vg0-lv_var rw,data=ordered",
137 mount: &MountInfo{
138 MountID: 137,
139 ParentID: 45,
140 MajorMinorVer: "253:2",
141 Root: "/lib/docker/overlay2",
142 MountPoint: "/var/lib/docker/overlay2",
143 Options: map[string]string{"rw": "", "relatime": ""},
144 OptionalFields: map[string]string{},
145 FSType: "ext4",
146 Source: "/dev/mapper/vg0-lv_var",
147 SuperOptions: map[string]string{"rw": "", "data": "ordered"},
148 },
149 },
150 {
151 name: "bind chroot bind mount with 10 fields (no optional fields)",
152 s: "157 47 253:2 /etc/named /var/named/chroot/etc/named rw,relatime - ext4 /dev/mapper/vg0-lv_root rw,data=ordered",
153 mount: &MountInfo{
154 MountID: 157,
155 ParentID: 47,
156 MajorMinorVer: "253:2",
157 Root: "/etc/named",
158 MountPoint: "/var/named/chroot/etc/named",
159 Options: map[string]string{"rw": "", "relatime": ""},
160 OptionalFields: map[string]string{},
161 FSType: "ext4",
162 Source: "/dev/mapper/vg0-lv_root",
163 SuperOptions: map[string]string{"rw": "", "data": "ordered"},
164 },
165 },
166 }
167
168 for i, test := range tests {
169 t.Logf("[%02d] test %q", i, test.name)
170
171 mount, err := parseMountInfoString(test.s)
172
173 if test.invalid && err == nil {
174 t.Error("expected an error, but none occurred")
175 }
176 if !test.invalid && err != nil {
177 t.Errorf("unexpected error: %v", err)
178 }
179
180 if want, have := test.mount, mount; !reflect.DeepEqual(want, have) {
181 t.Errorf("mounts:\nwant:\n%+v\nhave:\n%+v", want, have)
182 }
183 }
184 }
185
View as plain text