1
16
17 package hostpath
18
19 import (
20 "fmt"
21 "os"
22 "testing"
23
24 v1 "k8s.io/api/core/v1"
25 "k8s.io/apimachinery/pkg/api/resource"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/apimachinery/pkg/types"
28 "k8s.io/apimachinery/pkg/util/uuid"
29 "k8s.io/client-go/kubernetes/fake"
30 "k8s.io/klog/v2/ktesting"
31 "k8s.io/kubernetes/pkg/volume"
32 volumetest "k8s.io/kubernetes/pkg/volume/testing"
33 "k8s.io/kubernetes/pkg/volume/util/hostutil"
34 utilpath "k8s.io/utils/path"
35 )
36
37 func newHostPathType(pathType string) *v1.HostPathType {
38 hostPathType := new(v1.HostPathType)
39 *hostPathType = v1.HostPathType(pathType)
40 return hostPathType
41 }
42
43 func newHostPathTypeList(pathType ...string) []*v1.HostPathType {
44 typeList := []*v1.HostPathType{}
45 for _, ele := range pathType {
46 typeList = append(typeList, newHostPathType(ele))
47 }
48
49 return typeList
50 }
51
52 func TestCanSupport(t *testing.T) {
53 plugMgr := volume.VolumePluginMgr{}
54 plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), nil , volumetest.NewFakeKubeletVolumeHost(t, "fake", nil, nil))
55
56 plug, err := plugMgr.FindPluginByName(hostPathPluginName)
57 if err != nil {
58 t.Fatal("Can't find the plugin by name")
59 }
60 if plug.GetPluginName() != hostPathPluginName {
61 t.Errorf("Wrong name: %s", plug.GetPluginName())
62 }
63 if !plug.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{HostPath: &v1.HostPathVolumeSource{}}}}) {
64 t.Errorf("Expected true")
65 }
66 if !plug.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{HostPath: &v1.HostPathVolumeSource{}}}}}) {
67 t.Errorf("Expected true")
68 }
69 if plug.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{}}}) {
70 t.Errorf("Expected false")
71 }
72 }
73
74 func TestGetAccessModes(t *testing.T) {
75 plugMgr := volume.VolumePluginMgr{}
76 plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), nil , volumetest.NewFakeKubeletVolumeHost(t, "/tmp/fake", nil, nil))
77
78 plug, err := plugMgr.FindPersistentPluginByName(hostPathPluginName)
79 if err != nil {
80 t.Fatal("Can't find the plugin by name")
81 }
82 if len(plug.GetAccessModes()) != 1 || plug.GetAccessModes()[0] != v1.ReadWriteOnce {
83 t.Errorf("Expected %s PersistentVolumeAccessMode", v1.ReadWriteOnce)
84 }
85 }
86
87 func TestRecycler(t *testing.T) {
88 plugMgr := volume.VolumePluginMgr{}
89 pluginHost := volumetest.NewFakeKubeletVolumeHost(t, "/tmp/fake", nil, nil)
90 plugMgr.InitPlugins([]volume.VolumePlugin{&hostPathPlugin{nil, volume.VolumeConfig{}, false}}, nil, pluginHost)
91
92 spec := &volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{HostPath: &v1.HostPathVolumeSource{Path: "/foo"}}}}}
93 _, err := plugMgr.FindRecyclablePluginBySpec(spec)
94 if err != nil {
95 t.Errorf("Can't find the plugin by name")
96 }
97 }
98
99 func TestDeleter(t *testing.T) {
100
101 tempPath := fmt.Sprintf("/tmp/hostpath.%s", uuid.NewUUID())
102 err := os.MkdirAll(tempPath, 0750)
103 if err != nil {
104 t.Fatalf("Failed to create tmp directory for deleter: %v", err)
105 }
106 defer os.RemoveAll(tempPath)
107 plugMgr := volume.VolumePluginMgr{}
108 plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), nil , volumetest.NewFakeKubeletVolumeHost(t, "/tmp/fake", nil, nil))
109
110 spec := &volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{HostPath: &v1.HostPathVolumeSource{Path: tempPath}}}}}
111 plug, err := plugMgr.FindDeletablePluginBySpec(spec)
112 if err != nil {
113 t.Fatal("Can't find the plugin by name")
114 }
115 logger, _ := ktesting.NewTestContext(t)
116 deleter, err := plug.NewDeleter(logger, spec)
117 if err != nil {
118 t.Errorf("Failed to make a new Deleter: %v", err)
119 }
120 if deleter.GetPath() != tempPath {
121 t.Errorf("Expected %s but got %s", tempPath, deleter.GetPath())
122 }
123 if err := deleter.Delete(); err != nil {
124 t.Errorf("Mock Recycler expected to return nil but got %s", err)
125 }
126 if exists, _ := utilpath.Exists(utilpath.CheckFollowSymlink, tempPath); exists {
127 t.Errorf("Temp path expected to be deleted, but was found at %s", tempPath)
128 }
129 }
130
131 func TestDeleterTempDir(t *testing.T) {
132 tests := map[string]struct {
133 expectedFailure bool
134 path string
135 }{
136 "just-tmp": {true, "/tmp"},
137 "not-tmp": {true, "/nottmp"},
138 "good-tmp": {false, "/tmp/scratch"},
139 }
140 logger, _ := ktesting.NewTestContext(t)
141 for name, test := range tests {
142 plugMgr := volume.VolumePluginMgr{}
143 plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), nil , volumetest.NewFakeKubeletVolumeHost(t, "/tmp/fake", nil, nil))
144 spec := &volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{HostPath: &v1.HostPathVolumeSource{Path: test.path}}}}}
145 plug, _ := plugMgr.FindDeletablePluginBySpec(spec)
146 deleter, _ := plug.NewDeleter(logger, spec)
147 err := deleter.Delete()
148 if err == nil && test.expectedFailure {
149 t.Errorf("Expected failure for test '%s' but got nil err", name)
150 }
151 if err != nil && !test.expectedFailure {
152 t.Errorf("Unexpected failure for test '%s': %v", name, err)
153 }
154 }
155 }
156
157 func TestProvisioner(t *testing.T) {
158 plugMgr := volume.VolumePluginMgr{}
159 plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{ProvisioningEnabled: true}),
160 nil,
161 volumetest.NewFakeKubeletVolumeHost(t, "/tmp/fake", nil, nil))
162 spec := &volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{
163 PersistentVolumeSource: v1.PersistentVolumeSource{HostPath: &v1.HostPathVolumeSource{Path: fmt.Sprintf("/tmp/hostpath.%s", uuid.NewUUID())}}}}}
164 plug, err := plugMgr.FindCreatablePluginBySpec(spec)
165 if err != nil {
166 t.Fatalf("Can't find the plugin by name")
167 }
168 options := volume.VolumeOptions{
169 PVC: volumetest.CreateTestPVC("1Gi", []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce}),
170 PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete,
171 }
172 logger, _ := ktesting.NewTestContext(t)
173 creator, err := plug.NewProvisioner(logger, options)
174 if err != nil {
175 t.Fatalf("Failed to make a new Provisioner: %v", err)
176 }
177
178 hostPathCreator, ok := creator.(*hostPathProvisioner)
179 if !ok {
180 t.Fatal("Not a hostPathProvisioner")
181 }
182 hostPathCreator.basePath = fmt.Sprintf("%s.%s", "hostPath_pv", uuid.NewUUID())
183
184 pv, err := hostPathCreator.Provision(nil, nil)
185 if err != nil {
186 t.Errorf("Unexpected error creating volume: %v", err)
187 }
188 if pv.Spec.HostPath.Path == "" {
189 t.Errorf("Expected pv.Spec.HostPath.Path to not be empty: %#v", pv)
190 }
191 expectedCapacity := resource.NewQuantity(1*1024*1024*1024, resource.BinarySI)
192 actualCapacity := pv.Spec.Capacity[v1.ResourceStorage]
193 expectedAmt := expectedCapacity.Value()
194 actualAmt := actualCapacity.Value()
195 if expectedAmt != actualAmt {
196 t.Errorf("Expected capacity %+v but got %+v", expectedAmt, actualAmt)
197 }
198
199 if pv.Spec.PersistentVolumeReclaimPolicy != v1.PersistentVolumeReclaimDelete {
200 t.Errorf("Expected reclaim policy %+v but got %+v", v1.PersistentVolumeReclaimDelete, pv.Spec.PersistentVolumeReclaimPolicy)
201 }
202
203 os.RemoveAll(hostPathCreator.basePath)
204
205 }
206
207 func TestInvalidHostPath(t *testing.T) {
208 plugMgr := volume.VolumePluginMgr{}
209 plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), nil , volumetest.NewFakeKubeletVolumeHost(t, "fake", nil, nil))
210
211 plug, err := plugMgr.FindPluginByName(hostPathPluginName)
212 if err != nil {
213 t.Fatalf("Unable to find plugin %s by name: %v", hostPathPluginName, err)
214 }
215 spec := &v1.Volume{
216 Name: "vol1",
217 VolumeSource: v1.VolumeSource{HostPath: &v1.HostPathVolumeSource{Path: "/no/backsteps/allowed/.."}},
218 }
219 pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
220 mounter, err := plug.NewMounter(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{})
221 if err != nil {
222 t.Fatal(err)
223 }
224
225 err = mounter.SetUp(volume.MounterArgs{})
226 expectedMsg := "invalid HostPath `/no/backsteps/allowed/..`: must not contain '..'"
227 if err.Error() != expectedMsg {
228 t.Fatalf("expected error `%s` but got `%s`", expectedMsg, err)
229 }
230 }
231
232 func TestPlugin(t *testing.T) {
233 plugMgr := volume.VolumePluginMgr{}
234 plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), nil , volumetest.NewFakeKubeletVolumeHost(t, "fake", nil, nil))
235
236 plug, err := plugMgr.FindPluginByName(hostPathPluginName)
237 if err != nil {
238 t.Fatal("Can't find the plugin by name")
239 }
240
241 volPath := "/tmp/vol1"
242 spec := &v1.Volume{
243 Name: "vol1",
244 VolumeSource: v1.VolumeSource{HostPath: &v1.HostPathVolumeSource{Path: volPath, Type: newHostPathType(string(v1.HostPathDirectoryOrCreate))}},
245 }
246 pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
247 defer os.RemoveAll(volPath)
248 mounter, err := plug.NewMounter(volume.NewSpecFromVolume(spec), pod, volume.VolumeOptions{})
249 if err != nil {
250 t.Errorf("Failed to make a new Mounter: %v", err)
251 }
252 if mounter == nil {
253 t.Fatalf("Got a nil Mounter")
254 }
255
256 path := mounter.GetPath()
257 if path != volPath {
258 t.Errorf("Got unexpected path: %s", path)
259 }
260
261 if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
262 t.Errorf("Expected success, got: %v", err)
263 }
264
265 unmounter, err := plug.NewUnmounter("vol1", types.UID("poduid"))
266 if err != nil {
267 t.Errorf("Failed to make a new Unmounter: %v", err)
268 }
269 if unmounter == nil {
270 t.Fatalf("Got a nil Unmounter")
271 }
272
273 if err := unmounter.TearDown(); err != nil {
274 t.Errorf("Expected success, got: %v", err)
275 }
276 }
277
278 func TestPersistentClaimReadOnlyFlag(t *testing.T) {
279 pv := &v1.PersistentVolume{
280 ObjectMeta: metav1.ObjectMeta{
281 Name: "pvA",
282 },
283 Spec: v1.PersistentVolumeSpec{
284 PersistentVolumeSource: v1.PersistentVolumeSource{
285 HostPath: &v1.HostPathVolumeSource{Path: "foo", Type: newHostPathType(string(v1.HostPathDirectoryOrCreate))},
286 },
287 ClaimRef: &v1.ObjectReference{
288 Name: "claimA",
289 },
290 },
291 }
292 defer os.RemoveAll("foo")
293
294 claim := &v1.PersistentVolumeClaim{
295 ObjectMeta: metav1.ObjectMeta{
296 Name: "claimA",
297 Namespace: "nsA",
298 },
299 Spec: v1.PersistentVolumeClaimSpec{
300 VolumeName: "pvA",
301 },
302 Status: v1.PersistentVolumeClaimStatus{
303 Phase: v1.ClaimBound,
304 },
305 }
306
307 client := fake.NewSimpleClientset(pv, claim)
308
309 plugMgr := volume.VolumePluginMgr{}
310 plugMgr.InitPlugins(ProbeVolumePlugins(volume.VolumeConfig{}), nil , volumetest.NewFakeKubeletVolumeHost(t, "/tmp/fake", client, nil))
311 plug, _ := plugMgr.FindPluginByName(hostPathPluginName)
312
313
314 spec := volume.NewSpecFromPersistentVolume(pv, true)
315 pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
316 mounter, _ := plug.NewMounter(spec, pod, volume.VolumeOptions{})
317 if mounter == nil {
318 t.Fatalf("Got a nil Mounter")
319 }
320
321 if !mounter.GetAttributes().ReadOnly {
322 t.Errorf("Expected true for mounter.IsReadOnly")
323 }
324 }
325
326 func setUp() error {
327 err := os.MkdirAll("/tmp/ExistingFolder", os.FileMode(0755))
328 if err != nil {
329 return err
330 }
331
332 f, err := os.OpenFile("/tmp/ExistingFolder/foo", os.O_CREATE, os.FileMode(0644))
333 if err != nil {
334 return err
335 }
336 defer f.Close()
337
338 return nil
339 }
340
341 func tearDown() {
342 os.RemoveAll("/tmp/ExistingFolder")
343 }
344
345 func TestOSFileTypeChecker(t *testing.T) {
346 err := setUp()
347 if err != nil {
348 t.Error(err)
349 }
350 defer tearDown()
351 testCases := []struct {
352 name string
353 path string
354 desiredType string
355 isDir bool
356 isFile bool
357 isSocket bool
358 isBlock bool
359 isChar bool
360 }{
361 {
362 name: "Existing Folder",
363 path: "/tmp/ExistingFolder",
364 desiredType: string(hostutil.FileTypeDirectory),
365 isDir: true,
366 },
367 {
368 name: "Existing File",
369 path: "/tmp/ExistingFolder/foo",
370 desiredType: string(hostutil.FileTypeFile),
371 isFile: true,
372 },
373 {
374 name: "Existing Socket File",
375 path: "/tmp/ExistingFolder/foo",
376 desiredType: string(v1.HostPathSocket),
377 isSocket: true,
378 },
379 {
380 name: "Existing Character Device",
381 path: "/tmp/ExistingFolder/foo",
382 desiredType: string(v1.HostPathCharDev),
383 isChar: true,
384 },
385 {
386 name: "Existing Block Device",
387 path: "/tmp/ExistingFolder/foo",
388 desiredType: string(v1.HostPathBlockDev),
389 isBlock: true,
390 },
391 }
392
393 for i, tc := range testCases {
394 fakeFTC := hostutil.NewFakeHostUtil(
395 map[string]hostutil.FileType{
396 tc.path: hostutil.FileType(tc.desiredType),
397 })
398 oftc := newFileTypeChecker(tc.path, fakeFTC)
399
400 path := oftc.GetPath()
401 if path != tc.path {
402 t.Errorf("[%d: %q] got unexpected path: %s", i, tc.name, path)
403 }
404
405 exist := oftc.Exists()
406 if !exist {
407 t.Errorf("[%d: %q] path: %s does not exist", i, tc.name, path)
408 }
409
410 if tc.isDir {
411 if !oftc.IsDir() {
412 t.Errorf("[%d: %q] expected folder, got unexpected: %s", i, tc.name, path)
413 }
414 if oftc.IsFile() {
415 t.Errorf("[%d: %q] expected folder, got unexpected file: %s", i, tc.name, path)
416 }
417 if oftc.IsSocket() {
418 t.Errorf("[%d: %q] expected folder, got unexpected socket file: %s", i, tc.name, path)
419 }
420 if oftc.IsBlock() {
421 t.Errorf("[%d: %q] expected folder, got unexpected block device: %s", i, tc.name, path)
422 }
423 if oftc.IsChar() {
424 t.Errorf("[%d: %q] expected folder, got unexpected character device: %s", i, tc.name, path)
425 }
426 }
427
428 if tc.isFile {
429 if !oftc.IsFile() {
430 t.Errorf("[%d: %q] expected file, got unexpected: %s", i, tc.name, path)
431 }
432 if oftc.IsDir() {
433 t.Errorf("[%d: %q] expected file, got unexpected folder: %s", i, tc.name, path)
434 }
435 if oftc.IsSocket() {
436 t.Errorf("[%d: %q] expected file, got unexpected socket file: %s", i, tc.name, path)
437 }
438 if oftc.IsBlock() {
439 t.Errorf("[%d: %q] expected file, got unexpected block device: %s", i, tc.name, path)
440 }
441 if oftc.IsChar() {
442 t.Errorf("[%d: %q] expected file, got unexpected character device: %s", i, tc.name, path)
443 }
444 }
445
446 if tc.isSocket {
447 if !oftc.IsSocket() {
448 t.Errorf("[%d: %q] expected socket file, got unexpected: %s", i, tc.name, path)
449 }
450 if oftc.IsDir() {
451 t.Errorf("[%d: %q] expected socket file, got unexpected folder: %s", i, tc.name, path)
452 }
453 if oftc.IsFile() {
454 t.Errorf("[%d: %q] expected socket file, got unexpected file: %s", i, tc.name, path)
455 }
456 if oftc.IsBlock() {
457 t.Errorf("[%d: %q] expected socket file, got unexpected block device: %s", i, tc.name, path)
458 }
459 if oftc.IsChar() {
460 t.Errorf("[%d: %q] expected socket file, got unexpected character device: %s", i, tc.name, path)
461 }
462 }
463
464 if tc.isChar {
465 if !oftc.IsChar() {
466 t.Errorf("[%d: %q] expected character device, got unexpected: %s", i, tc.name, path)
467 }
468 if oftc.IsDir() {
469 t.Errorf("[%d: %q] expected character device, got unexpected folder: %s", i, tc.name, path)
470 }
471 if oftc.IsFile() {
472 t.Errorf("[%d: %q] expected character device, got unexpected file: %s", i, tc.name, path)
473 }
474 if oftc.IsSocket() {
475 t.Errorf("[%d: %q] expected character device, got unexpected socket file: %s", i, tc.name, path)
476 }
477 if oftc.IsBlock() {
478 t.Errorf("[%d: %q] expected character device, got unexpected block device: %s", i, tc.name, path)
479 }
480 }
481
482 if tc.isBlock {
483 if !oftc.IsBlock() {
484 t.Errorf("[%d: %q] expected block device, got unexpected: %s", i, tc.name, path)
485 }
486 if oftc.IsDir() {
487 t.Errorf("[%d: %q] expected block device, got unexpected folder: %s", i, tc.name, path)
488 }
489 if oftc.IsFile() {
490 t.Errorf("[%d: %q] expected block device, got unexpected file: %s", i, tc.name, path)
491 }
492 if oftc.IsSocket() {
493 t.Errorf("[%d: %q] expected block device, got unexpected socket file: %s", i, tc.name, path)
494 }
495 if oftc.IsChar() {
496 t.Errorf("[%d: %q] expected block device, got unexpected character device: %s", i, tc.name, path)
497 }
498 }
499 }
500
501 }
502
503 type fakeHostPathTypeChecker struct {
504 name string
505 path string
506 exists bool
507 isDir bool
508 isFile bool
509 isSocket bool
510 isBlock bool
511 isChar bool
512 validpathType []*v1.HostPathType
513 invalidpathType []*v1.HostPathType
514 }
515
516 func (ftc *fakeHostPathTypeChecker) MakeFile() error { return nil }
517 func (ftc *fakeHostPathTypeChecker) MakeDir() error { return nil }
518 func (ftc *fakeHostPathTypeChecker) Exists() bool { return ftc.exists }
519 func (ftc *fakeHostPathTypeChecker) IsFile() bool { return ftc.isFile }
520 func (ftc *fakeHostPathTypeChecker) IsDir() bool { return ftc.isDir }
521 func (ftc *fakeHostPathTypeChecker) IsBlock() bool { return ftc.isBlock }
522 func (ftc *fakeHostPathTypeChecker) IsChar() bool { return ftc.isChar }
523 func (ftc *fakeHostPathTypeChecker) IsSocket() bool { return ftc.isSocket }
524 func (ftc *fakeHostPathTypeChecker) GetPath() string { return ftc.path }
525
526 func TestHostPathTypeCheckerInternal(t *testing.T) {
527 testCases := []fakeHostPathTypeChecker{
528 {
529 name: "Existing Folder",
530 path: "/existingFolder",
531 isDir: true,
532 exists: true,
533 validpathType: newHostPathTypeList(string(v1.HostPathDirectoryOrCreate), string(v1.HostPathDirectory)),
534 invalidpathType: newHostPathTypeList(string(v1.HostPathFileOrCreate), string(v1.HostPathFile),
535 string(v1.HostPathSocket), string(v1.HostPathCharDev), string(v1.HostPathBlockDev)),
536 },
537 {
538 name: "New Folder",
539 path: "/newFolder",
540 isDir: false,
541 exists: false,
542 validpathType: newHostPathTypeList(string(v1.HostPathDirectoryOrCreate)),
543 invalidpathType: newHostPathTypeList(string(v1.HostPathDirectory), string(v1.HostPathFile),
544 string(v1.HostPathSocket), string(v1.HostPathCharDev), string(v1.HostPathBlockDev)),
545 },
546 {
547 name: "Existing File",
548 path: "/existingFile",
549 isFile: true,
550 exists: true,
551 validpathType: newHostPathTypeList(string(v1.HostPathFileOrCreate), string(v1.HostPathFile)),
552 invalidpathType: newHostPathTypeList(string(v1.HostPathDirectoryOrCreate), string(v1.HostPathDirectory),
553 string(v1.HostPathSocket), string(v1.HostPathCharDev), string(v1.HostPathBlockDev)),
554 },
555 {
556 name: "New File",
557 path: "/newFile",
558 isFile: false,
559 exists: false,
560 validpathType: newHostPathTypeList(string(v1.HostPathFileOrCreate)),
561 invalidpathType: newHostPathTypeList(string(v1.HostPathDirectory),
562 string(v1.HostPathSocket), string(v1.HostPathCharDev), string(v1.HostPathBlockDev)),
563 },
564 {
565 name: "Existing Socket",
566 path: "/existing.socket",
567 isSocket: true,
568 isFile: true,
569 exists: true,
570 validpathType: newHostPathTypeList(string(v1.HostPathSocket), string(v1.HostPathFileOrCreate), string(v1.HostPathFile)),
571 invalidpathType: newHostPathTypeList(string(v1.HostPathDirectoryOrCreate), string(v1.HostPathDirectory),
572 string(v1.HostPathCharDev), string(v1.HostPathBlockDev)),
573 },
574 {
575 name: "Existing Character Device",
576 path: "/existing.char",
577 isChar: true,
578 isFile: true,
579 exists: true,
580 validpathType: newHostPathTypeList(string(v1.HostPathCharDev), string(v1.HostPathFileOrCreate), string(v1.HostPathFile)),
581 invalidpathType: newHostPathTypeList(string(v1.HostPathDirectoryOrCreate), string(v1.HostPathDirectory),
582 string(v1.HostPathSocket), string(v1.HostPathBlockDev)),
583 },
584 {
585 name: "Existing Block Device",
586 path: "/existing.block",
587 isBlock: true,
588 isFile: true,
589 exists: true,
590 validpathType: newHostPathTypeList(string(v1.HostPathBlockDev), string(v1.HostPathFileOrCreate), string(v1.HostPathFile)),
591 invalidpathType: newHostPathTypeList(string(v1.HostPathDirectoryOrCreate), string(v1.HostPathDirectory),
592 string(v1.HostPathSocket), string(v1.HostPathCharDev)),
593 },
594 }
595
596 for i, tc := range testCases {
597 for _, pathType := range tc.validpathType {
598 err := checkTypeInternal(&tc, pathType)
599 if err != nil {
600 t.Errorf("[%d: %q] [%q] expected nil, got %v", i, tc.name, string(*pathType), err)
601 }
602 }
603
604 for _, pathType := range tc.invalidpathType {
605 checkResult := checkTypeInternal(&tc, pathType)
606 if checkResult == nil {
607 t.Errorf("[%d: %q] [%q] expected error, got nil", i, tc.name, string(*pathType))
608 }
609 }
610 }
611
612 }
613
View as plain text