1
2
3
4
19
20 package nsenter
21
22 import (
23 "io/ioutil"
24 "os"
25 "path/filepath"
26 "testing"
27
28 "k8s.io/utils/exec"
29 )
30
31 func TestExec(t *testing.T) {
32 tests := []struct {
33 name string
34 command string
35 args []string
36 expectedOutput string
37 expectError bool
38 }{
39 {
40 name: "simple command",
41 command: "echo",
42 args: []string{"hello", "world"},
43 expectedOutput: "hello world\n",
44 },
45 {
46 name: "nozero exit code",
47 command: "false",
48 expectError: true,
49 },
50 }
51
52 executor := fakeExec{
53 rootfsPath: "/rootfs",
54 }
55 for _, test := range tests {
56 ns := NSEnter{
57 hostRootFsPath: "/rootfs",
58 executor: executor,
59 }
60 cmd := ns.Exec(test.command, test.args)
61 outBytes, err := cmd.CombinedOutput()
62 out := string(outBytes)
63 if err != nil && !test.expectError {
64 t.Errorf("Test %q: unexpected error: %s", test.name, err)
65 }
66 if err == nil && test.expectError {
67 t.Errorf("Test %q: expected error, got none", test.name)
68 }
69 if test.expectedOutput != out {
70 t.Errorf("test %q: expected output %q, got %q", test.name, test.expectedOutput, out)
71 }
72 }
73 }
74
75 func TestKubeletPath(t *testing.T) {
76 tests := []struct {
77 rootfs string
78 hostpath string
79 expectedKubeletPath string
80 }{
81 {
82
83 "/rootfs",
84 "/some/path",
85 "/rootfs/some/path",
86 },
87 {
88
89 "/rootfs/",
90 "//some/path",
91 "/rootfs/some/path",
92 },
93 }
94
95 for _, test := range tests {
96 ns := NSEnter{
97 hostRootFsPath: test.rootfs,
98 }
99 out := ns.KubeletPath(test.hostpath)
100 if out != test.expectedKubeletPath {
101 t.Errorf("Expected path %q, got %q", test.expectedKubeletPath, out)
102 }
103
104 }
105 }
106
107 func TestEvalSymlinks(t *testing.T) {
108 tests := []struct {
109 name string
110 mustExist bool
111 prepare func(tmpdir string) (src string, expectedDst string, err error)
112 expectError bool
113 }{
114 {
115 name: "simple file /src",
116 mustExist: true,
117 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
118 src = filepath.Join(tmpdir, "src")
119 err = ioutil.WriteFile(src, []byte{}, 0644)
120 return src, src, err
121 },
122 },
123 {
124 name: "non-existing file /src",
125 mustExist: true,
126 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
127 src = filepath.Join(tmpdir, "src")
128 return src, "", nil
129 },
130 expectError: true,
131 },
132 {
133 name: "non-existing file /src/ with mustExist=false",
134 mustExist: false,
135 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
136 src = filepath.Join(tmpdir, "src")
137 return src, src, nil
138 },
139 },
140 {
141 name: "non-existing file /existing/path/src with mustExist=false with existing directories",
142 mustExist: false,
143 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
144 src = filepath.Join(tmpdir, "existing/path")
145 if err := os.MkdirAll(src, 0755); err != nil {
146 return "", "", err
147 }
148 src = filepath.Join(src, "src")
149 return src, src, nil
150 },
151 },
152 {
153 name: "simple symlink /src -> /dst",
154 mustExist: false,
155 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
156 dst := filepath.Join(tmpdir, "dst")
157 if err = ioutil.WriteFile(dst, []byte{}, 0644); err != nil {
158 return "", "", err
159 }
160 src = filepath.Join(tmpdir, "src")
161 err = os.Symlink(dst, src)
162 return src, dst, err
163 },
164 },
165 {
166 name: "dangling symlink /src -> /non-existing-path",
167 mustExist: true,
168 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
169 dst := filepath.Join(tmpdir, "non-existing-path")
170 src = filepath.Join(tmpdir, "src")
171 err = os.Symlink(dst, src)
172 return src, "", err
173 },
174 expectError: true,
175 },
176 {
177 name: "dangling symlink /src -> /non-existing-path with mustExist=false",
178 mustExist: false,
179 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
180 dst := filepath.Join(tmpdir, "non-existing-path")
181 src = filepath.Join(tmpdir, "src")
182 err = os.Symlink(dst, src)
183 return src, dst, err
184 },
185 },
186 {
187 name: "symlink to directory /src/file, where /src is link to /dst",
188 mustExist: true,
189 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
190 dst := filepath.Join(tmpdir, "dst")
191 if err = os.Mkdir(dst, 0755); err != nil {
192 return "", "", err
193 }
194 dstFile := filepath.Join(dst, "file")
195 if err = ioutil.WriteFile(dstFile, []byte{}, 0644); err != nil {
196 return "", "", err
197 }
198
199 src = filepath.Join(tmpdir, "src")
200 if err = os.Symlink(dst, src); err != nil {
201 return "", "", err
202 }
203 srcFile := filepath.Join(src, "file")
204 return srcFile, dstFile, nil
205 },
206 },
207 {
208 name: "symlink to non-existing directory: /src/file, where /src is link to /dst and dst does not exist",
209 mustExist: true,
210 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
211 dst := filepath.Join(tmpdir, "dst")
212
213 src = filepath.Join(tmpdir, "src")
214 if err = os.Symlink(dst, src); err != nil {
215 return "", "", err
216 }
217 srcFile := filepath.Join(src, "file")
218 return srcFile, "", nil
219 },
220 expectError: true,
221 },
222 {
223 name: "symlink to non-existing directory: /src/file, where /src is link to /dst and dst does not exist with mustExist=false",
224 mustExist: false,
225 prepare: func(tmpdir string) (src string, expectedDst string, err error) {
226 dst := filepath.Join(tmpdir, "dst")
227 dstFile := filepath.Join(dst, "file")
228
229 src = filepath.Join(tmpdir, "src")
230 if err = os.Symlink(dst, src); err != nil {
231 return "", "", err
232 }
233 srcFile := filepath.Join(src, "file")
234 return srcFile, dstFile, nil
235 },
236 },
237 }
238
239 for _, test := range tests {
240 ns := NSEnter{
241 hostRootFsPath: "/rootfs",
242 executor: fakeExec{
243 rootfsPath: "/rootfs",
244 },
245 }
246
247 tmpdir, err := ioutil.TempDir("", "nsenter-hostpath-")
248 if err != nil {
249 t.Fatal(err)
250 }
251 defer os.RemoveAll(tmpdir)
252
253 src, expectedDst, err := test.prepare(tmpdir)
254 if err != nil {
255 t.Error(err)
256 continue
257 }
258
259 dst, err := ns.EvalSymlinks(src, test.mustExist)
260 if err != nil && !test.expectError {
261 t.Errorf("Test %q: unexpected error: %s", test.name, err)
262 }
263 if err == nil && test.expectError {
264 t.Errorf("Test %q: expected error, got none", test.name)
265 }
266 if dst != expectedDst {
267 t.Errorf("Test %q: expected destination %q, got %q", test.name, expectedDst, dst)
268 }
269 }
270 }
271
272 func TestNewNsenter(t *testing.T) {
273
274
275
276 tmpdir, err := ioutil.TempDir("", "nsenter-hostpath-")
277 if err != nil {
278 t.Fatal(err)
279 }
280 defer os.RemoveAll(tmpdir)
281
282 rootfs := filepath.Join(tmpdir, "rootfs")
283 if err = os.Symlink("/", rootfs); err != nil {
284 t.Fatal(err)
285 }
286
287 _, err = NewNsenter(rootfs, exec.New())
288 if err != nil {
289 t.Errorf("Error: %s", err)
290 }
291 }
292
293 func TestNewNsenterError(t *testing.T) {
294
295
296
297 tmpdir, err := ioutil.TempDir("", "nsenter-hostpath-")
298 if err != nil {
299 t.Fatal(err)
300 }
301 defer os.RemoveAll(tmpdir)
302
303 rootfs := filepath.Join(tmpdir, "rootfs")
304 if err = os.MkdirAll(rootfs, 0755); err != nil {
305 t.Fatal(err)
306 }
307
308 _, err = NewNsenter(rootfs, exec.New())
309 if err == nil {
310 t.Errorf("Expected error, got none")
311 }
312 }
313
View as plain text