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  }