Merge pull request #78306 from hoyho/feat/e2e-storage-dynamic-size

feat(e2e): refactor hard-coded provision size
This commit is contained in:
Kubernetes Prow Robot 2019-10-08 17:07:51 -07:00 committed by GitHub
commit 05474a6d84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 697 additions and 81 deletions

View File

@ -90,6 +90,22 @@ const (
iSCSIIQNTemplate = "iqn.2003-01.io.k8s:e2e.%s" 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: // TestConfig is a struct for configuration of one tests. The test consist of:
// - server pod - runs serverImage, exports ports[] // - server pod - runs serverImage, exports ports[]
// - client pod - does not need any special configuration // - client pod - does not need any special configuration

View File

@ -52,6 +52,7 @@ import (
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/test/e2e/framework" "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/testpatterns"
"k8s.io/kubernetes/test/e2e/storage/testsuites" "k8s.io/kubernetes/test/e2e/storage/testsuites"
"k8s.io/kubernetes/test/e2e/storage/utils" "k8s.io/kubernetes/test/e2e/storage/utils"
@ -80,6 +81,9 @@ func initHostPathCSIDriver(name string, capabilities map[testsuites.Capability]b
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
SupportedSizeRange: volume.SizeRange{
Min: "1Mi",
},
Capabilities: capabilities, Capabilities: capabilities,
}, },
manifests: manifests, manifests: manifests,
@ -159,10 +163,6 @@ func (h *hostpathCSIDriver) GetSnapshotClass(config *testsuites.PerTestConfig) *
return testsuites.GetSnapshotClass(snapshotter, parameters, ns, suffix) return testsuites.GetSnapshotClass(snapshotter, parameters, ns, suffix)
} }
func (h *hostpathCSIDriver) GetClaimSize() string {
return "5Gi"
}
func (h *hostpathCSIDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) { func (h *hostpathCSIDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) {
ginkgo.By(fmt.Sprintf("deploying %s driver", h.driverInfo.Name)) ginkgo.By(fmt.Sprintf("deploying %s driver", h.driverInfo.Name))
cancelLogging := testsuites.StartPodLogs(f) cancelLogging := testsuites.StartPodLogs(f)
@ -287,10 +287,6 @@ func (m *mockCSIDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTe
return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) 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()) { func (m *mockCSIDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) {
ginkgo.By("deploying csi mock driver") ginkgo.By("deploying csi mock driver")
cancelLogging := testsuites.StartPodLogs(f) cancelLogging := testsuites.StartPodLogs(f)
@ -380,6 +376,9 @@ func InitGcePDCSIDriver() testsuites.TestDriver {
Name: GCEPDCSIDriverName, Name: GCEPDCSIDriverName,
FeatureTag: "[Serial]", FeatureTag: "[Serial]",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
"ext2", "ext2",
@ -432,10 +431,6 @@ func (g *gcePDCSIDriver) GetDynamicProvisionStorageClass(config *testsuites.PerT
return testsuites.GetStorageClass(provisioner, parameters, &delayedBinding, ns, suffix) 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()) { func (g *gcePDCSIDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) {
ginkgo.By("deploying csi gce-pd driver") ginkgo.By("deploying csi gce-pd driver")
cancelLogging := testsuites.StartPodLogs(f) cancelLogging := testsuites.StartPodLogs(f)

View File

@ -92,6 +92,9 @@ func InitNFSDriver() testsuites.TestDriver {
Name: "nfs", Name: "nfs",
InTreePluginName: "kubernetes.io/nfs", InTreePluginName: "kubernetes.io/nfs",
MaxFileSize: testpatterns.FileSizeLarge, MaxFileSize: testpatterns.FileSizeLarge,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
@ -147,10 +150,6 @@ func (n *nfsDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTestCo
return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) 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()) { func (n *nfsDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) {
cs := f.ClientSet cs := f.ClientSet
ns := f.Namespace ns := f.Namespace
@ -235,6 +234,9 @@ func InitGlusterFSDriver() testsuites.TestDriver {
Name: "gluster", Name: "gluster",
InTreePluginName: "kubernetes.io/glusterfs", InTreePluginName: "kubernetes.io/glusterfs",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
@ -469,6 +471,9 @@ func InitRbdDriver() testsuites.TestDriver {
InTreePluginName: "kubernetes.io/rbd", InTreePluginName: "kubernetes.io/rbd",
FeatureTag: "[Feature:Volumes][Serial]", FeatureTag: "[Feature:Volumes][Serial]",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
"ext2", "ext2",
@ -598,6 +603,9 @@ func InitCephFSDriver() testsuites.TestDriver {
InTreePluginName: "kubernetes.io/cephfs", InTreePluginName: "kubernetes.io/cephfs",
FeatureTag: "[Feature:Volumes][Serial]", FeatureTag: "[Feature:Volumes][Serial]",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
@ -983,6 +991,9 @@ func InitCinderDriver() testsuites.TestDriver {
Name: "cinder", Name: "cinder",
InTreePluginName: "kubernetes.io/cinder", InTreePluginName: "kubernetes.io/cinder",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
"ext3", "ext3",
@ -1052,10 +1063,6 @@ func (c *cinderDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTes
return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) 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()) { func (c *cinderDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) {
return &testsuites.PerTestConfig{ return &testsuites.PerTestConfig{
Driver: c, Driver: c,
@ -1153,9 +1160,12 @@ func InitGcePdDriver() testsuites.TestDriver {
) )
return &gcePdDriver{ return &gcePdDriver{
driverInfo: testsuites.DriverInfo{ driverInfo: testsuites.DriverInfo{
Name: "gcepd", Name: "gcepd",
InTreePluginName: "kubernetes.io/gce-pd", InTreePluginName: "kubernetes.io/gce-pd",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: supportedTypes, SupportedFsType: supportedTypes,
SupportedMountOption: sets.NewString("debug", "nouid32"), SupportedMountOption: sets.NewString("debug", "nouid32"),
TopologyKeys: []string{v1.LabelZoneFailureDomain}, TopologyKeys: []string{v1.LabelZoneFailureDomain},
@ -1230,10 +1240,6 @@ func (g *gcePdDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTest
return testsuites.GetStorageClass(provisioner, parameters, &delayedBinding, ns, suffix) 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()) { func (g *gcePdDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) {
config := &testsuites.PerTestConfig{ config := &testsuites.PerTestConfig{
Driver: g, Driver: g,
@ -1292,6 +1298,9 @@ func InitVSphereDriver() testsuites.TestDriver {
Name: "vsphere", Name: "vsphere",
InTreePluginName: "kubernetes.io/vsphere-volume", InTreePluginName: "kubernetes.io/vsphere-volume",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
"ext4", "ext4",
@ -1365,10 +1374,6 @@ func (v *vSphereDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTe
return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) 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()) { func (v *vSphereDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) {
return &testsuites.PerTestConfig{ return &testsuites.PerTestConfig{
Driver: v, Driver: v,
@ -1415,6 +1420,9 @@ func InitAzureDriver() testsuites.TestDriver {
Name: "azure", Name: "azure",
InTreePluginName: "kubernetes.io/azure-file", InTreePluginName: "kubernetes.io/azure-file",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
"ext4", "ext4",
@ -1495,10 +1503,6 @@ func (a *azureDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTest
return testsuites.GetStorageClass(provisioner, parameters, nil, ns, suffix) 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()) { func (a *azureDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) {
return &testsuites.PerTestConfig{ return &testsuites.PerTestConfig{
Driver: a, Driver: a,
@ -1550,6 +1554,9 @@ func InitAwsDriver() testsuites.TestDriver {
Name: "aws", Name: "aws",
InTreePluginName: "kubernetes.io/aws-ebs", InTreePluginName: "kubernetes.io/aws-ebs",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
"ext2", "ext2",
@ -1626,10 +1633,6 @@ func (a *awsDriver) GetDynamicProvisionStorageClass(config *testsuites.PerTestCo
return testsuites.GetStorageClass(provisioner, parameters, &delayedBinding, ns, suffix) 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()) { func (a *awsDriver) PrepareTest(f *framework.Framework) (*testsuites.PerTestConfig, func()) {
config := &testsuites.PerTestConfig{ config := &testsuites.PerTestConfig{
Driver: a, Driver: a,

View File

@ -15,6 +15,7 @@ go_library(
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
"//test/e2e/framework:go_default_library", "//test/e2e/framework:go_default_library",
"//test/e2e/framework/config: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/testpatterns:go_default_library",
"//test/e2e/storage/testsuites:go_default_library", "//test/e2e/storage/testsuites:go_default_library",
"//vendor/github.com/onsi/ginkgo:go_default_library", "//vendor/github.com/onsi/ginkgo:go_default_library",
@ -30,6 +31,7 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//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", "//test/e2e/storage/testsuites:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
], ],

View File

@ -31,6 +31,7 @@ import (
"k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/kubernetes/scheme"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/framework/config" "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/testpatterns"
"k8s.io/kubernetes/test/e2e/storage/testsuites" "k8s.io/kubernetes/test/e2e/storage/testsuites"
@ -111,7 +112,9 @@ func loadDriverDefinition(filename string) (*driverDefinition, error) {
"", // Default fsType "", // Default fsType
), ),
}, },
ClaimSize: "5Gi", SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
} }
// TODO: strict checking of the file content once https://github.com/kubernetes/kubernetes/pull/71589 // TODO: strict checking of the file content once https://github.com/kubernetes/kubernetes/pull/71589
// or something similar is merged. // or something similar is merged.
@ -200,9 +203,9 @@ type driverDefinition struct {
ReadOnly bool ReadOnly bool
} }
// ClaimSize defines the desired size of dynamically // SupportedSizeRange defines the desired size of dynamically
// provisioned volumes. Default is "5GiB". // provisioned volumes.
ClaimSize string SupportedSizeRange volume.SizeRange
// ClientNodeName selects a specific node for scheduling test pods. // ClientNodeName selects a specific node for scheduling test pods.
// Can be left empty. Most drivers should not need this and instead // 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) 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) { func (d *driverDefinition) GetVolume(config *testsuites.PerTestConfig, volumeNumber int) (map[string]string, bool, bool) {
if len(d.InlineVolumes) == 0 { if len(d.InlineVolumes) == 0 {
framework.Skipf("%s does not have any InlineVolumeAttributes defined", d.DriverInfo.Name) framework.Skipf("%s does not have any InlineVolumeAttributes defined", d.DriverInfo.Name)

View File

@ -22,6 +22,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/test/e2e/framework/volume"
"k8s.io/kubernetes/test/e2e/storage/testsuites" "k8s.io/kubernetes/test/e2e/storage/testsuites"
) )
@ -33,7 +34,9 @@ func TestDriverParameter(t *testing.T) {
"", // Default fsType "", // Default fsType
), ),
}, },
ClaimSize: "5Gi", SupportedSizeRange: volume.SizeRange{
Min: "5Gi",
},
} }
testcases := []struct { testcases := []struct {
name string name string

View File

@ -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( go_library(
name = "go_default_library", name = "go_default_library",
@ -73,3 +73,10 @@ filegroup(
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], 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"],
)

View File

@ -20,6 +20,7 @@ import (
"context" "context"
"flag" "flag"
"fmt" "fmt"
"math"
"regexp" "regexp"
"strings" "strings"
"time" "time"
@ -29,6 +30,7 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1" storagev1 "k8s.io/api/storage/v1"
apierrs "k8s.io/apimachinery/pkg/api/errors" apierrs "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -45,6 +47,8 @@ import (
var ( var (
migratedPlugins *string migratedPlugins *string
minValidSize = "1Ki"
maxValidSize = "10Ei"
) )
func init() { func init() {
@ -67,9 +71,10 @@ type TestSuite interface {
// TestSuiteInfo represents a set of parameters for TestSuite // TestSuiteInfo represents a set of parameters for TestSuite
type TestSuiteInfo struct { type TestSuiteInfo struct {
name string // name of the TestSuite name string // name of the TestSuite
featureTag string // featureTag for the TestSuite featureTag string // featureTag for the TestSuite
testPatterns []testpatterns.TestPattern // Slice of TestPattern 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 // TestResource represents an interface for resources that is used by TestSuite
@ -181,7 +186,7 @@ type genericVolumeTestResource struct {
var _ TestResource = &genericVolumeTestResource{} 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{ r := genericVolumeTestResource{
driver: driver, driver: driver,
config: config, config: config,
@ -214,7 +219,11 @@ func createGenericVolumeTestResource(driver TestDriver, config *PerTestConfig, p
case testpatterns.DynamicPV: case testpatterns.DynamicPV:
framework.Logf("Creating resource for dynamic PV") framework.Logf("Creating resource for dynamic PV")
if dDriver, ok := driver.(DynamicPVTestDriver); ok { 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) r.sc = dDriver.GetDynamicProvisionStorageClass(r.config, pattern.FsType)
if pattern.BindingMode != "" { if pattern.BindingMode != "" {
@ -225,7 +234,7 @@ func createGenericVolumeTestResource(driver TestDriver, config *PerTestConfig, p
} }
ginkgo.By("creating a StorageClass " + r.sc.Name) ginkgo.By("creating a StorageClass " + r.sc.Name)
var err error
r.sc, err = cs.StorageV1().StorageClasses().Create(r.sc) r.sc, err = cs.StorageV1().StorageClasses().Create(r.sc)
framework.ExpectNoError(err) 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 { func getSnapshot(claimName string, ns, snapshotClassName string) *unstructured.Unstructured {
snapshot := &unstructured.Unstructured{ snapshot := &unstructured.Unstructured{
Object: map[string]interface{}{ Object: map[string]interface{}{

View File

@ -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)
}
}
}

View File

@ -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) 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() { cleanup := func() {

View File

@ -28,6 +28,7 @@ import (
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
e2epv "k8s.io/kubernetes/test/e2e/framework/pv" 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/testpatterns"
"k8s.io/kubernetes/test/e2e/storage/utils" "k8s.io/kubernetes/test/e2e/storage/utils"
) )
@ -49,6 +50,9 @@ func InitMultiVolumeTestSuite() TestSuite {
testpatterns.BlockVolModePreprovisionedPV, testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV, testpatterns.BlockVolModeDynamicPV,
}, },
supportedSizeRange: volume.SizeRange{
Min: "1Mi",
},
}, },
} }
} }
@ -136,7 +140,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter
numVols := 2 numVols := 2
for i := 0; i < numVols; i++ { 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) l.resources = append(l.resources, resource)
pvcs = append(pvcs, resource.pvc) pvcs = append(pvcs, resource.pvc)
} }
@ -177,7 +182,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter
numVols := 2 numVols := 2
for i := 0; i < numVols; i++ { 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) l.resources = append(l.resources, resource)
pvcs = append(pvcs, resource.pvc) 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 // 1st volume should be block and set filesystem for 2nd and later volumes
curPattern.VolMode = v1.PersistentVolumeFilesystem 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) l.resources = append(l.resources, resource)
pvcs = append(pvcs, resource.pvc) 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 // 1st volume should be block and set filesystem for 2nd and later volumes
curPattern.VolMode = v1.PersistentVolumeFilesystem 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) l.resources = append(l.resources, resource)
pvcs = append(pvcs, resource.pvc) pvcs = append(pvcs, resource.pvc)
} }
@ -290,7 +298,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter
} }
// Create volume // 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) l.resources = append(l.resources, resource)
// Test access to the volume from pods on different node // Test access to the volume from pods on different node
@ -323,7 +332,8 @@ func (t *multiVolumeTestSuite) defineTests(driver TestDriver, pattern testpatter
} }
// Create volume // 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) l.resources = append(l.resources, resource)
// Test access to the volume from pods on different node // Test access to the volume from pods on different node

View File

@ -74,6 +74,9 @@ func InitProvisioningTestSuite() TestSuite {
testpatterns.DefaultFsDynamicPV, testpatterns.DefaultFsDynamicPV,
testpatterns.NtfsDynamicPV, 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.config, l.driverCleanup = driver.PrepareTest(f)
l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName) l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName)
l.cs = l.config.Framework.ClientSet 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) l.sc = dDriver.GetDynamicProvisionStorageClass(l.config, pattern.FsType)
if l.sc == nil { if l.sc == nil {
framework.Skipf("Driver %q does not define Dynamic Provision StorageClass - skipping", dInfo.Name) framework.Skipf("Driver %q does not define Dynamic Provision StorageClass - skipping", dInfo.Name)

View File

@ -29,6 +29,7 @@ import (
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
e2epv "k8s.io/kubernetes/test/e2e/framework/pv" 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/testpatterns"
) )
@ -58,6 +59,9 @@ func InitSnapshottableTestSuite() TestSuite {
testPatterns: []testpatterns.TestPattern{ testPatterns: []testpatterns.TestPattern{
testpatterns.DynamicSnapshot, testpatterns.DynamicSnapshot,
}, },
supportedSizeRange: volume.SizeRange{
Min: "1Mi",
},
}, },
} }
} }
@ -109,16 +113,19 @@ func (s *snapshottableTestSuite) defineTests(driver TestDriver, pattern testpatt
if class == nil { if class == nil {
framework.Skipf("Driver %q does not define Dynamic Provision StorageClass - skipping", driver.GetDriverInfo().Name) 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{ pvc := e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{
ClaimSize: dDriver.GetClaimSize(), ClaimSize: claimSize,
StorageClassName: &(class.Name), StorageClassName: &(class.Name),
}, config.Framework.Namespace.Name) }, config.Framework.Namespace.Name)
framework.Logf("In creating storage class object and pvc object for driver - sc: %v, pvc: %v", class, pvc) 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) ginkgo.By("creating a StorageClass " + class.Name)
class, err := cs.StorageV1().StorageClasses().Create(class) class, err = cs.StorageV1().StorageClasses().Create(class)
framework.ExpectNoError(err) framework.ExpectNoError(err)
defer func() { defer func() {
framework.Logf("deleting storage class %s", class.Name) framework.Logf("deleting storage class %s", class.Name)

View File

@ -65,6 +65,9 @@ func InitSubPathTestSuite() TestSuite {
testpatterns.DefaultFsDynamicPV, testpatterns.DefaultFsDynamicPV,
testpatterns.NtfsDynamicPV, 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. // Now do the more expensive test initialization.
l.config, l.driverCleanup = driver.PrepareTest(f) l.config, l.driverCleanup = driver.PrepareTest(f)
l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, driver.GetDriverInfo().InTreePluginName) 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 // Setup subPath test dependent resource
volType := pattern.VolType volType := pattern.VolType

View File

@ -94,11 +94,6 @@ type DynamicPVTestDriver interface {
// It will set fsType to the StorageClass, if TestDriver supports it. // It will set fsType to the StorageClass, if TestDriver supports it.
// It will return nil, if the TestDriver doesn't support it. // It will return nil, if the TestDriver doesn't support it.
GetDynamicProvisionStorageClass(config *PerTestConfig, fsType string) *storagev1.StorageClass 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. // 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 // Max file size to be tested for this driver
MaxFileSize int64 MaxFileSize int64
// The range of size supported by this driver
SupportedSizeRange volume.SizeRange
// Map of string for supported fs type // Map of string for supported fs type
SupportedFsType sets.String SupportedFsType sets.String
// Map of string for supported mount option // Map of string for supported mount option

View File

@ -139,7 +139,10 @@ func (t *topologyTestSuite) defineTests(driver TestDriver, pattern testpatterns.
framework.ExpectNotEqual(l.resource.sc, nil, "driver failed to provide a StorageClass") framework.ExpectNotEqual(l.resource.sc, nil, "driver failed to provide a StorageClass")
l.resource.sc.VolumeBindingMode = &pattern.BindingMode 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{ l.resource.pvc = e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{
ClaimSize: claimSize, ClaimSize: claimSize,
StorageClassName: &(l.resource.sc.Name), StorageClassName: &(l.resource.sc.Name),

View File

@ -31,6 +31,7 @@ import (
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
e2epv "k8s.io/kubernetes/test/e2e/framework/pv" 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/testpatterns"
) )
@ -57,6 +58,9 @@ func InitVolumeExpandTestSuite() TestSuite {
testpatterns.DefaultFsDynamicPVAllowExpansion, testpatterns.DefaultFsDynamicPVAllowExpansion,
testpatterns.BlockVolModeDynamicPVAllowExpansion, 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. // Now do the more expensive test initialization.
l.config, l.driverCleanup = driver.PrepareTest(f) l.config, l.driverCleanup = driver.PrepareTest(f)
l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, driver.GetDriverInfo().InTreePluginName) 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() { cleanup := func() {

View File

@ -68,6 +68,9 @@ func InitVolumeIOTestSuite() TestSuite {
testpatterns.DefaultFsPreprovisionedPV, testpatterns.DefaultFsPreprovisionedPV,
testpatterns.DefaultFsDynamicPV, 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.config, l.driverCleanup = driver.PrepareTest(f)
l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName) 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 { if l.resource.volSource == nil {
framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name) framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name)
} }

View File

@ -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) 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. // 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 l.resource.cleanupResource()
defer func() { defer func() {
@ -148,9 +153,10 @@ func (t *volumeLimitsTestSuite) defineTests(driver TestDriver, pattern testpatte
// Create <limit> PVCs for one gigantic pod. // Create <limit> PVCs for one gigantic pod.
ginkgo.By(fmt.Sprintf("Creating %d PVC(s)", limit)) ginkgo.By(fmt.Sprintf("Creating %d PVC(s)", limit))
for i := 0; i < limit; i++ { for i := 0; i < limit; i++ {
pvc := e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{ pvc := e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{
ClaimSize: dDriver.GetClaimSize(), ClaimSize: claimSize,
StorageClassName: &l.resource.sc.Name, StorageClassName: &l.resource.sc.Name,
}, l.ns.Name) }, l.ns.Name)
pvc, err = l.cs.CoreV1().PersistentVolumeClaims(l.ns.Name).Create(pvc) pvc, err = l.cs.CoreV1().PersistentVolumeClaims(l.ns.Name).Create(pvc)

View File

@ -35,6 +35,7 @@ import (
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod" e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
e2epv "k8s.io/kubernetes/test/e2e/framework/pv" 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/testpatterns"
"k8s.io/kubernetes/test/e2e/storage/utils" "k8s.io/kubernetes/test/e2e/storage/utils"
) )
@ -61,6 +62,9 @@ func InitVolumeModeTestSuite() TestSuite {
testpatterns.BlockVolModePreprovisionedPV, testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV, 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) framework.Skipf("Driver %q does not define Dynamic Provision StorageClass - skipping", dInfo.Name)
} }
l.sc.VolumeBindingMode = &volBindMode 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{ l.pvc = e2epv.MakePersistentVolumeClaim(e2epv.PersistentVolumeClaimConfig{
ClaimSize: dDriver.GetClaimSize(), ClaimSize: claimSize,
StorageClassName: &(l.sc.Name), StorageClassName: &(l.sc.Name),
VolumeMode: &pattern.VolMode, VolumeMode: &pattern.VolMode,
}, l.ns.Name) }, 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() { ginkgo.It("should fail to use a volume in a pod with mismatched mode [Slow]", func() {
skipTestIfBlockNotSupported(driver) skipTestIfBlockNotSupported(driver)
init() init()
l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern) testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange
l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange)
defer cleanup() defer cleanup()
ginkgo.By("Creating pod") ginkgo.By("Creating pod")
@ -326,7 +335,8 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
skipTestIfBlockNotSupported(driver) skipTestIfBlockNotSupported(driver)
} }
init() init()
l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern) testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange
l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange)
defer cleanup() defer cleanup()
ginkgo.By("Creating pod") ginkgo.By("Creating pod")

View File

@ -71,6 +71,9 @@ func InitVolumesTestSuite() TestSuite {
testpatterns.BlockVolModePreprovisionedPV, testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV, 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. // Now do the more expensive test initialization.
l.config, l.driverCleanup = driver.PrepareTest(f) l.config, l.driverCleanup = driver.PrepareTest(f)
l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName) 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 { if l.resource.volSource == nil {
framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name) framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name)
} }