diff --git a/test/e2e/framework/volume/fixtures.go b/test/e2e/framework/volume/fixtures.go index 189d813f9e7..bd2e007a2f1 100644 --- a/test/e2e/framework/volume/fixtures.go +++ b/test/e2e/framework/volume/fixtures.go @@ -90,6 +90,22 @@ const ( iSCSIIQNTemplate = "iqn.2003-01.io.k8s:e2e.%s" ) +// SizeRange encapsulates a range of sizes specified as minimum and maximum quantity strings +// Both values are optional. +// If size is not set, it will assume there's not limitation and it may set a very small size (E.g. 1ki) +// as Min and set a considerable big size(E.g. 10Ei) as Max, which make it possible to calculate +// the intersection of given intervals (if it exists) +type SizeRange struct { + // Max quantity specified as a string including units. E.g "3Gi". + // If the Max size is unset, It will be assign a default valid maximum size 10Ei, + // which is defined in test/e2e/storage/testsuites/base.go + Max string + // Min quantity specified as a string including units. E.g "1Gi" + // If the Min size is unset, It will be assign a default valid minimum size 1Ki, + // which is defined in test/e2e/storage/testsuites/base.go + Min string +} + // TestConfig is a struct for configuration of one tests. The test consist of: // - server pod - runs serverImage, exports ports[] // - client pod - does not need any special configuration diff --git a/test/e2e/storage/drivers/csi.go b/test/e2e/storage/drivers/csi.go index d79e0d5804a..d7ecd57c922 100644 --- a/test/e2e/storage/drivers/csi.go +++ b/test/e2e/storage/drivers/csi.go @@ -52,6 +52,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/testpatterns" "k8s.io/kubernetes/test/e2e/storage/testsuites" "k8s.io/kubernetes/test/e2e/storage/utils" @@ -80,6 +81,9 @@ func initHostPathCSIDriver(name string, capabilities map[testsuites.Capability]b SupportedFsType: sets.NewString( "", // Default fsType ), + SupportedSizeRange: volume.SizeRange{ + Min: "1Mi", + }, Capabilities: capabilities, }, manifests: manifests, @@ -159,10 +163,6 @@ func (h *hostpathCSIDriver) GetSnapshotClass(config *testsuites.PerTestConfig) * return testsuites.GetSnapshotClass(snapshotter, parameters, ns, suffix) } -func (h *hostpathCSIDriver) GetClaimSize() string { - return "5Gi" -} - func (h *hostpathCSIDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { ginkgo.By(fmt.Sprintf("deploying %s driver", h.driverInfo.Name)) cancelLogging := testsuites.StartPodLogs(f) @@ -287,10 +287,6 @@ func (m *mockCSIDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTe return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) } -func (m *mockCSIDriver) GetClaimSize() string { - return "5Gi" -} - func (m *mockCSIDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { ginkgo.By("deploying csi mock driver") cancelLogging := testsuites.StartPodLogs(f) @@ -380,6 +376,9 @@ func InitGcePDCSIDriver() testsuites.TestDriver { Name: GCEPDCSIDriverName, FeatureTag: "[Serial]", MaxFileSize: testpatterns.FileSizeMedium, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: sets.NewString( "", // Default fsType "ext2", @@ -432,10 +431,6 @@ func (g *gcePDCSIDriver) GetDynamicProvisionStorageClass(config *testsuites.PerT return testsuites.GetStorageClass(provisioner, parameters, &delayedBinding, ns, suffix) } -func (g *gcePDCSIDriver) GetClaimSize() string { - return "5Gi" -} - func (g *gcePDCSIDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { ginkgo.By("deploying csi gce-pd driver") cancelLogging := testsuites.StartPodLogs(f) diff --git a/test/e2e/storage/drivers/in_tree.go b/test/e2e/storage/drivers/in_tree.go index 995b7693a84..0cd8812d08a 100644 --- a/test/e2e/storage/drivers/in_tree.go +++ b/test/e2e/storage/drivers/in_tree.go @@ -92,6 +92,9 @@ func InitNFSDriver() testsuites.TestDriver { Name: "nfs", InTreePluginName: "kubernetes.io/nfs", MaxFileSize: testpatterns.FileSizeLarge, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: sets.NewString( "", // Default fsType ), @@ -147,10 +150,6 @@ func (n *nfsDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTestCo return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) } -func (n *nfsDriver) GetClaimSize() string { - return "5Gi" -} - func (n *nfsDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { cs := f.ClientSet ns := f.Namespace @@ -235,6 +234,9 @@ func InitGlusterFSDriver() testsuites.TestDriver { Name: "gluster", InTreePluginName: "kubernetes.io/glusterfs", MaxFileSize: testpatterns.FileSizeMedium, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: sets.NewString( "", // Default fsType ), @@ -469,6 +471,9 @@ func InitRbdDriver() testsuites.TestDriver { InTreePluginName: "kubernetes.io/rbd", FeatureTag: "[Feature:Volumes][Serial]", MaxFileSize: testpatterns.FileSizeMedium, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: sets.NewString( "", // Default fsType "ext2", @@ -598,6 +603,9 @@ func InitCephFSDriver() testsuites.TestDriver { InTreePluginName: "kubernetes.io/cephfs", FeatureTag: "[Feature:Volumes][Serial]", MaxFileSize: testpatterns.FileSizeMedium, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: sets.NewString( "", // Default fsType ), @@ -983,6 +991,9 @@ func InitCinderDriver() testsuites.TestDriver { Name: "cinder", InTreePluginName: "kubernetes.io/cinder", MaxFileSize: testpatterns.FileSizeMedium, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: sets.NewString( "", // Default fsType "ext3", @@ -1052,10 +1063,6 @@ func (c *cinderDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTes return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) } -func (c *cinderDriver) GetClaimSize() string { - return "5Gi" -} - func (c *cinderDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { return &testsuites.PerTestConfig{ Driver: c, @@ -1153,9 +1160,12 @@ func InitGcePdDriver() testsuites.TestDriver { ) return &gcePdDriver{ driverInfo: testsuites.DriverInfo{ - Name: "gcepd", - InTreePluginName: "kubernetes.io/gce-pd", - MaxFileSize: testpatterns.FileSizeMedium, + Name: "gcepd", + InTreePluginName: "kubernetes.io/gce-pd", + MaxFileSize: testpatterns.FileSizeMedium, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: supportedTypes, SupportedMountOption: sets.NewString("debug", "nouid32"), TopologyKeys: []string{v1.LabelZoneFailureDomain}, @@ -1230,10 +1240,6 @@ func (g *gcePdDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTest return testsuites.GetStorageClass(provisioner, parameters, &delayedBinding, ns, suffix) } -func (g *gcePdDriver) GetClaimSize() string { - return "5Gi" -} - func (g *gcePdDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { config := &testsuites.PerTestConfig{ Driver: g, @@ -1292,6 +1298,9 @@ func InitVSphereDriver() testsuites.TestDriver { Name: "vsphere", InTreePluginName: "kubernetes.io/vsphere-volume", MaxFileSize: testpatterns.FileSizeMedium, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: sets.NewString( "", // Default fsType "ext4", @@ -1365,10 +1374,6 @@ func (v *vSphereDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTe return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) } -func (v *vSphereDriver) GetClaimSize() string { - return "5Gi" -} - func (v *vSphereDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { return &testsuites.PerTestConfig{ Driver: v, @@ -1415,6 +1420,9 @@ func InitAzureDriver() testsuites.TestDriver { Name: "azure", InTreePluginName: "kubernetes.io/azure-file", MaxFileSize: testpatterns.FileSizeMedium, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: sets.NewString( "", // Default fsType "ext4", @@ -1495,10 +1503,6 @@ func (a *azureDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTest return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) } -func (a *azureDriver) GetClaimSize() string { - return "5Gi" -} - func (a *azureDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { return &testsuites.PerTestConfig{ Driver: a, @@ -1550,6 +1554,9 @@ func InitAwsDriver() testsuites.TestDriver { Name: "aws", InTreePluginName: "kubernetes.io/aws-ebs", MaxFileSize: testpatterns.FileSizeMedium, + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, SupportedFsType: sets.NewString( "", // Default fsType "ext2", @@ -1626,10 +1633,6 @@ func (a *awsDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTestCo return testsuites.GetStorageClass(provisioner, parameters, &delayedBinding, ns, suffix) } -func (a *awsDriver) GetClaimSize() string { - return "5Gi" -} - func (a *awsDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { config := &testsuites.PerTestConfig{ Driver: a, diff --git a/test/e2e/storage/external/BUILD b/test/e2e/storage/external/BUILD index ac0bffc1ec8..dbadb6899fe 100644 --- a/test/e2e/storage/external/BUILD +++ b/test/e2e/storage/external/BUILD @@ -15,6 +15,7 @@ go_library( "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library", "//test/e2e/framework:go_default_library", "//test/e2e/framework/config:go_default_library", + "//test/e2e/framework/volume:go_default_library", "//test/e2e/storage/testpatterns:go_default_library", "//test/e2e/storage/testsuites:go_default_library", "//vendor/github.com/onsi/ginkgo:go_default_library", @@ -30,6 +31,7 @@ go_test( embed = [":go_default_library"], deps = [ "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", + "//test/e2e/framework/volume:go_default_library", "//test/e2e/storage/testsuites:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", ], diff --git a/test/e2e/storage/external/external.go b/test/e2e/storage/external/external.go index 87261fc7406..bb9957a3896 100644 --- a/test/e2e/storage/external/external.go +++ b/test/e2e/storage/external/external.go @@ -31,6 +31,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework/config" + "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/testpatterns" "k8s.io/kubernetes/test/e2e/storage/testsuites" @@ -111,7 +112,9 @@ func loadDriverDefinition(filename string) (*driverDefinition, error) { "", // Default fsType ), }, - ClaimSize: "5Gi", + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, } // TODO: strict checking of the file content once https://github.com/kubernetes/kubernetes/pull/71589 // or something similar is merged. @@ -200,9 +203,9 @@ type driverDefinition struct { ReadOnly bool } - // ClaimSize defines the desired size of dynamically - // provisioned volumes. Default is "5GiB". - ClaimSize string + // SupportedSizeRange defines the desired size of dynamically + // provisioned volumes. + SupportedSizeRange volume.SizeRange // ClientNodeName selects a specific node for scheduling test pods. // Can be left empty. Most drivers should not need this and instead @@ -302,10 +305,6 @@ func (d *driverDefinition) GetSnapshotClass(config *testsuites.PerTestConfig) *u return testsuites.GetSnapshotClass(snapshotter, parameters, ns, suffix) } -func (d *driverDefinition) GetClaimSize() string { - return d.ClaimSize -} - func (d *driverDefinition) GetVolume(config *testsuites.PerTestConfig, volumeNumber int) (map[string]string, bool, bool) { if len(d.InlineVolumes) == 0 { framework.Skipf("%s does not have any InlineVolumeAttributes defined", d.DriverInfo.Name) diff --git a/test/e2e/storage/external/external_test.go b/test/e2e/storage/external/external_test.go index 3d8ed85f2a8..2cf52312a0e 100644 --- a/test/e2e/storage/external/external_test.go +++ b/test/e2e/storage/external/external_test.go @@ -22,6 +22,7 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/testsuites" ) @@ -33,7 +34,9 @@ func TestDriverParameter(t *testing.T) { "", // Default fsType ), }, - ClaimSize: "5Gi", + SupportedSizeRange: volume.SizeRange{ + Min: "5Gi", + }, } testcases := []struct { name string diff --git a/test/e2e/storage/testsuites/BUILD b/test/e2e/storage/testsuites/BUILD index c544a3f6ab5..d4699ccc952 100644 --- a/test/e2e/storage/testsuites/BUILD +++ b/test/e2e/storage/testsuites/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -73,3 +73,10 @@ filegroup( tags = ["automanaged"], visibility = ["//visibility:public"], ) + +go_test( + name = "go_default_test", + srcs = ["base_test.go"], + embed = [":go_default_library"], + deps = ["//test/e2e/framework/volume:go_default_library"], +) diff --git a/test/e2e/storage/testsuites/base.go b/test/e2e/storage/testsuites/base.go index 654ebff4f57..48d8bb1e463 100644 --- a/test/e2e/storage/testsuites/base.go +++ b/test/e2e/storage/testsuites/base.go @@ -20,6 +20,7 @@ import ( "context" "flag" "fmt" + "math" "regexp" "strings" "time" @@ -29,6 +30,7 @@ import ( v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" apierrs "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" utilerrors "k8s.io/apimachinery/pkg/util/errors" @@ -45,6 +47,8 @@ import ( var ( migratedPlugins *string + minValidSize = "1Ki" + maxValidSize = "10Ei" ) func init() { @@ -67,9 +71,10 @@ type TestSuite interface { // TestSuiteInfo represents a set of parameters for TestSuite type TestSuiteInfo struct { - name string // name of the TestSuite - featureTag string // featureTag for the TestSuite - testPatterns []testpatterns.TestPattern // Slice of TestPattern for the TestSuite + name string // name of the TestSuite + featureTag string // featureTag for the TestSuite + testPatterns []testpatterns.TestPattern // Slice of TestPattern for the TestSuite + supportedSizeRange volume.SizeRange // Size range supported by the test suite } // TestResource represents an interface for resources that is used by TestSuite @@ -181,7 +186,7 @@ type genericVolumeTestResource struct { var _ TestResource = &genericVolumeTestResource{} -func createGenericVolumeTestResource(driver TestDriver, config *PerTestConfig, pattern testpatterns.TestPattern) *genericVolumeTestResource { +func createGenericVolumeTestResource(driver TestDriver, config *PerTestConfig, pattern testpatterns.TestPattern, testVolumeSizeRange volume.SizeRange) *genericVolumeTestResource { r := genericVolumeTestResource{ driver: driver, config: config, @@ -214,7 +219,11 @@ func createGenericVolumeTestResource(driver TestDriver, config *PerTestConfig, p case testpatterns.DynamicPV: framework.Logf("Creating resource for dynamic PV") if dDriver, ok := driver.(DynamicPVTestDriver); ok { - claimSize := dDriver.GetClaimSize() + var err error + driverVolumeSizeRange := dDriver.GetDriverInfo().SupportedSizeRange + claimSize, err := getSizeRangesIntersection(testVolumeSizeRange, driverVolumeSizeRange) + framework.ExpectNoError(err, "determine intersection of test size range %+v and driver size range %+v", testVolumeSizeRange, driverVolumeSizeRange) + framework.Logf("Using claimSize:%s, test suite supported size:%v, driver(%s) supported size:%v ", claimSize, testVolumeSizeRange, dDriver.GetDriverInfo().Name, testVolumeSizeRange) r.sc = dDriver.GetDynamicProvisionStorageClass(r.config, pattern.FsType) if pattern.BindingMode != "" { @@ -225,7 +234,7 @@ func createGenericVolumeTestResource(driver TestDriver, config *PerTestConfig, p } ginkgo.By("creating a StorageClass " + r.sc.Name) - var err error + r.sc, err = cs.StorageV1().StorageClasses().Create(r.sc) framework.ExpectNoError(err) @@ -414,6 +423,55 @@ func convertTestConfig(in *PerTestConfig) volume.TestConfig { } } +// getSizeRangesIntersection takes two instances of storage size ranges and determines the +// intersection of the intervals (if it exists) and return the minimum of the intersection +// to be used as the claim size for the test. +// if value not set, that means there's no minimum or maximum size limitation and we set default size for it. +func getSizeRangesIntersection(first volume.SizeRange, second volume.SizeRange) (string, error) { + var firstMin, firstMax, secondMin, secondMax resource.Quantity + var err error + + //if SizeRange is not set, assign a minimum or maximum size + if len(first.Min) == 0 { + first.Min = minValidSize + } + if len(first.Max) == 0 { + first.Max = maxValidSize + } + if len(second.Min) == 0 { + second.Min = minValidSize + } + if len(second.Max) == 0 { + second.Max = maxValidSize + } + + if firstMin, err = resource.ParseQuantity(first.Min); err != nil { + return "", err + } + if firstMax, err = resource.ParseQuantity(first.Max); err != nil { + return "", err + } + if secondMin, err = resource.ParseQuantity(second.Min); err != nil { + return "", err + } + if secondMax, err = resource.ParseQuantity(second.Max); err != nil { + return "", err + } + + interSectionStart := math.Max(float64(firstMin.Value()), float64(secondMin.Value())) + intersectionEnd := math.Min(float64(firstMax.Value()), float64(secondMax.Value())) + + // the minimum of the intersection shall be returned as the claim size + var intersectionMin resource.Quantity + + if intersectionEnd-interSectionStart >= 0 { //have intersection + intersectionMin = *resource.NewQuantity(int64(interSectionStart), "BinarySI") //convert value to BinarySI format. E.g. 5Gi + // return the minimum of the intersection as the claim size + return intersectionMin.String(), nil + } + return "", fmt.Errorf("intersection of size ranges %+v, %+v is null", first, second) +} + func getSnapshot(claimName string, ns, snapshotClassName string) *unstructured.Unstructured { snapshot := &unstructured.Unstructured{ Object: map[string]interface{}{ diff --git a/test/e2e/storage/testsuites/base_test.go b/test/e2e/storage/testsuites/base_test.go new file mode 100644 index 00000000000..59b0ad2e528 --- /dev/null +++ b/test/e2e/storage/testsuites/base_test.go @@ -0,0 +1,475 @@ +/* +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 ( + "testing" + + "k8s.io/kubernetes/test/e2e/framework/volume" +) + +// getSizeRangesIntersection takes two instances of storage size ranges and determines the +// intersection of the intervals (if it exists) and return the minimum of the intersection +// to be used as the claim size for the test. +// if value not set, that means there's no minimum or maximum size limitation and we set default size for it. +// Considerate all corner case as followed: +// first: A,B is regular value and ? means unspecified +// second: C,D is regular value and ? means unspecified +// ---------------------------------------------------------------- +// | \second| min=C,max=?| min=C,max=D| min=?,max=D| min=?,max=?| +// |first\ | | | | | +// |---------------------------------------------------------------- +// |min=A,max=?| #1 | #2 | #3 | #4 | +// ----------------------------------------------------------------- +// |min=A,max=B| #5 | #6 | #7 | #8 | +// ----------------------------------------------------------------- +// |min=?,max=B| #9 | #10 | #11 | #12 | +// ----------------------------------------------------------------- +// |min=?,max=?| #13 | #14 | #15 | #16 | +// |---------------------------------------------------------------| +func Test_getSizeRangesIntersection(t *testing.T) { + type args struct { + first volume.SizeRange + second volume.SizeRange + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "case #1: first{min=A,max=?} second{min=C,max=?} where C > A ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + }, + second: volume.SizeRange{ + Min: "10Gi", + }, + }, + want: "10Gi", + wantErr: false, + }, + { + name: "case #1: first{min=A,max=?} second{min=C,max=?} where C < A ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + }, + second: volume.SizeRange{ + Min: "1Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #2: first{min=A,max=?} second{min=C,max=D} where A > D ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + }, + second: volume.SizeRange{ + Min: "1Gi", + Max: "4Gi", + }, + }, + want: "", + wantErr: true, + }, + { + name: "case #2: first{min=A,max=?} second{min=C,max=D} where D > A > C ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "", + }, + second: volume.SizeRange{ + Min: "3Gi", + Max: "10Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #2: first{min=A,max=?} second{min=C,max=D} where A < C ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "", + }, + second: volume.SizeRange{ + Min: "6Gi", + Max: "10Gi", + }, + }, + want: "6Gi", + wantErr: false, + }, + { + name: "case #3: first{min=A,max=?} second{min=?,max=D} where A > D", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "", + }, + second: volume.SizeRange{ + Max: "1Gi", + }, + }, + want: "", + wantErr: true, + }, + { + name: "case #3: first{min=A,max=?} second{min=?,max=D} where A < D", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "", + }, + second: volume.SizeRange{ + Max: "10Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #4: first{min=A,max=?} second{min=?,max=?} ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "", + }, + second: volume.SizeRange{}, + }, + want: "5Gi", + wantErr: false, + }, + + { + name: "case #5: first{min=A,max=B} second{min=C,max=?} where C < A ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "10Gi", + }, + second: volume.SizeRange{ + Min: "1Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #5: first{min=A,max=B} second{min=C,max=?} where B > C > A ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "10Gi", + }, + second: volume.SizeRange{ + Min: "6Gi", + }, + }, + want: "6Gi", + wantErr: false, + }, + { + name: "case #5: first{min=A,max=B} second{min=C,max=?} where C > B ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "10Gi", + }, + second: volume.SizeRange{ + Min: "15Gi", + }, + }, + want: "", + wantErr: true, + }, + { + name: "case #6: first{min=A,max=B} second{min=C,max=D} where A < B < C < D", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "6Gi", + }, + second: volume.SizeRange{ + Min: "7Gi", + Max: "8Gi", + }, + }, + want: "", + wantErr: true, + }, + { + name: "case #6: first{min=A,max=B} second{min=C,max=D} where A < C < B < D ", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "10Gi", + }, + second: volume.SizeRange{ + Min: "8Gi", + Max: "15Gi", + }, + }, + want: "8Gi", + wantErr: false, + }, + { + name: "case #7: first{min=A,max=B} second{min=?,max=D} where D < A", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "10Gi", + }, + second: volume.SizeRange{ + Max: "3Gi", + }, + }, + want: "", + wantErr: true, + }, + { + name: "case #7: first{min=A,max=B} second{min=?,max=D} where B > D > A", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "10Gi", + }, + second: volume.SizeRange{ + Max: "8Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #7: first{min=A,max=B} second{min=?,max=D} where D > B", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "10Gi", + }, + second: volume.SizeRange{ + Max: "15Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #8: first{min=A,max=B} second{min=?,max=?}", + args: args{ + first: volume.SizeRange{ + Min: "5Gi", + Max: "10Gi", + }, + second: volume.SizeRange{}, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #9: first{min=?,max=B} second{min=C,max=?} where C > B", + args: args{ + first: volume.SizeRange{ + Max: "5Gi", + }, + second: volume.SizeRange{ + Min: "10Gi", + }, + }, + want: "", + wantErr: true, + }, + { + name: "case #9: first{min=?,max=B} second{min=C,max=?} where C < B", + args: args{ + first: volume.SizeRange{ + Max: "10Gi", + }, + second: volume.SizeRange{ + Min: "5Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #10: first{min=?,max=B} second{min=C,max=D} where B > D", + args: args{ + first: volume.SizeRange{ + Max: "10Gi", + }, + second: volume.SizeRange{ + Min: "1Gi", + Max: "5Gi", + }, + }, + want: "1Gi", + wantErr: false, + }, + { + name: "case #10: first{min=?,max=B} second{min=C,max=D} where C < B < D", + args: args{ + first: volume.SizeRange{ + Max: "10Gi", + }, + second: volume.SizeRange{ + Min: "5Gi", + Max: "15Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #10: first{min=?,max=B} second{min=C,max=D} where B < C", + args: args{ + first: volume.SizeRange{ + Max: "10Gi", + }, + second: volume.SizeRange{ + Min: "15Gi", + Max: "20Gi", + }, + }, + want: "", + wantErr: true, + }, + { + name: "case #11: first{min=?,max=B} second{min=?,max=D} where D < B", + args: args{ + first: volume.SizeRange{ + Max: "10Gi", + }, + second: volume.SizeRange{ + Max: "5Gi", + }, + }, + want: minValidSize, + wantErr: false, + }, + { + name: "case #11: first{min=?,max=B} second{min=?,max=D} where D > B", + args: args{ + first: volume.SizeRange{ + Max: "10Gi", + }, + second: volume.SizeRange{ + Max: "15Gi", + }, + }, + want: minValidSize, + wantErr: false, + }, + { + name: "case #12: first{min=?,max=B} second{min=?,max=?} ", + args: args{ + first: volume.SizeRange{ + Max: "10Gi", + }, + second: volume.SizeRange{}, + }, + want: minValidSize, + wantErr: false, + }, + { + name: "case #13: first{min=?,max=?} second{min=C,max=?} ", + args: args{ + first: volume.SizeRange{}, + second: volume.SizeRange{ + Min: "5Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #14: first{min=?,max=?} second{min=C,max=D} where C < D", + args: args{ + first: volume.SizeRange{}, + second: volume.SizeRange{ + Min: "5Gi", + Max: "10Gi", + }, + }, + want: "5Gi", + wantErr: false, + }, + { + name: "case #14: first{min=?,max=?} second{min=C,max=D} where C > D", + args: args{ + first: volume.SizeRange{}, + second: volume.SizeRange{ + Min: "10Gi", + Max: "5Gi", + }, + }, + want: "", + wantErr: true, + }, + { + name: "case #14: first{min=?,max=?} second{min=C,max=D} where C = D", + args: args{ + first: volume.SizeRange{}, + second: volume.SizeRange{ + Min: "1Mi", + Max: "1Mi", + }, + }, + want: "1Mi", + wantErr: false, + }, + { + name: "case #15: first{min=?,max=?} second{min=?,max=D}", + args: args{ + first: volume.SizeRange{}, + second: volume.SizeRange{ + Max: "10Gi", + }, + }, + want: minValidSize, + wantErr: false, + }, + { + name: "case #16: first{min=?,max=?} second{min=?,max=?}", + args: args{ + first: volume.SizeRange{}, + second: volume.SizeRange{}, + }, + want: minValidSize, + wantErr: false, + }, + } + for _, tt := range tests { + got, err := getSizeRangesIntersection(tt.args.first, tt.args.second) + if (err != nil) != tt.wantErr { + t.Errorf("%q. getSizeRangesIntersection() error = %v, wantErr %v", tt.name, err, tt.wantErr) + continue + } + if got != tt.want { + t.Errorf("%q. getSizeRangesIntersection() = %v, want %v", tt.name, got, tt.want) + } + } +} diff --git a/test/e2e/storage/testsuites/disruptive.go b/test/e2e/storage/testsuites/disruptive.go index 540628401ea..ce1dd053563 100644 --- a/test/e2e/storage/testsuites/disruptive.go +++ b/test/e2e/storage/testsuites/disruptive.go @@ -93,7 +93,8 @@ func (s *disruptiveTestSuite) defineTests(driver TestDriver, pattern testpattern framework.Skipf("Driver %s doesn't support %v -- skipping", driver.GetDriverInfo().Name, pattern.VolMode) } - l.resource = createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := s.getTestSuiteInfo().supportedSizeRange + l.resource = createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) } cleanup := func() { diff --git a/test/e2e/storage/testsuites/multivolume.go b/test/e2e/storage/testsuites/multivolume.go index 4f3aae6ba2c..c1bf976b07b 100644 --- a/test/e2e/storage/testsuites/multivolume.go +++ b/test/e2e/storage/testsuites/multivolume.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2epv "k8s.io/kubernetes/test/e2e/framework/pv" + "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/testpatterns" "k8s.io/kubernetes/test/e2e/storage/utils" ) @@ -49,6 +50,9 @@ func InitMultiVolumeTestSuite() TestSuite { testpatterns.BlockVolModePreprovisionedPV, testpatterns.BlockVolModeDynamicPV, }, + supportedSizeRange: volume.SizeRange{ + Min: "1Mi", + }, }, } } @@ -136,7 +140,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter numVols := 2 for i := 0; i < numVols; i++ { - resource := createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + resource := createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) l.resources = append(l.resources, resource) pvcs = append(pvcs, resource.pvc) } @@ -177,7 +182,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter numVols := 2 for i := 0; i < numVols; i++ { - resource := createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + resource := createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) l.resources = append(l.resources, resource) pvcs = append(pvcs, resource.pvc) } @@ -215,7 +221,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter // 1st volume should be block and set filesystem for 2nd and later volumes curPattern.VolMode = v1.PersistentVolumeFilesystem } - resource := createGenericVolumeTestResource(driver, l.config, curPattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + resource := createGenericVolumeTestResource(driver, l.config, curPattern, testVolumeSizeRange) l.resources = append(l.resources, resource) pvcs = append(pvcs, resource.pvc) } @@ -265,7 +272,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter // 1st volume should be block and set filesystem for 2nd and later volumes curPattern.VolMode = v1.PersistentVolumeFilesystem } - resource := createGenericVolumeTestResource(driver, l.config, curPattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + resource := createGenericVolumeTestResource(driver, l.config, curPattern, testVolumeSizeRange) l.resources = append(l.resources, resource) pvcs = append(pvcs, resource.pvc) } @@ -290,7 +298,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter } // Create volume - resource := createGenericVolumeTestResource(l.driver, l.config, pattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + resource := createGenericVolumeTestResource(l.driver, l.config, pattern, testVolumeSizeRange) l.resources = append(l.resources, resource) // Test access to the volume from pods on different node @@ -323,7 +332,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter } // Create volume - resource := createGenericVolumeTestResource(l.driver, l.config, pattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + resource := createGenericVolumeTestResource(l.driver, l.config, pattern, testVolumeSizeRange) l.resources = append(l.resources, resource) // Test access to the volume from pods on different node diff --git a/test/e2e/storage/testsuites/provisioning.go b/test/e2e/storage/testsuites/provisioning.go index dd6c9357e4a..ce87f9652b8 100644 --- a/test/e2e/storage/testsuites/provisioning.go +++ b/test/e2e/storage/testsuites/provisioning.go @@ -74,6 +74,9 @@ func InitProvisioningTestSuite() TestSuite { testpatterns.DefaultFsDynamicPV, testpatterns.NtfsDynamicPV, }, + supportedSizeRange: volume.SizeRange{ + Min: "1Mi", + }, }, } } @@ -130,7 +133,11 @@ func (p *provisioningTestSuite) defineTests(driver TestDriver, pattern testpatte l.config, l.driverCleanup = driver.PrepareTest(f) l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName) l.cs = l.config.Framework.ClientSet - claimSize := dDriver.GetClaimSize() + testVolumeSizeRange := p.getTestSuiteInfo().supportedSizeRange + driverVolumeSizeRange := dDriver.GetDriverInfo().SupportedSizeRange + claimSize, err := getSizeRangesIntersection(testVolumeSizeRange, driverVolumeSizeRange) + framework.ExpectNoError(err, "determine intersection of test size range %+v and driver size range %+v", testVolumeSizeRange, driverVolumeSizeRange) + l.sc = dDriver.GetDynamicProvisionStorageClass(l.config, pattern.FsType) if l.sc == nil { framework.Skipf("Driver %q does not define Dynamic Provision StorageClass - skipping", dInfo.Name) diff --git a/test/e2e/storage/testsuites/snapshottable.go b/test/e2e/storage/testsuites/snapshottable.go index 638a73c82fd..8fce14c57d3 100644 --- a/test/e2e/storage/testsuites/snapshottable.go +++ b/test/e2e/storage/testsuites/snapshottable.go @@ -29,6 +29,7 @@ import ( "k8s.io/client-go/dynamic" "k8s.io/kubernetes/test/e2e/framework" e2epv "k8s.io/kubernetes/test/e2e/framework/pv" + "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/testpatterns" ) @@ -58,6 +59,9 @@ func InitSnapshottableTestSuite() TestSuite { testPatterns: []testpatterns.TestPattern{ testpatterns.DynamicSnapshot, }, + supportedSizeRange: volume.SizeRange{ + Min: "1Mi", + }, }, } } @@ -109,16 +113,19 @@ func (s *snapshottableTestSuite) defineTests(driver TestDriver, pattern testpatt if class == nil { framework.Skipf("Driver %q does not define Dynamic Provision StorageClass - skipping", driver.GetDriverInfo().Name) } - + testVolumeSizeRange := s.getTestSuiteInfo().supportedSizeRange + driverVolumeSizeRange := dDriver.GetDriverInfo().SupportedSizeRange + claimSize, err := getSizeRangesIntersection(testVolumeSizeRange, driverVolumeSizeRange) + framework.ExpectNoError(err, "determine intersection of test size range %+v and driver size range %+v", testVolumeSizeRange, driverVolumeSizeRange) pvc := e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{ - ClaimSize: dDriver.GetClaimSize(), + ClaimSize: claimSize, StorageClassName: &(class.Name), }, config.Framework.Namespace.Name) framework.Logf("In creating storage class object and pvc object for driver - sc: %v, pvc: %v", class, pvc) ginkgo.By("creating a StorageClass " + class.Name) - class, err := cs.StorageV1().StorageClasses().Create(class) + class, err = cs.StorageV1().StorageClasses().Create(class) framework.ExpectNoError(err) defer func() { framework.Logf("deleting storage class %s", class.Name) diff --git a/test/e2e/storage/testsuites/subpath.go b/test/e2e/storage/testsuites/subpath.go index 4e77dcf5b59..d7d1eca86fe 100644 --- a/test/e2e/storage/testsuites/subpath.go +++ b/test/e2e/storage/testsuites/subpath.go @@ -65,6 +65,9 @@ func InitSubPathTestSuite() TestSuite { testpatterns.DefaultFsDynamicPV, testpatterns.NtfsDynamicPV, }, + supportedSizeRange: volume.SizeRange{ + Min: "1Mi", + }, }, } } @@ -111,7 +114,8 @@ func (s *subPathTestSuite) defineTests(driver TestDriver, pattern testpatterns.T // Now do the more expensive test initialization. l.config, l.driverCleanup = driver.PrepareTest(f) l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, driver.GetDriverInfo().InTreePluginName) - l.resource = createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := s.getTestSuiteInfo().supportedSizeRange + l.resource = createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) // Setup subPath test dependent resource volType := pattern.VolType diff --git a/test/e2e/storage/testsuites/testdriver.go b/test/e2e/storage/testsuites/testdriver.go index 8351f30af8d..01c6cb05e4c 100644 --- a/test/e2e/storage/testsuites/testdriver.go +++ b/test/e2e/storage/testsuites/testdriver.go @@ -94,11 +94,6 @@ type DynamicPVTestDriver interface { // 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 - - // GetClaimSize returns the size of the volume that is to be provisioned ("5Gi", "1Mi"). - // The size must be chosen so that the resulting volume is large enough for all - // enabled tests and within the range supported by the underlying storage. - GetClaimSize() string } // EphemeralTestDriver represents an interface for a TestDriver that supports ephemeral inline volumes. @@ -173,6 +168,8 @@ type DriverInfo struct { // Max file size to be tested for this driver MaxFileSize int64 + // The range of 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 diff --git a/test/e2e/storage/testsuites/topology.go b/test/e2e/storage/testsuites/topology.go index 421dcafbec0..ea40ba45392 100644 --- a/test/e2e/storage/testsuites/topology.go +++ b/test/e2e/storage/testsuites/topology.go @@ -139,7 +139,10 @@ func (t *topologyTestSuite) defineTests(driver TestDriver, pattern testpatterns. framework.ExpectNotEqual(l.resource.sc, nil, "driver failed to provide a StorageClass") l.resource.sc.VolumeBindingMode = &pattern.BindingMode - claimSize := dDriver.GetClaimSize() + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + driverVolumeSizeRange := dDriver.GetDriverInfo().SupportedSizeRange + claimSize, err := getSizeRangesIntersection(testVolumeSizeRange, driverVolumeSizeRange) + framework.ExpectNoError(err, "determine intersection of test size range %+v and driver size range %+v", testVolumeSizeRange, driverVolumeSizeRange) l.resource.pvc = e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{ ClaimSize: claimSize, StorageClassName: &(l.resource.sc.Name), diff --git a/test/e2e/storage/testsuites/volume_expand.go b/test/e2e/storage/testsuites/volume_expand.go index 97ec20759c1..0d1a1b60216 100644 --- a/test/e2e/storage/testsuites/volume_expand.go +++ b/test/e2e/storage/testsuites/volume_expand.go @@ -31,6 +31,7 @@ import ( "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2epv "k8s.io/kubernetes/test/e2e/framework/pv" + "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/testpatterns" ) @@ -57,6 +58,9 @@ func InitVolumeExpandTestSuite() TestSuite { testpatterns.DefaultFsDynamicPVAllowExpansion, testpatterns.BlockVolModeDynamicPVAllowExpansion, }, + supportedSizeRange: volume.SizeRange{ + Min: "1Mi", + }, }, } } @@ -104,7 +108,8 @@ func (v *volumeExpandTestSuite) defineTests(driver TestDriver, pattern testpatte // Now do the more expensive test initialization. l.config, l.driverCleanup = driver.PrepareTest(f) l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, driver.GetDriverInfo().InTreePluginName) - l.resource = createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := v.getTestSuiteInfo().supportedSizeRange + l.resource = createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) } cleanup := func() { diff --git a/test/e2e/storage/testsuites/volume_io.go b/test/e2e/storage/testsuites/volume_io.go index e789e1bac3c..3022b5dadee 100644 --- a/test/e2e/storage/testsuites/volume_io.go +++ b/test/e2e/storage/testsuites/volume_io.go @@ -68,6 +68,9 @@ func InitVolumeIOTestSuite() TestSuite { testpatterns.DefaultFsPreprovisionedPV, testpatterns.DefaultFsDynamicPV, }, + supportedSizeRange: volume.SizeRange{ + Min: "1Mi", + }, }, } } @@ -112,7 +115,8 @@ func (t *volumeIOTestSuite) defineTests(driver TestDriver, pattern testpatterns. l.config, l.driverCleanup = driver.PrepareTest(f) l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName) - l.resource = createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + l.resource = createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) if l.resource.volSource == nil { framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name) } diff --git a/test/e2e/storage/testsuites/volumelimits.go b/test/e2e/storage/testsuites/volumelimits.go index b2e5c0aadb9..ac1604dadb8 100644 --- a/test/e2e/storage/testsuites/volumelimits.go +++ b/test/e2e/storage/testsuites/volumelimits.go @@ -139,7 +139,12 @@ func (t *volumeLimitsTestSuite) defineTests(driver TestDriver, pattern testpatte framework.Logf("Node %s can handle %d volumes of driver %s", nodeName, limit, driverInfo.Name) // Create a storage class and generate a PVC. Do not instantiate the PVC yet, keep it for the last pod. - l.resource = createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + driverVolumeSizeRange := dDriver.GetDriverInfo().SupportedSizeRange + claimSize, err := getSizeRangesIntersection(testVolumeSizeRange, driverVolumeSizeRange) + framework.ExpectNoError(err, "determine intersection of test size range %+v and driver size range %+v", testVolumeSizeRange, dDriver) + + l.resource = createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) defer l.resource.cleanupResource() defer func() { @@ -148,9 +153,10 @@ func (t *volumeLimitsTestSuite) defineTests(driver TestDriver, pattern testpatte // Create PVCs for one gigantic pod. ginkgo.By(fmt.Sprintf("Creating %d PVC(s)", limit)) + for i := 0; i < limit; i++ { pvc := e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{ - ClaimSize: dDriver.GetClaimSize(), + ClaimSize: claimSize, StorageClassName: &l.resource.sc.Name, }, l.ns.Name) pvc, err = l.cs.CoreV1().PersistentVolumeClaims(l.ns.Name).Create(pvc) diff --git a/test/e2e/storage/testsuites/volumemode.go b/test/e2e/storage/testsuites/volumemode.go index f70a1824781..73decadbddf 100644 --- a/test/e2e/storage/testsuites/volumemode.go +++ b/test/e2e/storage/testsuites/volumemode.go @@ -35,6 +35,7 @@ import ( "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2epv "k8s.io/kubernetes/test/e2e/framework/pv" + "k8s.io/kubernetes/test/e2e/framework/volume" "k8s.io/kubernetes/test/e2e/storage/testpatterns" "k8s.io/kubernetes/test/e2e/storage/utils" ) @@ -61,6 +62,9 @@ func InitVolumeModeTestSuite() TestSuite { testpatterns.BlockVolModePreprovisionedPV, testpatterns.BlockVolModeDynamicPV, }, + supportedSizeRange: volume.SizeRange{ + Min: "1Mi", + }, }, } } @@ -155,9 +159,13 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern framework.Skipf("Driver %q does not define Dynamic Provision StorageClass - skipping", dInfo.Name) } l.sc.VolumeBindingMode = &volBindMode + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + driverVolumeSizeRange := dInfo.SupportedSizeRange + claimSize, err := getSizeRangesIntersection(testVolumeSizeRange, driverVolumeSizeRange) + framework.ExpectNoError(err, "determine intersection of test size range %+v and driver size range %+v", testVolumeSizeRange, driverVolumeSizeRange) l.pvc = e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{ - ClaimSize: dDriver.GetClaimSize(), + ClaimSize: claimSize, StorageClassName: &(l.sc.Name), VolumeMode: &pattern.VolMode, }, l.ns.Name) @@ -278,7 +286,8 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern ginkgo.It("should fail to use a volume in a pod with mismatched mode [Slow]", func() { skipTestIfBlockNotSupported(driver) init() - l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) defer cleanup() ginkgo.By("Creating pod") @@ -326,7 +335,8 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern skipTestIfBlockNotSupported(driver) } init() - l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) defer cleanup() ginkgo.By("Creating pod") diff --git a/test/e2e/storage/testsuites/volumes.go b/test/e2e/storage/testsuites/volumes.go index 9e357099778..bfcdfef7e2c 100644 --- a/test/e2e/storage/testsuites/volumes.go +++ b/test/e2e/storage/testsuites/volumes.go @@ -71,6 +71,9 @@ func InitVolumesTestSuite() TestSuite { testpatterns.BlockVolModePreprovisionedPV, testpatterns.BlockVolModeDynamicPV, }, + supportedSizeRange: volume.SizeRange{ + Min: "1Mi", + }, }, } } @@ -123,7 +126,8 @@ func (t *volumesTestSuite) defineTests(driver TestDriver, pattern testpatterns.T // Now do the more expensive test initialization. l.config, l.driverCleanup = driver.PrepareTest(f) l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName) - l.resource = createGenericVolumeTestResource(driver, l.config, pattern) + testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange + l.resource = createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange) if l.resource.volSource == nil { framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name) }