k8s.io/kubernetes@v1.29.3/pkg/volume/vsphere_volume/vsphere_volume_test.go (about)

     1  //go:build !providerless
     2  // +build !providerless
     3  
     4  /*
     5  Copyright 2016 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package vsphere_volume
    21  
    22  import (
    23  	"fmt"
    24  	"os"
    25  	"path/filepath"
    26  	"testing"
    27  
    28  	"k8s.io/mount-utils"
    29  
    30  	v1 "k8s.io/api/core/v1"
    31  	"k8s.io/apimachinery/pkg/types"
    32  	utiltesting "k8s.io/client-go/util/testing"
    33  	cloudprovider "k8s.io/cloud-provider"
    34  	"k8s.io/cloud-provider/fake"
    35  	"k8s.io/kubernetes/pkg/volume"
    36  	volumetest "k8s.io/kubernetes/pkg/volume/testing"
    37  	"k8s.io/legacy-cloud-providers/vsphere"
    38  )
    39  
    40  func TestCanSupport(t *testing.T) {
    41  	tmpDir, err := utiltesting.MkTmpdir("vsphereVolumeTest")
    42  	if err != nil {
    43  		t.Fatalf("can't make a temp dir: %v", err)
    44  	}
    45  	defer os.RemoveAll(tmpDir)
    46  	plugMgr := volume.VolumePluginMgr{}
    47  	plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeKubeletVolumeHost(t, tmpDir, nil, nil))
    48  
    49  	plug, err := plugMgr.FindPluginByName("kubernetes.io/vsphere-volume")
    50  	if err != nil {
    51  		t.Fatal("Can't find the plugin by name")
    52  	}
    53  	if plug.GetPluginName() != "kubernetes.io/vsphere-volume" {
    54  		t.Errorf("Wrong name: %s", plug.GetPluginName())
    55  	}
    56  
    57  	if !plug.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{}}}}) {
    58  		t.Errorf("Expected true")
    59  	}
    60  
    61  	if !plug.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{}}}}}) {
    62  		t.Errorf("Expected true")
    63  	}
    64  }
    65  
    66  type fakePDManager struct {
    67  }
    68  
    69  func (fake *fakePDManager) CreateVolume(v *vsphereVolumeProvisioner, selectedNode *v1.Node, selectedZone []string) (volSpec *VolumeSpec, err error) {
    70  	volSpec = &VolumeSpec{
    71  		Path:              "[local] test-volume-name.vmdk",
    72  		Size:              100,
    73  		Fstype:            "ext4",
    74  		StoragePolicyName: "gold",
    75  		StoragePolicyID:   "1234",
    76  	}
    77  	return volSpec, nil
    78  }
    79  
    80  func (fake *fakePDManager) DeleteVolume(vd *vsphereVolumeDeleter) error {
    81  	if vd.volPath != "[local] test-volume-name.vmdk" {
    82  		return fmt.Errorf("Deleter got unexpected volume path: %s", vd.volPath)
    83  	}
    84  	return nil
    85  }
    86  
    87  func TestPlugin(t *testing.T) {
    88  	// Initial setup to test volume plugin
    89  	tmpDir, err := utiltesting.MkTmpdir("vsphereVolumeTest")
    90  	if err != nil {
    91  		t.Fatalf("can't make a temp dir: %v", err)
    92  	}
    93  	defer os.RemoveAll(tmpDir)
    94  
    95  	plugMgr := volume.VolumePluginMgr{}
    96  	plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeKubeletVolumeHost(t, tmpDir, nil, nil))
    97  
    98  	plug, err := plugMgr.FindPluginByName("kubernetes.io/vsphere-volume")
    99  	if err != nil {
   100  		t.Errorf("Can't find the plugin by name")
   101  	}
   102  
   103  	spec := &v1.Volume{
   104  		Name: "vol1",
   105  		VolumeSource: v1.VolumeSource{
   106  			VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{
   107  				VolumePath: "[local] test-volume-name.vmdk",
   108  				FSType:     "ext4",
   109  			},
   110  		},
   111  	}
   112  
   113  	// Test Mounter
   114  	fakeManager := &fakePDManager{}
   115  	fakeMounter := mount.NewFakeMounter(nil)
   116  	mounter, err := plug.(*vsphereVolumePlugin).newMounterInternal(volume.NewSpecFromVolume(spec), types.UID("poduid"), fakeManager, fakeMounter)
   117  	if err != nil {
   118  		t.Errorf("Failed to make a new Mounter: %v", err)
   119  	}
   120  	if mounter == nil {
   121  		t.Errorf("Got a nil Mounter")
   122  	}
   123  
   124  	mntPath := filepath.Join(tmpDir, "pods/poduid/volumes/kubernetes.io~vsphere-volume/vol1")
   125  	path := mounter.GetPath()
   126  	if path != mntPath {
   127  		t.Errorf("Got unexpected path: %s", path)
   128  	}
   129  
   130  	if err := mounter.SetUp(volume.MounterArgs{}); err != nil {
   131  		t.Errorf("Expected success, got: %v", err)
   132  	}
   133  
   134  	// Test Unmounter
   135  	fakeManager = &fakePDManager{}
   136  	unmounter, err := plug.(*vsphereVolumePlugin).newUnmounterInternal("vol1", types.UID("poduid"), fakeManager, fakeMounter)
   137  	if err != nil {
   138  		t.Errorf("Failed to make a new Unmounter: %v", err)
   139  	}
   140  	if unmounter == nil {
   141  		t.Errorf("Got a nil Unmounter")
   142  	}
   143  
   144  	if err := unmounter.TearDown(); err != nil {
   145  		t.Errorf("Expected success, got: %v", err)
   146  	}
   147  	if _, err := os.Stat(path); err == nil {
   148  		t.Errorf("TearDown() failed, volume path still exists: %s", path)
   149  	} else if !os.IsNotExist(err) {
   150  		t.Errorf("TearDown() failed: %v", err)
   151  	}
   152  
   153  	// Test Provisioner
   154  	options := volume.VolumeOptions{
   155  		PVC:                           volumetest.CreateTestPVC("100Mi", []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce}),
   156  		PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete,
   157  	}
   158  	provisioner, err := plug.(*vsphereVolumePlugin).newProvisionerInternal(options, &fakePDManager{})
   159  	if err != nil {
   160  		t.Errorf("newProvisionerInternal() failed: %v", err)
   161  	}
   162  	persistentSpec, err := provisioner.Provision(nil, nil)
   163  	if err != nil {
   164  		t.Errorf("Provision() failed: %v", err)
   165  	}
   166  
   167  	if persistentSpec.Spec.PersistentVolumeSource.VsphereVolume.VolumePath != "[local] test-volume-name.vmdk" {
   168  		t.Errorf("Provision() returned unexpected path %s", persistentSpec.Spec.PersistentVolumeSource.VsphereVolume.VolumePath)
   169  	}
   170  
   171  	if persistentSpec.Spec.PersistentVolumeSource.VsphereVolume.StoragePolicyName != "gold" {
   172  		t.Errorf("Provision() returned unexpected storagepolicy name %s", persistentSpec.Spec.PersistentVolumeSource.VsphereVolume.StoragePolicyName)
   173  	}
   174  
   175  	cap := persistentSpec.Spec.Capacity[v1.ResourceStorage]
   176  	size := cap.Value()
   177  	if size != 100*1024 {
   178  		t.Errorf("Provision() returned unexpected volume size: %v", size)
   179  	}
   180  
   181  	// Test Deleter
   182  	volSpec := &volume.Spec{
   183  		PersistentVolume: persistentSpec,
   184  	}
   185  	deleter, err := plug.(*vsphereVolumePlugin).newDeleterInternal(volSpec, &fakePDManager{})
   186  	if err != nil {
   187  		t.Errorf("newDeleterInternal() failed: %v", err)
   188  	}
   189  	err = deleter.Delete()
   190  	if err != nil {
   191  		t.Errorf("Deleter() failed: %v", err)
   192  	}
   193  }
   194  
   195  func TestUnsupportedCloudProvider(t *testing.T) {
   196  	// Initial setup to test volume plugin
   197  	tmpDir, err := utiltesting.MkTmpdir("vsphereVolumeTest")
   198  	if err != nil {
   199  		t.Fatalf("can't make a temp dir: %v", err)
   200  	}
   201  	defer os.RemoveAll(tmpDir)
   202  
   203  	testcases := []struct {
   204  		name          string
   205  		cloudProvider cloudprovider.Interface
   206  		success       bool
   207  	}{
   208  		{name: "nil cloudprovider", cloudProvider: nil},
   209  		{name: "vSphere", cloudProvider: &vsphere.VSphere{}, success: true},
   210  		{name: "fake cloudprovider", cloudProvider: &fake.Cloud{}},
   211  	}
   212  
   213  	for _, tc := range testcases {
   214  		t.Logf("test case: %v", tc.name)
   215  
   216  		plugMgr := volume.VolumePluginMgr{}
   217  		plugMgr.InitPlugins(ProbeVolumePlugins(), nil, /* prober */
   218  			volumetest.NewFakeKubeletVolumeHostWithCloudProvider(t, tmpDir, nil, nil, tc.cloudProvider))
   219  
   220  		plug, err := plugMgr.FindAttachablePluginByName("kubernetes.io/vsphere-volume")
   221  		if err != nil {
   222  			t.Errorf("Can't find the plugin by name")
   223  		}
   224  
   225  		_, err = plug.NewAttacher()
   226  		if !tc.success && err == nil {
   227  			t.Errorf("expected error when creating attacher due to incorrect cloud provider, but got none")
   228  		} else if tc.success && err != nil {
   229  			t.Errorf("expected no error when creating attacher, but got error: %v", err)
   230  		}
   231  
   232  		_, err = plug.NewDetacher()
   233  		if !tc.success && err == nil {
   234  			t.Errorf("expected error when creating detacher due to incorrect cloud provider, but got none")
   235  		} else if tc.success && err != nil {
   236  			t.Errorf("expected no error when creating detacher, but got error: %v", err)
   237  		}
   238  	}
   239  }
   240  
   241  func TestUnsupportedVolumeHost(t *testing.T) {
   242  	tmpDir, err := utiltesting.MkTmpdir("vsphereVolumeTest")
   243  	if err != nil {
   244  		t.Fatalf("can't make a temp dir: %v", err)
   245  	}
   246  	defer os.RemoveAll(tmpDir)
   247  	plugMgr := volume.VolumePluginMgr{}
   248  	plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(t, tmpDir, nil, nil))
   249  
   250  	plug, err := plugMgr.FindPluginByName("kubernetes.io/vsphere-volume")
   251  	if err != nil {
   252  		t.Fatal("Can't find the plugin by name")
   253  	}
   254  
   255  	_, err = plug.ConstructVolumeSpec("", "")
   256  	if err == nil {
   257  		t.Errorf("Expected failure constructing volume spec with unsupported VolumeHost")
   258  	}
   259  }