type StorageClassTest … type provisioningTestSuite … // InitCustomProvisioningTestSuite returns provisioningTestSuite that implements TestSuite interface // using custom test patterns func InitCustomProvisioningTestSuite(patterns []storageframework.TestPattern) storageframework.TestSuite { … } // InitProvisioningTestSuite returns provisioningTestSuite that implements TestSuite interface\ // using test suite default patterns func InitProvisioningTestSuite() storageframework.TestSuite { … } func (p *provisioningTestSuite) GetTestSuiteInfo() storageframework.TestSuiteInfo { … } func (p *provisioningTestSuite) SkipUnsupportedTests(driver storageframework.TestDriver, pattern storageframework.TestPattern) { … } func (p *provisioningTestSuite) DefineTests(driver storageframework.TestDriver, pattern storageframework.TestPattern) { … } // SetupStorageClass ensures that a StorageClass from a spec exists, if the StorageClass already exists // then it's returned as it is, if it doesn't exist then it's created first // and then returned, if the spec is nil then we return the `default` StorageClass func SetupStorageClass( ctx context.Context, client clientset.Interface, class *storagev1.StorageClass, ) *storagev1.StorageClass { … } // TestDynamicProvisioning tests dynamic provisioning with specified StorageClassTest // it's assumed that the StorageClass `t.Class` is already provisioned, // see #ProvisionStorageClass func (t StorageClassTest) TestDynamicProvisioning(ctx context.Context) *v1.PersistentVolume { … } // getBoundPV returns a PV details. func getBoundPV(ctx context.Context, client clientset.Interface, pvc *v1.PersistentVolumeClaim) (*v1.PersistentVolume, error) { … } // checkProvisioning verifies that the claim is bound and has the correct properties func (t StorageClassTest) checkProvisioning(ctx context.Context, client clientset.Interface, claim *v1.PersistentVolumeClaim, class *storagev1.StorageClass) *v1.PersistentVolume { … } // PVWriteReadSingleNodeCheck checks that a PV retains data on a single node // and returns the PV. // // It starts two pods: // - The first pod writes 'hello word' to the /mnt/test (= the volume) on one node. // - The second pod runs grep 'hello world' on /mnt/test on the same node. // // The node is selected by Kubernetes when scheduling the first // pod. It's then selected via its name for the second pod. // // If both succeed, Kubernetes actually allocated something that is // persistent across pods. // // This is a common test that can be called from a StorageClassTest.PvCheck. func PVWriteReadSingleNodeCheck(ctx context.Context, client clientset.Interface, timeouts *framework.TimeoutContext, claim *v1.PersistentVolumeClaim, node e2epod.NodeSelection) *v1.PersistentVolume { … } // PVMultiNodeCheck checks that a PV retains data when moved between nodes. // // It starts these pods: // - The first pod writes 'hello word' to the /mnt/test (= the volume) on one node. // - The second pod runs grep 'hello world' on /mnt/test on another node. // // The first node is selected by Kubernetes when scheduling the first pod. The second pod uses the same criteria, except that a special anti-affinity // for the first node gets added. This test can only pass if the cluster has more than one // suitable node. The caller has to ensure that. // // If all succeeds, Kubernetes actually allocated something that is // persistent across pods and across nodes. // // This is a common test that can be called from a StorageClassTest.PvCheck. func PVMultiNodeCheck(ctx context.Context, client clientset.Interface, timeouts *framework.TimeoutContext, claim *v1.PersistentVolumeClaim, node e2epod.NodeSelection) { … } // TestBindingWaitForFirstConsumerMultiPVC tests the binding with WaitForFirstConsumer mode func (t StorageClassTest) TestBindingWaitForFirstConsumerMultiPVC(ctx context.Context, claims []*v1.PersistentVolumeClaim, nodeSelector map[string]string, expectUnschedulable bool) ([]*v1.PersistentVolume, *v1.Node) { … } // RunInPodWithVolume runs a command in a pod with given claim mounted to /mnt directory. // It starts, checks, collects output and stops it. func RunInPodWithVolume(ctx context.Context, c clientset.Interface, t *framework.TimeoutContext, ns, claimName, podName, command string, node e2epod.NodeSelection) *v1.Pod { … } // StartInPodWithVolume starts a command in a pod with given claim mounted to /mnt directory // The caller is responsible for checking the pod and deleting it. func StartInPodWithVolume(ctx context.Context, c clientset.Interface, ns, claimName, podName, command string, node e2epod.NodeSelection) *v1.Pod { … } // StartInPodWithVolumeSource starts a command in a pod with given volume mounted to /mnt directory // The caller is responsible for checking the pod and deleting it. func StartInPodWithVolumeSource(ctx context.Context, c clientset.Interface, volSrc v1.VolumeSource, ns, podName, command string, node e2epod.NodeSelection) *v1.Pod { … } // StopPod first tries to log the output of the pod's container, then deletes the pod and // waits for that to succeed. func StopPod(ctx context.Context, c clientset.Interface, pod *v1.Pod) { … } // StopPodAndDependents first tries to log the output of the pod's container, // then deletes the pod and waits for that to succeed. Also waits for all owned // resources to be deleted. func StopPodAndDependents(ctx context.Context, c clientset.Interface, timeouts *framework.TimeoutContext, pod *v1.Pod) { … } func verifyPVCsPending(ctx context.Context, client clientset.Interface, pvcs []*v1.PersistentVolumeClaim) { … } func prepareSnapshotDataSourceForProvisioning( ctx context.Context, f *framework.Framework, config e2evolume.TestConfig, perTestConfig *storageframework.PerTestConfig, pattern storageframework.TestPattern, client clientset.Interface, dynamicClient dynamic.Interface, initClaim *v1.PersistentVolumeClaim, class *storagev1.StorageClass, sDriver storageframework.SnapshottableTestDriver, mode v1.PersistentVolumeMode, injectContent string, ) *v1.TypedObjectReference { … } func preparePVCDataSourceForProvisioning( ctx context.Context, f *framework.Framework, config e2evolume.TestConfig, client clientset.Interface, source *v1.PersistentVolumeClaim, class *storagev1.StorageClass, mode v1.PersistentVolumeMode, injectContent string, ) *v1.TypedObjectReference { … } // findVolumeMountPath looks for a claim name inside a pod and returns an absolute path of its volume mount point. func findVolumeMountPath(pod *v1.Pod, claim *v1.PersistentVolumeClaim) string { … } // getFilesystemSizeBytes returns a total size of a filesystem on given mountPath inside a pod. You can use findVolumeMountPath for mountPath lookup. func getFilesystemSizeBytes(pod *v1.Pod, mountPath string) (int, error) { … } // MultiplePVMountSingleNodeCheck checks that multiple PV pointing to the same underlying storage can be mounted simultaneously on a single node. // // Steps: // - Start Pod1 using PVC1, PV1 (which points to a underlying volume v) on node N1. // - Create PVC2, PV2 and prebind them. PV2 points to the same underlying volume v. // - Start Pod2 using PVC2, PV2 (which points to a underlying volume v) on node N1. func MultiplePVMountSingleNodeCheck(ctx context.Context, client clientset.Interface, timeouts *framework.TimeoutContext, claim *v1.PersistentVolumeClaim, node e2epod.NodeSelection) { … }