123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- /*
- Copyright 2018 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package testsuites
- import (
- v1 "k8s.io/api/core/v1"
- storagev1 "k8s.io/api/storage/v1"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/apimachinery/pkg/util/sets"
- "k8s.io/kubernetes/test/e2e/framework"
- e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
- "k8s.io/kubernetes/test/e2e/framework/volume"
- "k8s.io/kubernetes/test/e2e/storage/testpatterns"
- )
- // TestDriver represents an interface for a driver to be tested in TestSuite.
- // Except for GetDriverInfo, all methods will be called at test runtime and thus
- // can use e2eskipper.Skipf, framework.Fatal, Gomega assertions, etc.
- type TestDriver interface {
- // GetDriverInfo returns DriverInfo for the TestDriver. This must be static
- // information.
- GetDriverInfo() *DriverInfo
- // SkipUnsupportedTest skips test if Testpattern is not
- // suitable to test with the TestDriver. It gets called after
- // parsing parameters of the test suite and before the
- // framework is initialized. Cheap tests that just check
- // parameters like the cloud provider can and should be
- // done in SkipUnsupportedTest to avoid setting up more
- // expensive resources like framework.Framework. Tests that
- // depend on a connection to the cluster can be done in
- // PrepareTest once the framework is ready.
- SkipUnsupportedTest(testpatterns.TestPattern)
- // PrepareTest is called at test execution time each time a new test case is about to start.
- // It sets up all necessary resources and returns the per-test configuration
- // plus a cleanup function that frees all allocated resources.
- PrepareTest(f *framework.Framework) (*PerTestConfig, func())
- }
- // TestVolume is the result of PreprovisionedVolumeTestDriver.CreateVolume.
- // The only common functionality is to delete it. Individual driver interfaces
- // have additional methods that work with volumes created by them.
- type TestVolume interface {
- DeleteVolume()
- }
- // PreprovisionedVolumeTestDriver represents an interface for a TestDriver that has pre-provisioned volume
- type PreprovisionedVolumeTestDriver interface {
- TestDriver
- // CreateVolume creates a pre-provisioned volume of the desired volume type.
- CreateVolume(config *PerTestConfig, volumeType testpatterns.TestVolType) TestVolume
- }
- // InlineVolumeTestDriver represents an interface for a TestDriver that supports InlineVolume
- type InlineVolumeTestDriver interface {
- PreprovisionedVolumeTestDriver
- // GetVolumeSource returns a volumeSource for inline volume.
- // It will set readOnly and fsType to the volumeSource, if TestDriver supports both of them.
- // It will return nil, if the TestDriver doesn't support either of the parameters.
- GetVolumeSource(readOnly bool, fsType string, testVolume TestVolume) *v1.VolumeSource
- }
- // PreprovisionedPVTestDriver represents an interface for a TestDriver that supports PreprovisionedPV
- type PreprovisionedPVTestDriver interface {
- PreprovisionedVolumeTestDriver
- // GetPersistentVolumeSource returns a PersistentVolumeSource with volume node affinity for pre-provisioned Persistent Volume.
- // It will set readOnly and fsType to the PersistentVolumeSource, if TestDriver supports both of them.
- // It will return nil, if the TestDriver doesn't support either of the parameters.
- GetPersistentVolumeSource(readOnly bool, fsType string, testVolume TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity)
- }
- // DynamicPVTestDriver represents an interface for a TestDriver that supports DynamicPV
- type DynamicPVTestDriver interface {
- TestDriver
- // GetDynamicProvisionStorageClass returns a StorageClass dynamic provision Persistent Volume.
- // The StorageClass must be created in the current test's namespace and have
- // a unique name inside that namespace because GetDynamicProvisionStorageClass might
- // be called more than once per test.
- // It will set fsType to the StorageClass, if TestDriver supports it.
- // It will return nil, if the TestDriver doesn't support it.
- GetDynamicProvisionStorageClass(config *PerTestConfig, fsType string) *storagev1.StorageClass
- }
- // EphemeralTestDriver represents an interface for a TestDriver that supports ephemeral inline volumes.
- type EphemeralTestDriver interface {
- TestDriver
- // GetVolume returns the volume attributes for a certain
- // inline ephemeral volume, enumerated starting with #0. Some
- // tests might require more than one volume. They can all be
- // the same or different, depending what the driver supports
- // and/or wants to test.
- //
- // For each volume, the test driver can return volume attributes,
- // whether the resulting volume is shared between different pods (i.e.
- // changes made in one pod are visible in another), and whether the
- // volume can be mounted read/write or only read-only.
- GetVolume(config *PerTestConfig, volumeNumber int) (attributes map[string]string, shared bool, readOnly bool)
- // GetCSIDriverName returns the name that was used when registering with
- // kubelet. Depending on how the driver was deployed, this can be different
- // from DriverInfo.Name. Starting with Kubernetes 1.16, there must also
- // be a CSIDriver object under the same name with a "mode" field that enables
- // usage of the driver for ephemeral inline volumes.
- GetCSIDriverName(config *PerTestConfig) string
- }
- // SnapshottableTestDriver represents an interface for a TestDriver that supports DynamicSnapshot
- type SnapshottableTestDriver interface {
- TestDriver
- // GetSnapshotClass returns a SnapshotClass to create snapshot.
- // It will return nil, if the TestDriver doesn't support it.
- GetSnapshotClass(config *PerTestConfig) *unstructured.Unstructured
- }
- // Capability represents a feature that a volume plugin supports
- type Capability string
- // Constants related to capability
- const (
- CapPersistence Capability = "persistence" // data is persisted across pod restarts
- CapBlock Capability = "block" // raw block mode
- CapFsGroup Capability = "fsGroup" // volume ownership via fsGroup
- CapExec Capability = "exec" // exec a file in the volume
- CapSnapshotDataSource Capability = "snapshotDataSource" // support populate data from snapshot
- CapPVCDataSource Capability = "pvcDataSource" // support populate data from pvc
- // multiple pods on a node can use the same volume concurrently;
- // for CSI, see:
- // - https://github.com/container-storage-interface/spec/pull/150
- // - https://github.com/container-storage-interface/spec/issues/178
- // - NodeStageVolume in the spec
- CapMultiPODs Capability = "multipods"
- CapRWX Capability = "RWX" // support ReadWriteMany access modes
- CapControllerExpansion Capability = "controllerExpansion" // support volume expansion for controller
- CapNodeExpansion Capability = "nodeExpansion" // support volume expansion for node
- CapVolumeLimits Capability = "volumeLimits" // support volume limits (can be *very* slow)
- CapSingleNodeVolume Capability = "singleNodeVolume" // support volume that can run on single node (like hostpath)
- CapTopology Capability = "topology" // support topology
- )
- // DriverInfo represents static information about a TestDriver.
- type DriverInfo struct {
- // Internal name of the driver, this is used as a display name in the test
- // case and test objects
- Name string
- // Fully qualified plugin name as registered in Kubernetes of the in-tree
- // plugin if it exists and is empty if this DriverInfo represents a CSI
- // Driver
- InTreePluginName string
- FeatureTag string // FeatureTag for the driver
- // Maximum single file size supported by this driver
- MaxFileSize int64
- // The range of disk size supported by this driver
- SupportedSizeRange volume.SizeRange
- // Map of string for supported fs type
- SupportedFsType sets.String
- // Map of string for supported mount option
- SupportedMountOption sets.String
- // [Optional] Map of string for required mount option
- RequiredMountOption sets.String
- // Map that represents plugin capabilities
- Capabilities map[Capability]bool
- // [Optional] List of access modes required for provisioning, defaults to
- // RWO if unset
- RequiredAccessModes []v1.PersistentVolumeAccessMode
- // [Optional] List of topology keys driver supports
- TopologyKeys []string
- // [Optional] Number of allowed topologies the driver requires.
- // Only relevant if TopologyKeys is set. Defaults to 1.
- // Example: multi-zonal disk requires at least 2 allowed topologies.
- NumAllowedTopologies int
- }
- // PerTestConfig represents parameters that control test execution.
- // One instance gets allocated for each test and is then passed
- // via pointer to functions involved in the test.
- type PerTestConfig struct {
- // The test driver for the test.
- Driver TestDriver
- // Some short word that gets inserted into dynamically
- // generated entities (pods, paths) as first part of the name
- // to make debugging easier. Can be the same for different
- // tests inside the test suite.
- Prefix string
- // The framework instance allocated for the current test.
- Framework *framework.Framework
- // If non-empty, Pods using a volume will be scheduled
- // according to the NodeSelection. Otherwise Kubernetes will
- // pick a node.
- ClientNodeSelection e2epod.NodeSelection
- // Some test drivers initialize a storage server. This is
- // the configuration that then has to be used to run tests.
- // The values above are ignored for such tests.
- ServerConfig *volume.TestConfig
- }
- // GetUniqueDriverName returns unique driver name that can be used parallelly in tests
- func (config *PerTestConfig) GetUniqueDriverName() string {
- return config.Driver.GetDriverInfo().Name + "-" + config.Framework.UniqueName
- }
|