k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/volume/plugins_test.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package volume 18 19 import ( 20 "testing" 21 22 v1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/apimachinery/pkg/types" 25 ) 26 27 const testPluginName = "kubernetes.io/testPlugin" 28 29 func TestSpecSourceConverters(t *testing.T) { 30 v := &v1.Volume{ 31 Name: "foo", 32 VolumeSource: v1.VolumeSource{EmptyDir: &v1.EmptyDirVolumeSource{}}, 33 } 34 35 converted := NewSpecFromVolume(v) 36 if converted.Volume.EmptyDir == nil { 37 t.Errorf("Unexpected nil EmptyDir: %#v", converted) 38 } 39 if v.Name != converted.Name() { 40 t.Errorf("Expected %v but got %v", converted.Name(), v.Name) 41 } 42 43 pv := &v1.PersistentVolume{ 44 ObjectMeta: metav1.ObjectMeta{Name: "bar"}, 45 Spec: v1.PersistentVolumeSpec{ 46 PersistentVolumeSource: v1.PersistentVolumeSource{AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{}}, 47 }, 48 } 49 50 converted = NewSpecFromPersistentVolume(pv, false) 51 if converted.PersistentVolume.Spec.AWSElasticBlockStore == nil { 52 t.Errorf("Unexpected nil AWSElasticBlockStore: %#v", converted) 53 } 54 if pv.Name != converted.Name() { 55 t.Errorf("Expected %v but got %v", converted.Name(), pv.Name) 56 } 57 } 58 59 type testPlugins struct { 60 } 61 62 func (plugin *testPlugins) Init(host VolumeHost) error { 63 return nil 64 } 65 66 func (plugin *testPlugins) GetPluginName() string { 67 return testPluginName 68 } 69 70 func (plugin *testPlugins) GetVolumeName(spec *Spec) (string, error) { 71 return "", nil 72 } 73 74 func (plugin *testPlugins) CanSupport(spec *Spec) bool { 75 return true 76 } 77 78 func (plugin *testPlugins) RequiresRemount(spec *Spec) bool { 79 return false 80 } 81 82 func (plugin *testPlugins) SupportsMountOption() bool { 83 return false 84 } 85 86 func (plugin *testPlugins) SupportsSELinuxContextMount(spec *Spec) (bool, error) { 87 return false, nil 88 } 89 90 func (plugin *testPlugins) NewMounter(spec *Spec, podRef *v1.Pod, opts VolumeOptions) (Mounter, error) { 91 return nil, nil 92 } 93 94 func (plugin *testPlugins) NewUnmounter(name string, podUID types.UID) (Unmounter, error) { 95 return nil, nil 96 } 97 98 func (plugin *testPlugins) ConstructVolumeSpec(volumeName, mountPath string) (ReconstructedVolume, error) { 99 return ReconstructedVolume{}, nil 100 } 101 102 func newTestPlugin() []VolumePlugin { 103 return []VolumePlugin{&testPlugins{}} 104 } 105 106 func TestVolumePluginMgrFunc(t *testing.T) { 107 vpm := VolumePluginMgr{} 108 var prober DynamicPluginProber = nil // TODO (#51147) inject mock 109 vpm.InitPlugins(newTestPlugin(), prober, nil) 110 111 plug, err := vpm.FindPluginByName(testPluginName) 112 if err != nil { 113 t.Fatal("Can't find the plugin by name") 114 } 115 if plug.GetPluginName() != testPluginName { 116 t.Errorf("Wrong name: %s", plug.GetPluginName()) 117 } 118 119 _, err = vpm.FindPluginBySpec(nil) 120 if err == nil { 121 t.Errorf("Should return error if volume spec is nil") 122 } 123 124 volumeSpec := &Spec{} 125 _, err = vpm.FindPluginBySpec(volumeSpec) 126 if err != nil { 127 t.Errorf("Should return test plugin if volume spec is not nil") 128 } 129 } 130 131 func Test_ValidatePodTemplate(t *testing.T) { 132 pod := &v1.Pod{ 133 Spec: v1.PodSpec{ 134 Volumes: []v1.Volume{ 135 { 136 Name: "vol", 137 VolumeSource: v1.VolumeSource{}, 138 }, 139 }, 140 }, 141 } 142 var want error 143 if got := ValidateRecyclerPodTemplate(pod); got != want { 144 t.Errorf("isPodTemplateValid(%v) returned (%v), want (%v)", pod.String(), got.Error(), want) 145 } 146 147 // Check that the default recycle pod template is valid 148 pod = NewPersistentVolumeRecyclerPodTemplate() 149 want = nil 150 if got := ValidateRecyclerPodTemplate(pod); got != want { 151 t.Errorf("isPodTemplateValid(%v) returned (%v), want (%v)", pod.String(), got.Error(), want) 152 } 153 154 pod = &v1.Pod{ 155 Spec: v1.PodSpec{ 156 Containers: []v1.Container{ 157 { 158 Name: "pv-recycler", 159 }, 160 }, 161 }, 162 } 163 // want = an error 164 if got := ValidateRecyclerPodTemplate(pod); got == nil { 165 t.Errorf("isPodTemplateValid(%v) returned (%v), want (%v)", pod.String(), got, "Error: pod specification does not contain any volume(s).") 166 } 167 }