k8s.io/kubernetes@v1.29.3/test/e2e/storage/framework/testdriver.go (about) 1 /* 2 Copyright 2018 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 framework 18 19 import ( 20 "context" 21 "time" 22 23 v1 "k8s.io/api/core/v1" 24 storagev1 "k8s.io/api/storage/v1" 25 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 26 "k8s.io/apimachinery/pkg/util/sets" 27 "k8s.io/kubernetes/test/e2e/framework" 28 e2evolume "k8s.io/kubernetes/test/e2e/framework/volume" 29 ) 30 31 // TestDriver represents an interface for a driver to be tested in TestSuite. 32 // Except for GetDriverInfo, all methods will be called at test runtime and thus 33 // can use e2eskipper.Skipf, framework.Fatal, Gomega assertions, etc. 34 type TestDriver interface { 35 // GetDriverInfo returns DriverInfo for the TestDriver. This must be static 36 // information. 37 GetDriverInfo() *DriverInfo 38 39 // SkipUnsupportedTest skips test if Testpattern is not 40 // suitable to test with the TestDriver. It gets called after 41 // parsing parameters of the test suite and before the 42 // framework is initialized. Cheap tests that just check 43 // parameters like the cloud provider can and should be 44 // done in SkipUnsupportedTest to avoid setting up more 45 // expensive resources like framework.Framework. Tests that 46 // depend on a connection to the cluster can be done in 47 // PrepareTest once the framework is ready. 48 SkipUnsupportedTest(TestPattern) 49 50 // PrepareTest is called at test execution time each time a new test case is about to start. 51 // It sets up all necessary resources and returns the per-test configuration. 52 // Cleanup is handled via ginkgo.DeferCleanup inside PrepareTest. 53 PrepareTest(ctx context.Context, f *framework.Framework) *PerTestConfig 54 } 55 56 // TestVolume is the result of PreprovisionedVolumeTestDriver.CreateVolume. 57 // The only common functionality is to delete it. Individual driver interfaces 58 // have additional methods that work with volumes created by them. 59 type TestVolume interface { 60 DeleteVolume(ctx context.Context) 61 } 62 63 // PreprovisionedVolumeTestDriver represents an interface for a TestDriver that has pre-provisioned volume 64 type PreprovisionedVolumeTestDriver interface { 65 TestDriver 66 // CreateVolume creates a pre-provisioned volume of the desired volume type. 67 CreateVolume(ctx context.Context, config *PerTestConfig, volumeType TestVolType) TestVolume 68 } 69 70 // InlineVolumeTestDriver represents an interface for a TestDriver that supports InlineVolume 71 type InlineVolumeTestDriver interface { 72 PreprovisionedVolumeTestDriver 73 74 // GetVolumeSource returns a volumeSource for inline volume. 75 // It will set readOnly and fsType to the volumeSource, if TestDriver supports both of them. 76 // It will return nil, if the TestDriver doesn't support either of the parameters. 77 GetVolumeSource(readOnly bool, fsType string, testVolume TestVolume) *v1.VolumeSource 78 } 79 80 // PreprovisionedPVTestDriver represents an interface for a TestDriver that supports PreprovisionedPV 81 type PreprovisionedPVTestDriver interface { 82 PreprovisionedVolumeTestDriver 83 // GetPersistentVolumeSource returns a PersistentVolumeSource with volume node affinity for pre-provisioned Persistent Volume. 84 // It will set readOnly and fsType to the PersistentVolumeSource, if TestDriver supports both of them. 85 // It will return nil, if the TestDriver doesn't support either of the parameters. 86 GetPersistentVolumeSource(readOnly bool, fsType string, testVolume TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) 87 } 88 89 // DynamicPVTestDriver represents an interface for a TestDriver that supports DynamicPV 90 type DynamicPVTestDriver interface { 91 TestDriver 92 // GetDynamicProvisionStorageClass returns a StorageClass dynamic provision Persistent Volume. 93 // The StorageClass must have 94 // a unique name because GetDynamicProvisionStorageClass might 95 // be called more than once per test. 96 // It will set fsType to the StorageClass, if TestDriver supports it. 97 // It will return nil, if the TestDriver doesn't support it. 98 GetDynamicProvisionStorageClass(ctx context.Context, config *PerTestConfig, fsType string) *storagev1.StorageClass 99 } 100 101 // EphemeralTestDriver represents an interface for a TestDriver that supports ephemeral inline volumes. 102 type EphemeralTestDriver interface { 103 TestDriver 104 105 // GetVolume returns the volume attributes for a certain 106 // inline ephemeral volume, enumerated starting with #0. Some 107 // tests might require more than one volume. They can all be 108 // the same or different, depending what the driver supports 109 // and/or wants to test. 110 // 111 // For each volume, the test driver can return volume attributes, 112 // whether the resulting volume is shared between different pods (i.e. 113 // changes made in one pod are visible in another), and whether the 114 // volume can be mounted read/write or only read-only. 115 GetVolume(config *PerTestConfig, volumeNumber int) (attributes map[string]string, shared bool, readOnly bool) 116 117 // GetCSIDriverName returns the name that was used when registering with 118 // kubelet. Depending on how the driver was deployed, this can be different 119 // from DriverInfo.Name. Starting with Kubernetes 1.16, there must also 120 // be a CSIDriver object under the same name with a "mode" field that enables 121 // usage of the driver for ephemeral inline volumes. 122 GetCSIDriverName(config *PerTestConfig) string 123 } 124 125 // SnapshottableTestDriver represents an interface for a TestDriver that supports DynamicSnapshot 126 type SnapshottableTestDriver interface { 127 TestDriver 128 // GetSnapshotClass returns a SnapshotClass to create snapshot. 129 // It will return nil, if the TestDriver doesn't support it. 130 GetSnapshotClass(ctx context.Context, config *PerTestConfig, parameters map[string]string) *unstructured.Unstructured 131 } 132 133 // CustomTimeoutsTestDriver represents an interface fo a TestDriver that supports custom timeouts. 134 type CustomTimeoutsTestDriver interface { 135 TestDriver 136 GetTimeouts() *framework.TimeoutContext 137 } 138 139 // GetDriverTimeouts returns the timeout of the driver operation 140 func GetDriverTimeouts(driver TestDriver) *framework.TimeoutContext { 141 if d, ok := driver.(CustomTimeoutsTestDriver); ok { 142 return d.GetTimeouts() 143 } 144 return framework.NewTimeoutContext() 145 } 146 147 // Capability represents a feature that a volume plugin supports 148 type Capability string 149 150 // Constants related to capabilities and behavior of the driver. 151 const ( 152 CapPersistence Capability = "persistence" // data is persisted across pod restarts 153 CapBlock Capability = "block" // raw block mode 154 CapFsGroup Capability = "fsGroup" // volume ownership via fsGroup 155 CapVolumeMountGroup Capability = "volumeMountGroup" // Driver has the VolumeMountGroup CSI node capability. Because this is a FSGroup feature, the fsGroup capability must also be set to true. 156 CapExec Capability = "exec" // exec a file in the volume 157 CapSnapshotDataSource Capability = "snapshotDataSource" // support populate data from snapshot 158 CapPVCDataSource Capability = "pvcDataSource" // support populate data from pvc 159 160 // multiple pods on a node can use the same volume concurrently; 161 // for CSI, see: 162 // - https://github.com/container-storage-interface/spec/pull/150 163 // - https://github.com/container-storage-interface/spec/issues/178 164 // - NodeStageVolume in the spec 165 CapMultiPODs Capability = "multipods" 166 167 CapRWX Capability = "RWX" // support ReadWriteMany access modes 168 CapControllerExpansion Capability = "controllerExpansion" // support volume expansion for controller 169 CapNodeExpansion Capability = "nodeExpansion" // support volume expansion for node 170 171 // offlineExpansion and onlineExpansion both default to true when 172 // controllerExpansion is true. The only reason to set offlineExpansion 173 // to false is when a CSI driver can only expand a volume while it's 174 // attached to a pod. Conversely, onlineExpansion can be set to false 175 // if the driver can only expand a volume while it is detached. 176 CapOfflineExpansion Capability = "offlineExpansion" // supports offline volume expansion (default: true) 177 CapOnlineExpansion Capability = "onlineExpansion" // supports online volume expansion (default: true) 178 179 CapVolumeLimits Capability = "volumeLimits" // support volume limits (can be *very* slow) 180 CapSingleNodeVolume Capability = "singleNodeVolume" // support volume that can run on single node (like hostpath) 181 CapTopology Capability = "topology" // support topology 182 183 // The driver publishes storage capacity information: when the storage class 184 // for dynamic provisioning exists, the driver is expected to provide 185 // capacity information for it. 186 CapCapacity Capability = "capacity" 187 188 // Anti-capability for drivers that do not support filesystem resizing of PVCs 189 // that are cloned or restored from a snapshot. 190 CapFSResizeFromSourceNotSupported Capability = "FSResizeFromSourceNotSupported" 191 192 // To support ReadWriteOncePod, the following CSI sidecars must be 193 // updated to these versions or greater: 194 // - csi-provisioner:v3.0.0+ 195 // - csi-attacher:v3.3.0+ 196 // - csi-resizer:v1.3.0+ 197 CapReadWriteOncePod Capability = "readWriteOncePod" 198 199 // The driver can handle two PersistentVolumes with the same VolumeHandle (= volume_id in CSI spec). 200 // This capability is highly recommended for volumes that support ReadWriteMany access mode, 201 // because creating multiple PVs for the same VolumeHandle is frequently used to share a single 202 // volume among multiple namespaces. 203 // Note that this capability needs to be disabled only for CSI drivers that break CSI boundary and 204 // inspect Kubernetes PersistentVolume objects. A CSI driver that implements only CSI and does not 205 // talk to Kubernetes API server in any way should keep this capability enabled, because 206 // they will see the same NodeStage / NodePublish requests as if only one PV existed. 207 CapMultiplePVsSameID Capability = "multiplePVsSameID" 208 209 // The driver supports ReadOnlyMany (ROX) access mode 210 CapReadOnlyMany Capability = "capReadOnlyMany" 211 ) 212 213 // DriverInfo represents static information about a TestDriver. 214 type DriverInfo struct { 215 // Internal name of the driver, this is used as a display name in the test 216 // case and test objects 217 Name string 218 // Fully qualified plugin name as registered in Kubernetes of the in-tree 219 // plugin if it exists and is empty if this DriverInfo represents a CSI 220 // Driver 221 InTreePluginName string 222 TestTags []interface{} // tags for the driver (e.g. framework.WithSlow()) 223 224 // Maximum single file size supported by this driver 225 MaxFileSize int64 226 // The range of disk size supported by this driver 227 SupportedSizeRange e2evolume.SizeRange 228 // Map of string for supported fs type 229 SupportedFsType sets.String 230 // Map of string for supported mount option 231 SupportedMountOption sets.String 232 // [Optional] Map of string for required mount option 233 RequiredMountOption sets.String 234 // Map that represents plugin capabilities 235 Capabilities map[Capability]bool 236 // [Optional] List of access modes required for provisioning, defaults to 237 // RWO if unset 238 RequiredAccessModes []v1.PersistentVolumeAccessMode 239 // [Optional] List of topology keys driver supports 240 TopologyKeys []string 241 // [Optional] Number of allowed topologies the driver requires. 242 // Only relevant if TopologyKeys is set. Defaults to 1. 243 // Example: multi-zonal disk requires at least 2 allowed topologies. 244 NumAllowedTopologies int 245 // [Optional] Scale parameters for stress tests. 246 // TODO(#96241): Rename this field to reflect the tests that consume it. 247 StressTestOptions *StressTestOptions 248 // [Optional] Scale parameters for volume snapshot stress tests. 249 VolumeSnapshotStressTestOptions *VolumeSnapshotStressTestOptions 250 // [Optional] Parameters for performance tests 251 PerformanceTestOptions *PerformanceTestOptions 252 } 253 254 // StressTestOptions contains parameters used for stress tests. 255 type StressTestOptions struct { 256 // Number of pods to create in the test. This may also create 257 // up to 1 volume per pod. 258 NumPods int 259 // Number of times to restart each Pod. 260 NumRestarts int 261 } 262 263 // VolumeSnapshotStressTestOptions contains parameters used for volume snapshot stress tests. 264 type VolumeSnapshotStressTestOptions struct { 265 // Number of pods to create in the test. This may also create 266 // up to 1 volume per pod. 267 NumPods int 268 // Number of snapshots to create for each volume. 269 NumSnapshots int 270 } 271 272 // Metrics to evaluate performance of an operation 273 // TODO: Add metrics like median, mode, standard deviation, percentile 274 type Metrics struct { 275 AvgLatency time.Duration 276 Throughput float64 277 } 278 279 // PerformanceTestProvisioningOptions contains parameters for 280 // testing provisioning operation performance. 281 type PerformanceTestProvisioningOptions struct { 282 VolumeSize string 283 Count int 284 // Expected metrics from PVC creation till PVC being Bound. 285 ExpectedMetrics *Metrics 286 } 287 288 // PerformanceTestOptions contains parameters used for performance tests 289 type PerformanceTestOptions struct { 290 ProvisioningOptions *PerformanceTestProvisioningOptions 291 }