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  }