Storage testsuite refactor & cleanup

Cleanup all the f.BeforeEach() before new framework to move all the
testskips in the new SkipUnsupportedTests() to make the structure easier.
And provide the standard way of RegisterTests()

Add a InitCustomXXXTestSuite(patterns []patterns) function for each
TestSuite to enable custom test suite definition.
This commit is contained in:
Jiawei Wang 2020-11-07 00:08:06 -08:00
parent bfd826e836
commit 5dc491758c
21 changed files with 464 additions and 414 deletions

View File

@ -37,7 +37,7 @@ var _ = utils.SIGDescribe("CSI Volumes", func() {
curDriver := initDriver() curDriver := initDriver()
ginkgo.Context(testsuites.GetDriverNameWithFeatureTags(curDriver), func() { ginkgo.Context(testsuites.GetDriverNameWithFeatureTags(curDriver), func() {
testsuites.DefineTestSuite(curDriver, testsuites.CSISuites) testsuites.DefineTestSuites(curDriver, testsuites.CSISuites)
}) })
} }
}) })

View File

@ -173,7 +173,7 @@ func AddDriverDefinition(filename string) error {
description := "External Storage " + testsuites.GetDriverNameWithFeatureTags(driver) description := "External Storage " + testsuites.GetDriverNameWithFeatureTags(driver)
ginkgo.Describe(description, func() { ginkgo.Describe(description, func() {
testsuites.DefineTestSuite(driver, testsuites.CSISuites) testsuites.DefineTestSuites(driver, testsuites.CSISuites)
}) })
return nil return nil

View File

@ -0,0 +1,21 @@
StorageClass:
FromExistingClassName: example
DriverInfo:
Name: example
RequiredAccessModes:
- ReadWriteOnce
Capabilities:
persistence: true
multipods: true
exec: true
block: true
fsGroup: true
topology: true
controllerExpansion: true
nodeExpansion: true
volumeLimits: false
snapshotDataSource: true
StressTestOptions:
NumPods: 10
NumRestarts: 20
NumSnapshots: 10

View File

@ -55,7 +55,7 @@ var _ = utils.SIGDescribe("In-tree Volumes", func() {
curDriver := initDriver() curDriver := initDriver()
ginkgo.Context(testsuites.GetDriverNameWithFeatureTags(curDriver), func() { ginkgo.Context(testsuites.GetDriverNameWithFeatureTags(curDriver), func() {
testsuites.DefineTestSuite(curDriver, testsuites.BaseSuites) testsuites.DefineTestSuites(curDriver, testsuites.BaseSuites)
}) })
} }
}) })

View File

@ -31,8 +31,7 @@ import (
"k8s.io/kubernetes/test/e2e/storage/testsuites" "k8s.io/kubernetes/test/e2e/storage/testsuites"
) )
type fakeSuite struct { type fakeSuite struct{}
}
func (f *fakeSuite) GetTestSuiteInfo() testsuites.TestSuiteInfo { func (f *fakeSuite) GetTestSuiteInfo() testsuites.TestSuiteInfo {
return testsuites.TestSuiteInfo{ return testsuites.TestSuiteInfo{
@ -46,7 +45,7 @@ func (f *fakeSuite) GetTestSuiteInfo() testsuites.TestSuiteInfo {
func (f *fakeSuite) DefineTests(testsuites.TestDriver, testpatterns.TestPattern) { func (f *fakeSuite) DefineTests(testsuites.TestDriver, testpatterns.TestPattern) {
} }
func (f *fakeSuite) SkipRedundantSuite(testsuites.TestDriver, testpatterns.TestPattern) { func (f *fakeSuite) SkipUnsupportedTests(testsuites.TestDriver, testpatterns.TestPattern) {
} }
var _ testsuites.TestSuite = &fakeSuite{} var _ testsuites.TestSuite = &fakeSuite{}

View File

@ -95,16 +95,40 @@ var CSISuites = append(BaseSuites,
InitSnapshottableStressTestSuite, InitSnapshottableStressTestSuite,
) )
// TestSuite represents an interface for a set of tests which works with TestDriver // TestSuite represents an interface for a set of tests which works with TestDriver.
// Each testsuite should implement this interface.
// All the functions except GetTestSuiteInfo() should not be called directly. Instead,
// use RegisterTests() to register the tests in a more standard way.
type TestSuite interface { type TestSuite interface {
// GetTestSuiteInfo returns the TestSuiteInfo for this TestSuite
GetTestSuiteInfo() TestSuiteInfo GetTestSuiteInfo() TestSuiteInfo
// DefineTests defines tests of the testpattern for the driver. // DefineTests defines tests of the testpattern for the driver.
// Called inside a Ginkgo context that reflects the current driver and test pattern, // Called inside a Ginkgo context that reflects the current driver and test pattern,
// so the test suite can define tests directly with ginkgo.It. // so the test suite can define tests directly with ginkgo.It.
DefineTests(TestDriver, testpatterns.TestPattern) DefineTests(TestDriver, testpatterns.TestPattern)
// SkipRedundantSuite will skip the test suite based on the given TestPattern and TestDriver // SkipUnsupportedTests will skip the test suite based on the given TestPattern, TestDriver
SkipRedundantSuite(TestDriver, testpatterns.TestPattern) // Testsuite should check if the given pattern and driver works for the "whole testsuite"
// Testcase specific check should happen inside defineTests
SkipUnsupportedTests(TestDriver, testpatterns.TestPattern)
}
// RegisterTests register the driver + pattern combination to the inside TestSuite
// This function actually register tests inside testsuite
func RegisterTests(suite TestSuite, driver TestDriver, pattern testpatterns.TestPattern) {
tsInfo := suite.GetTestSuiteInfo()
testName := fmt.Sprintf("[Testpattern: %s]%s %s%s", pattern.Name, pattern.FeatureTag, tsInfo.Name, tsInfo.FeatureTag)
ginkgo.Context(testName, func() {
ginkgo.BeforeEach(func() {
// skip all the invalid combination of driver and pattern
SkipInvalidDriverPatternCombination(driver, pattern)
// skip the unsupported test pattern and driver combination specific for this TestSuite
suite.SkipUnsupportedTests(driver, pattern)
})
// actually define the tests
// at this step the testsuite should not worry about if the pattern and driver
// does not fit for the whole testsuite. But driver&pattern check
// might still needed for specific independent test cases.
suite.DefineTests(driver, pattern)
})
} }
// TestSuiteInfo represents a set of parameters for TestSuite // TestSuiteInfo represents a set of parameters for TestSuite
@ -115,40 +139,28 @@ type TestSuiteInfo struct {
SupportedSizeRange e2evolume.SizeRange // Size range supported by the test suite SupportedSizeRange e2evolume.SizeRange // Size range supported by the test suite
} }
func getTestNameStr(suite TestSuite, pattern testpatterns.TestPattern) string { // DefineTestSuites defines tests for all testpatterns and all testSuites for a driver
tsInfo := suite.GetTestSuiteInfo() func DefineTestSuites(driver TestDriver, tsInits []func() TestSuite) {
return fmt.Sprintf("[Testpattern: %s]%s %s%s", pattern.Name, pattern.FeatureTag, tsInfo.Name, tsInfo.FeatureTag)
}
// DefineTestSuite defines tests for all testpatterns and all testSuites for a driver
func DefineTestSuite(driver TestDriver, tsInits []func() TestSuite) {
for _, testSuiteInit := range tsInits { for _, testSuiteInit := range tsInits {
suite := testSuiteInit() suite := testSuiteInit()
for _, pattern := range suite.GetTestSuiteInfo().TestPatterns { for _, pattern := range suite.GetTestSuiteInfo().TestPatterns {
p := pattern RegisterTests(suite, driver, pattern)
ginkgo.Context(getTestNameStr(suite, p), func() {
ginkgo.BeforeEach(func() {
// Skip unsupported tests to avoid unnecessary resource initialization
suite.SkipRedundantSuite(driver, p)
skipUnsupportedTest(driver, p)
})
suite.DefineTests(driver, p)
})
} }
} }
} }
// skipUnsupportedTest will skip tests if the combination of driver, and testpattern // SkipInvalidDriverPatternCombination will skip tests if the combination of driver, and testpattern
// is not suitable to be tested. // is not compatible to be tested. This function will be called in the RegisterTests() to make
// Whether it needs to be skipped is checked by following steps: // sure all the testsuites we defined are valid.
// 1. Check if Whether SnapshotType is supported by driver from its interface
// 2. Check if Whether volType is supported by driver from its interface
// 3. Check if fsType is supported
// 4. Check with driver specific logic
// //
// Test suites can also skip tests inside their own DefineTests function or in // Whether it needs to be skipped is checked by following steps:
// 0. Check with driver SkipUnsupportedTest
// 1. Check if volType is supported by driver from its interface
// 2. Check if fsType is supported
//
// Test suites can also skip tests inside their own skipUnsupportedTests function or in
// individual tests. // individual tests.
func skipUnsupportedTest(driver TestDriver, pattern testpatterns.TestPattern) { func SkipInvalidDriverPatternCombination(driver TestDriver, pattern testpatterns.TestPattern) {
dInfo := driver.GetDriverInfo() dInfo := driver.GetDriverInfo()
var isSupported bool var isSupported bool

View File

@ -25,7 +25,6 @@ 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"
e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
e2evolume "k8s.io/kubernetes/test/e2e/framework/volume" e2evolume "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"
@ -35,30 +34,37 @@ type disruptiveTestSuite struct {
tsInfo TestSuiteInfo tsInfo TestSuiteInfo
} }
var _ TestSuite = &disruptiveTestSuite{} // InitCustomDisruptiveTestSuite returns subPathTestSuite that implements TestSuite interface
// using custom test patterns
// InitDisruptiveTestSuite returns subPathTestSuite that implements TestSuite interface func InitCustomDisruptiveTestSuite(patterns []testpatterns.TestPattern) TestSuite {
func InitDisruptiveTestSuite() TestSuite {
return &disruptiveTestSuite{ return &disruptiveTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "disruptive", Name: "disruptive",
FeatureTag: "[Disruptive][LinuxOnly]", FeatureTag: "[Disruptive][LinuxOnly]",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
// FSVolMode is already covered in subpath testsuite
testpatterns.DefaultFsInlineVolume,
testpatterns.FsVolModePreprovisionedPV,
testpatterns.FsVolModeDynamicPV,
testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV,
},
}, },
} }
} }
// InitDisruptiveTestSuite returns subPathTestSuite that implements TestSuite interface
// using test suite default patterns
func InitDisruptiveTestSuite() TestSuite {
testPatterns := []testpatterns.TestPattern{
// FSVolMode is already covered in subpath testsuite
testpatterns.DefaultFsInlineVolume,
testpatterns.FsVolModePreprovisionedPV,
testpatterns.FsVolModeDynamicPV,
testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV,
}
return InitCustomDisruptiveTestSuite(testPatterns)
}
func (s *disruptiveTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (s *disruptiveTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return s.tsInfo return s.tsInfo
} }
func (s *disruptiveTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (s *disruptiveTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap(testpatterns.PreprovisionedPV)) skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap(testpatterns.PreprovisionedPV))
} }
@ -76,11 +82,7 @@ func (s *disruptiveTestSuite) DefineTests(driver TestDriver, pattern testpattern
} }
var l local var l local
// No preconditions to test. Normally they would be in a BeforeEach here. // Beware that it also registers an AfterEach which renders f unusable. Any code using
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("disruptive", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("disruptive", getDriverTimeouts(driver))
@ -92,10 +94,6 @@ func (s *disruptiveTestSuite) DefineTests(driver TestDriver, pattern testpattern
// 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)
if pattern.VolMode == v1.PersistentVolumeBlock && !driver.GetDriverInfo().Capabilities[CapBlock] {
e2eskipper.Skipf("Driver %s doesn't support %v -- skipping", driver.GetDriverInfo().Name, pattern.VolMode)
}
testVolumeSizeRange := s.GetTestSuiteInfo().SupportedSizeRange testVolumeSizeRange := s.GetTestSuiteInfo().SupportedSizeRange
l.resource = CreateVolumeResource(driver, l.config, pattern, testVolumeSizeRange) l.resource = CreateVolumeResource(driver, l.config, pattern, testVolumeSizeRange)
} }

View File

@ -42,9 +42,19 @@ type ephemeralTestSuite struct {
tsInfo TestSuiteInfo tsInfo TestSuiteInfo
} }
var _ TestSuite = &ephemeralTestSuite{} // InitCustomEphemeralTestSuite returns ephemeralTestSuite that implements TestSuite interface
// using custom test patterns
func InitCustomEphemeralTestSuite(patterns []testpatterns.TestPattern) TestSuite {
return &ephemeralTestSuite{
tsInfo: TestSuiteInfo{
Name: "ephemeral",
TestPatterns: patterns,
},
}
}
// InitEphemeralTestSuite returns ephemeralTestSuite that implements TestSuite interface // InitEphemeralTestSuite returns ephemeralTestSuite that implements TestSuite interface
// using test suite default patterns
func InitEphemeralTestSuite() TestSuite { func InitEphemeralTestSuite() TestSuite {
genericLateBinding := testpatterns.DefaultFsGenericEphemeralVolume genericLateBinding := testpatterns.DefaultFsGenericEphemeralVolume
genericLateBinding.Name += " (late-binding)" genericLateBinding.Name += " (late-binding)"
@ -60,19 +70,14 @@ func InitEphemeralTestSuite() TestSuite {
genericImmediateBinding, genericImmediateBinding,
} }
return &ephemeralTestSuite{ return InitCustomEphemeralTestSuite(patterns)
tsInfo: TestSuiteInfo{
Name: "ephemeral",
TestPatterns: patterns,
},
}
} }
func (p *ephemeralTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (p *ephemeralTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return p.tsInfo return p.tsInfo
} }
func (p *ephemeralTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (p *ephemeralTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
} }
func (p *ephemeralTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (p *ephemeralTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -84,31 +89,18 @@ func (p *ephemeralTestSuite) DefineTests(driver TestDriver, pattern testpatterns
resource *VolumeResource resource *VolumeResource
} }
var ( var (
dInfo = driver.GetDriverInfo()
eDriver EphemeralTestDriver eDriver EphemeralTestDriver
l local l local
) )
ginkgo.BeforeEach(func() { // Beware that it also registers an AfterEach which renders f unusable. Any code using
ok := false
switch pattern.VolType {
case testpatterns.CSIInlineVolume:
eDriver, ok = driver.(EphemeralTestDriver)
case testpatterns.GenericEphemeralVolume:
_, ok = driver.(DynamicPVTestDriver)
}
if !ok {
e2eskipper.Skipf("Driver %s doesn't support %q volumes -- skipping", dInfo.Name, pattern.VolType)
}
})
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("ephemeral", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("ephemeral", getDriverTimeouts(driver))
init := func() { init := func() {
if pattern.VolType == testpatterns.CSIInlineVolume {
eDriver, _ = driver.(EphemeralTestDriver)
}
if pattern.VolType == testpatterns.GenericEphemeralVolume { if pattern.VolType == testpatterns.GenericEphemeralVolume {
enabled, err := GenericEphemeralVolumesEnabled(f.ClientSet, f.Timeouts, f.Namespace.Name) enabled, err := GenericEphemeralVolumesEnabled(f.ClientSet, f.Timeouts, f.Namespace.Name)
framework.ExpectNoError(err, "check GenericEphemeralVolume feature") framework.ExpectNoError(err, "check GenericEphemeralVolume feature")

View File

@ -47,14 +47,12 @@ type fsGroupChangePolicyTestSuite struct {
var _ TestSuite = &fsGroupChangePolicyTestSuite{} var _ TestSuite = &fsGroupChangePolicyTestSuite{}
// InitFsGroupChangePolicyTestSuite returns fsGroupChangePolicyTestSuite that implements TestSuite interface // InitCustomFsGroupChangePolicyTestSuite returns fsGroupChangePolicyTestSuite that implements TestSuite interface
func InitFsGroupChangePolicyTestSuite() TestSuite { func InitCustomFsGroupChangePolicyTestSuite(patterns []testpatterns.TestPattern) TestSuite {
return &fsGroupChangePolicyTestSuite{ return &fsGroupChangePolicyTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "fsgroupchangepolicy", Name: "fsgroupchangepolicy",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.DefaultFsDynamicPV,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi", Min: "1Mi",
}, },
@ -62,12 +60,37 @@ func InitFsGroupChangePolicyTestSuite() TestSuite {
} }
} }
// InitFsGroupChangePolicyTestSuite returns fsGroupChangePolicyTestSuite that implements TestSuite interface
func InitFsGroupChangePolicyTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.DefaultFsDynamicPV,
}
return InitCustomFsGroupChangePolicyTestSuite(patterns)
}
func (s *fsGroupChangePolicyTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (s *fsGroupChangePolicyTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return s.tsInfo return s.tsInfo
} }
func (s *fsGroupChangePolicyTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (s *fsGroupChangePolicyTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap(testpatterns.CSIInlineVolume, testpatterns.GenericEphemeralVolume)) skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap(testpatterns.CSIInlineVolume, testpatterns.GenericEphemeralVolume))
dInfo := driver.GetDriverInfo()
if !dInfo.Capabilities[CapFsGroup] {
e2eskipper.Skipf("Driver %q does not support FsGroup - skipping", dInfo.Name)
}
if pattern.VolMode == v1.PersistentVolumeBlock {
e2eskipper.Skipf("Test does not support non-filesystem volume mode - skipping")
}
if pattern.VolType != testpatterns.DynamicPV {
e2eskipper.Skipf("Suite %q does not support %v", s.tsInfo.Name, pattern.VolType)
}
_, ok := driver.(DynamicPVTestDriver)
if !ok {
e2eskipper.Skipf("Driver %s doesn't support %v -- skipping", dInfo.Name, pattern.VolType)
}
} }
func (s *fsGroupChangePolicyTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (s *fsGroupChangePolicyTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -78,29 +101,8 @@ func (s *fsGroupChangePolicyTestSuite) DefineTests(driver TestDriver, pattern te
resource *VolumeResource resource *VolumeResource
} }
var l local var l local
ginkgo.BeforeEach(func() {
dInfo := driver.GetDriverInfo()
if !dInfo.Capabilities[CapFsGroup] {
e2eskipper.Skipf("Driver %q does not support FsGroup - skipping", dInfo.Name)
}
if pattern.VolMode == v1.PersistentVolumeBlock { // Beware that it also registers an AfterEach which renders f unusable. Any code using
e2eskipper.Skipf("Test does not support non-filesystem volume mode - skipping")
}
if pattern.VolType != testpatterns.DynamicPV {
e2eskipper.Skipf("Suite %q does not support %v", s.tsInfo.Name, pattern.VolType)
}
_, ok := driver.(DynamicPVTestDriver)
if !ok {
e2eskipper.Skipf("Driver %s doesn't support %v -- skipping", dInfo.Name, pattern.VolType)
}
})
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("fsgroupchangepolicy", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("fsgroupchangepolicy", getDriverTimeouts(driver))

View File

@ -43,17 +43,13 @@ type multiVolumeTestSuite struct {
var _ TestSuite = &multiVolumeTestSuite{} var _ TestSuite = &multiVolumeTestSuite{}
// InitMultiVolumeTestSuite returns multiVolumeTestSuite that implements TestSuite interface // InitCustomMultiVolumeTestSuite returns multiVolumeTestSuite that implements TestSuite interface
func InitMultiVolumeTestSuite() TestSuite { // using custom test patterns
func InitCustomMultiVolumeTestSuite(patterns []testpatterns.TestPattern) TestSuite {
return &multiVolumeTestSuite{ return &multiVolumeTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "multiVolume [Slow]", Name: "multiVolume [Slow]",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.FsVolModePreprovisionedPV,
testpatterns.FsVolModeDynamicPV,
testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi", Min: "1Mi",
}, },
@ -61,12 +57,28 @@ func InitMultiVolumeTestSuite() TestSuite {
} }
} }
// InitMultiVolumeTestSuite returns multiVolumeTestSuite that implements TestSuite interface
// using test suite default patterns
func InitMultiVolumeTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.FsVolModePreprovisionedPV,
testpatterns.FsVolModeDynamicPV,
testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV,
}
return InitCustomMultiVolumeTestSuite(patterns)
}
func (t *multiVolumeTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (t *multiVolumeTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return t.tsInfo return t.tsInfo
} }
func (t *multiVolumeTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (t *multiVolumeTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
dInfo := driver.GetDriverInfo()
skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap(testpatterns.PreprovisionedPV)) skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap(testpatterns.PreprovisionedPV))
if pattern.VolMode == v1.PersistentVolumeBlock && !dInfo.Capabilities[CapBlock] {
e2eskipper.Skipf("Driver %s doesn't support %v -- skipping", dInfo.Name, pattern.VolMode)
}
} }
func (t *multiVolumeTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (t *multiVolumeTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -86,16 +98,7 @@ func (t *multiVolumeTestSuite) DefineTests(driver TestDriver, pattern testpatter
l local l local
) )
ginkgo.BeforeEach(func() { // Beware that it also registers an AfterEach which renders f unusable. Any code using
// Check preconditions.
if pattern.VolMode == v1.PersistentVolumeBlock && !dInfo.Capabilities[CapBlock] {
e2eskipper.Skipf("Driver %s doesn't support %v -- skipping", dInfo.Name, pattern.VolMode)
}
})
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("multivolume", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("multivolume", getDriverTimeouts(driver))

View File

@ -65,18 +65,13 @@ type provisioningTestSuite struct {
tsInfo TestSuiteInfo tsInfo TestSuiteInfo
} }
var _ TestSuite = &provisioningTestSuite{} // InitCustomProvisioningTestSuite returns provisioningTestSuite that implements TestSuite interface
// using custom test patterns
// InitProvisioningTestSuite returns provisioningTestSuite that implements TestSuite interface func InitCustomProvisioningTestSuite(patterns []testpatterns.TestPattern) TestSuite {
func InitProvisioningTestSuite() TestSuite {
return &provisioningTestSuite{ return &provisioningTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "provisioning", Name: "provisioning",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.DefaultFsDynamicPV,
testpatterns.BlockVolModeDynamicPV,
testpatterns.NtfsDynamicPV,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi", Min: "1Mi",
}, },
@ -84,11 +79,30 @@ func InitProvisioningTestSuite() TestSuite {
} }
} }
// InitProvisioningTestSuite returns provisioningTestSuite that implements TestSuite interface\
// using test suite default patterns
func InitProvisioningTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.DefaultFsDynamicPV,
testpatterns.BlockVolModeDynamicPV,
testpatterns.NtfsDynamicPV,
}
return InitCustomProvisioningTestSuite(patterns)
}
func (p *provisioningTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (p *provisioningTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return p.tsInfo return p.tsInfo
} }
func (p *provisioningTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (p *provisioningTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
// Check preconditions.
if pattern.VolType != testpatterns.DynamicPV {
e2eskipper.Skipf("Suite %q does not support %v", p.tsInfo.Name, pattern.VolType)
}
dInfo := driver.GetDriverInfo()
if pattern.VolMode == v1.PersistentVolumeBlock && !dInfo.Capabilities[CapBlock] {
e2eskipper.Skipf("Driver %s doesn't support %v -- skipping", dInfo.Name, pattern.VolMode)
}
} }
func (p *provisioningTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (p *provisioningTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -110,31 +124,13 @@ func (p *provisioningTestSuite) DefineTests(driver TestDriver, pattern testpatte
l local l local
) )
ginkgo.BeforeEach(func() { // Beware that it also registers an AfterEach which renders f unusable. Any code using
// Check preconditions.
if pattern.VolType != testpatterns.DynamicPV {
e2eskipper.Skipf("Suite %q does not support %v", p.tsInfo.Name, pattern.VolType)
}
if pattern.VolMode == v1.PersistentVolumeBlock && !dInfo.Capabilities[CapBlock] {
e2eskipper.Skipf("Driver %q does not support block volumes - skipping", dInfo.Name)
}
ok := false
dDriver, ok = driver.(DynamicPVTestDriver)
if !ok {
e2eskipper.Skipf("Driver %s doesn't support %v -- skipping", dInfo.Name, pattern.VolType)
}
})
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("provisioning", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("provisioning", getDriverTimeouts(driver))
init := func() { init := func() {
l = local{} l = local{}
dDriver, _ = driver.(DynamicPVTestDriver)
// 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.migrationCheck = newMigrationOpCheck(f.ClientSet, dInfo.InTreePluginName) l.migrationCheck = newMigrationOpCheck(f.ClientSet, dInfo.InTreePluginName)

View File

@ -64,24 +64,18 @@ type snapshottableTestSuite struct {
tsInfo TestSuiteInfo tsInfo TestSuiteInfo
} }
var _ TestSuite = &snapshottableTestSuite{}
var ( var (
sDriver SnapshottableTestDriver sDriver SnapshottableTestDriver
dDriver DynamicPVTestDriver dDriver DynamicPVTestDriver
) )
// InitSnapshottableTestSuite returns snapshottableTestSuite that implements TestSuite interface // InitCustomSnapshottableTestSuite returns snapshottableTestSuite that implements TestSuite interface
func InitSnapshottableTestSuite() TestSuite { // using custom test patterns
func InitCustomSnapshottableTestSuite(patterns []testpatterns.TestPattern) TestSuite {
return &snapshottableTestSuite{ return &snapshottableTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "snapshottable", Name: "snapshottable",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.DynamicSnapshotDelete,
testpatterns.DynamicSnapshotRetain,
testpatterns.PreprovisionedSnapshotDelete,
testpatterns.PreprovisionedSnapshotRetain,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi", Min: "1Mi",
}, },
@ -90,31 +84,39 @@ func InitSnapshottableTestSuite() TestSuite {
} }
} }
// InitSnapshottableTestSuite returns snapshottableTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitSnapshottableTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.DynamicSnapshotDelete,
testpatterns.DynamicSnapshotRetain,
testpatterns.PreprovisionedSnapshotDelete,
testpatterns.PreprovisionedSnapshotRetain,
}
return InitCustomSnapshottableTestSuite(patterns)
}
func (s *snapshottableTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (s *snapshottableTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return s.tsInfo return s.tsInfo
} }
func (s *snapshottableTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (s *snapshottableTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
// Check preconditions.
dInfo := driver.GetDriverInfo()
ok := false
_, ok = driver.(SnapshottableTestDriver)
if !dInfo.Capabilities[CapSnapshotDataSource] || !ok {
e2eskipper.Skipf("Driver %q does not support snapshots - skipping", dInfo.Name)
}
_, ok = driver.(DynamicPVTestDriver)
if !ok {
e2eskipper.Skipf("Driver %q does not support dynamic provisioning - skipping", driver.GetDriverInfo().Name)
}
} }
func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
ginkgo.BeforeEach(func() {
// Check preconditions.
dInfo := driver.GetDriverInfo()
ok := false
sDriver, ok = driver.(SnapshottableTestDriver)
if !dInfo.Capabilities[CapSnapshotDataSource] || !ok {
e2eskipper.Skipf("Driver %q does not support snapshots - skipping", dInfo.Name)
}
dDriver, ok = driver.(DynamicPVTestDriver)
if !ok {
e2eskipper.Skipf("Driver %q does not support dynamic provisioning - skipping", driver.GetDriverInfo().Name)
}
})
// This intentionally comes after checking the preconditions because it // Beware that it also registers an AfterEach which renders f unusable. Any code using
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewDefaultFramework("snapshotting") f := framework.NewDefaultFramework("snapshotting")
@ -133,6 +135,8 @@ func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatt
originalMntTestData string originalMntTestData string
) )
init := func() { init := func() {
sDriver, _ = driver.(SnapshottableTestDriver)
dDriver, _ = driver.(DynamicPVTestDriver)
cleanupSteps = make([]func(), 0) cleanupSteps = make([]func(), 0)
// init snap class, create a source PV, PVC, Pod // init snap class, create a source PV, PVC, Pod
cs = f.ClientSet cs = f.ClientSet

View File

@ -57,17 +57,13 @@ type snapshottableStressTest struct {
cancel context.CancelFunc cancel context.CancelFunc
} }
var _ TestSuite = &snapshottableStressTestSuite{} // InitCustomSnapshottableStressTestSuite returns snapshottableStressTestSuite that implements TestSuite interface
// using custom test patterns
// InitSnapshottableStressTestSuite returns snapshottableStressTestSuite that implements TestSuite interface func InitCustomSnapshottableStressTestSuite(patterns []testpatterns.TestPattern) TestSuite {
func InitSnapshottableStressTestSuite() TestSuite {
return &snapshottableStressTestSuite{ return &snapshottableStressTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "snapshottable-stress", Name: "snapshottable-stress",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.DynamicSnapshotDelete,
testpatterns.DynamicSnapshotRetain,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi", Min: "1Mi",
}, },
@ -76,11 +72,41 @@ func InitSnapshottableStressTestSuite() TestSuite {
} }
} }
// InitSnapshottableStressTestSuite returns snapshottableStressTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitSnapshottableStressTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.DynamicSnapshotDelete,
testpatterns.DynamicSnapshotRetain,
}
return InitCustomSnapshottableStressTestSuite(patterns)
}
func (t *snapshottableStressTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (t *snapshottableStressTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return t.tsInfo return t.tsInfo
} }
func (t *snapshottableStressTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (t *snapshottableStressTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
driverInfo := driver.GetDriverInfo()
var ok bool
if driverInfo.VolumeSnapshotStressTestOptions == nil {
e2eskipper.Skipf("Driver %s doesn't specify snapshot stress test options -- skipping", driverInfo.Name)
}
if driverInfo.VolumeSnapshotStressTestOptions.NumPods <= 0 {
framework.Failf("NumPods in snapshot stress test options must be a positive integer, received: %d", driverInfo.VolumeSnapshotStressTestOptions.NumPods)
}
if driverInfo.VolumeSnapshotStressTestOptions.NumSnapshots <= 0 {
framework.Failf("NumSnapshots in snapshot stress test options must be a positive integer, received: %d", driverInfo.VolumeSnapshotStressTestOptions.NumSnapshots)
}
_, ok = driver.(SnapshottableTestDriver)
if !driverInfo.Capabilities[CapSnapshotDataSource] || !ok {
e2eskipper.Skipf("Driver %q doesn't implement SnapshottableTestDriver - skipping", driverInfo.Name)
}
_, ok = driver.(DynamicPVTestDriver)
if !ok {
e2eskipper.Skipf("Driver %s doesn't implement DynamicPVTestDriver -- skipping", driverInfo.Name)
}
} }
func (t *snapshottableStressTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (t *snapshottableStressTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -91,40 +117,13 @@ func (t *snapshottableStressTestSuite) DefineTests(driver TestDriver, pattern te
stressTest *snapshottableStressTest stressTest *snapshottableStressTest
) )
// Check preconditions before setting up namespace via framework below. // Beware that it also registers an AfterEach which renders f unusable. Any code using
ginkgo.BeforeEach(func() {
driverInfo = driver.GetDriverInfo()
if driverInfo.VolumeSnapshotStressTestOptions == nil {
e2eskipper.Skipf("Driver %s doesn't specify snapshot stress test options -- skipping", driverInfo.Name)
}
if driverInfo.VolumeSnapshotStressTestOptions.NumPods <= 0 {
framework.Failf("NumPods in snapshot stress test options must be a positive integer, received: %d", driverInfo.VolumeSnapshotStressTestOptions.NumPods)
}
if driverInfo.VolumeSnapshotStressTestOptions.NumSnapshots <= 0 {
framework.Failf("NumSnapshots in snapshot stress test options must be a positive integer, received: %d", driverInfo.VolumeSnapshotStressTestOptions.NumSnapshots)
}
// Because we're initializing snapshottableDriver, both vars must exist.
ok := false
snapshottableDriver, ok = driver.(SnapshottableTestDriver)
if !driverInfo.Capabilities[CapSnapshotDataSource] || !ok {
e2eskipper.Skipf("Driver %q doesn't implement SnapshottableTestDriver - skipping", driverInfo.Name)
}
_, ok = driver.(DynamicPVTestDriver)
if !ok {
e2eskipper.Skipf("Driver %s doesn't implement DynamicPVTestDriver -- skipping", driverInfo.Name)
}
})
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewDefaultFramework("snapshottable-stress") f := framework.NewDefaultFramework("snapshottable-stress")
init := func() { init := func() {
driverInfo = driver.GetDriverInfo()
snapshottableDriver, _ = driver.(SnapshottableTestDriver)
cs = f.ClientSet cs = f.ClientSet
config, driverCleanup := driver.PrepareTest(f) config, driverCleanup := driver.PrepareTest(f)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())

View File

@ -58,19 +58,13 @@ type subPathTestSuite struct {
tsInfo TestSuiteInfo tsInfo TestSuiteInfo
} }
var _ TestSuite = &subPathTestSuite{} // InitCustomSubPathTestSuite returns subPathTestSuite that implements TestSuite interface
// using custom test patterns
// InitSubPathTestSuite returns subPathTestSuite that implements TestSuite interface func InitCustomSubPathTestSuite(patterns []testpatterns.TestPattern) TestSuite {
func InitSubPathTestSuite() TestSuite {
return &subPathTestSuite{ return &subPathTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "subPath", Name: "subPath",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.DefaultFsInlineVolume,
testpatterns.DefaultFsPreprovisionedPV,
testpatterns.DefaultFsDynamicPV,
testpatterns.NtfsDynamicPV,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi", Min: "1Mi",
}, },
@ -78,11 +72,23 @@ func InitSubPathTestSuite() TestSuite {
} }
} }
// InitSubPathTestSuite returns subPathTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitSubPathTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.DefaultFsInlineVolume,
testpatterns.DefaultFsPreprovisionedPV,
testpatterns.DefaultFsDynamicPV,
testpatterns.NtfsDynamicPV,
}
return InitCustomSubPathTestSuite(patterns)
}
func (s *subPathTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (s *subPathTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return s.tsInfo return s.tsInfo
} }
func (s *subPathTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (s *subPathTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap( skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap(
testpatterns.PreprovisionedPV, testpatterns.PreprovisionedPV,
testpatterns.InlineVolume)) testpatterns.InlineVolume))
@ -106,11 +112,7 @@ func (s *subPathTestSuite) DefineTests(driver TestDriver, pattern testpatterns.T
} }
var l local var l local
// No preconditions to test. Normally they would be in a BeforeEach here. // Beware that it also registers an AfterEach which renders f unusable. Any code using
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("provisioning", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("provisioning", getDriverTimeouts(driver))

View File

@ -55,26 +55,42 @@ type topologyTest struct {
type topology map[string]string type topology map[string]string
var _ TestSuite = &topologyTestSuite{} // InitCustomTopologyTestSuite returns topologyTestSuite that implements TestSuite interface
// using custom test patterns
// InitTopologyTestSuite returns topologyTestSuite that implements TestSuite interface func InitCustomTopologyTestSuite(patterns []testpatterns.TestPattern) TestSuite {
func InitTopologyTestSuite() TestSuite {
return &topologyTestSuite{ return &topologyTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "topology", Name: "topology",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.TopologyImmediate,
testpatterns.TopologyDelayed,
},
}, },
} }
} }
// InitTopologyTestSuite returns topologyTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitTopologyTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.TopologyImmediate,
testpatterns.TopologyDelayed,
}
return InitCustomTopologyTestSuite(patterns)
}
func (t *topologyTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (t *topologyTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return t.tsInfo return t.tsInfo
} }
func (t *topologyTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (t *topologyTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
dInfo := driver.GetDriverInfo()
var ok bool
_, ok = driver.(DynamicPVTestDriver)
if !ok {
e2eskipper.Skipf("Driver %s doesn't support %v -- skipping", dInfo.Name, pattern.VolType)
}
if !dInfo.Capabilities[CapTopology] {
e2eskipper.Skipf("Driver %q does not support topology - skipping", dInfo.Name)
}
} }
func (t *topologyTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (t *topologyTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -85,28 +101,12 @@ func (t *topologyTestSuite) DefineTests(driver TestDriver, pattern testpatterns.
err error err error
) )
ginkgo.BeforeEach(func() { // Beware that it also registers an AfterEach which renders f unusable. Any code using
// Check preconditions.
ok := false
dDriver, ok = driver.(DynamicPVTestDriver)
if !ok {
e2eskipper.Skipf("Driver %s doesn't support %v -- skipping", dInfo.Name, pattern.VolType)
}
if !dInfo.Capabilities[CapTopology] {
e2eskipper.Skipf("Driver %q does not support topology - skipping", dInfo.Name)
}
})
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("topology", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("topology", getDriverTimeouts(driver))
init := func() topologyTest { init := func() topologyTest {
dDriver, _ = driver.(DynamicPVTestDriver)
l := topologyTest{} l := topologyTest{}
// Now do the more expensive test initialization. // Now do the more expensive test initialization.

View File

@ -55,21 +55,13 @@ type volumeExpandTestSuite struct {
tsInfo TestSuiteInfo tsInfo TestSuiteInfo
} }
var _ TestSuite = &volumeExpandTestSuite{} // InitCustomVolumeExpandTestSuite returns volumeExpandTestSuite that implements TestSuite interface
// using custom test patterns
// InitVolumeExpandTestSuite returns volumeExpandTestSuite that implements TestSuite interface func InitCustomVolumeExpandTestSuite(patterns []testpatterns.TestPattern) TestSuite {
func InitVolumeExpandTestSuite() TestSuite {
return &volumeExpandTestSuite{ return &volumeExpandTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "volume-expand", Name: "volume-expand",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.DefaultFsDynamicPV,
testpatterns.BlockVolModeDynamicPV,
testpatterns.DefaultFsDynamicPVAllowExpansion,
testpatterns.BlockVolModeDynamicPVAllowExpansion,
testpatterns.NtfsDynamicPV,
testpatterns.NtfsDynamicPVAllowExpansion,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Gi", Min: "1Gi",
}, },
@ -77,11 +69,33 @@ func InitVolumeExpandTestSuite() TestSuite {
} }
} }
// InitVolumeExpandTestSuite returns volumeExpandTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitVolumeExpandTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.DefaultFsDynamicPV,
testpatterns.BlockVolModeDynamicPV,
testpatterns.DefaultFsDynamicPVAllowExpansion,
testpatterns.BlockVolModeDynamicPVAllowExpansion,
testpatterns.NtfsDynamicPV,
testpatterns.NtfsDynamicPVAllowExpansion,
}
return InitCustomVolumeExpandTestSuite(patterns)
}
func (v *volumeExpandTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (v *volumeExpandTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return v.tsInfo return v.tsInfo
} }
func (v *volumeExpandTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (v *volumeExpandTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
// Check preconditions.
if !driver.GetDriverInfo().Capabilities[CapControllerExpansion] {
e2eskipper.Skipf("Driver %q does not support volume expansion - skipping", driver.GetDriverInfo().Name)
}
// Check preconditions.
if !driver.GetDriverInfo().Capabilities[CapBlock] && pattern.VolMode == v1.PersistentVolumeBlock {
e2eskipper.Skipf("Driver %q does not support block volume mode - skipping", driver.GetDriverInfo().Name)
}
} }
func (v *volumeExpandTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (v *volumeExpandTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -97,19 +111,7 @@ func (v *volumeExpandTestSuite) DefineTests(driver TestDriver, pattern testpatte
} }
var l local var l local
ginkgo.BeforeEach(func() { // Beware that it also registers an AfterEach which renders f unusable. Any code using
// Check preconditions.
if !driver.GetDriverInfo().Capabilities[CapBlock] && pattern.VolMode == v1.PersistentVolumeBlock {
e2eskipper.Skipf("Driver %q does not support block volume mode - skipping", driver.GetDriverInfo().Name)
}
if !driver.GetDriverInfo().Capabilities[CapControllerExpansion] {
e2eskipper.Skipf("Driver %q does not support volume expansion - skipping", driver.GetDriverInfo().Name)
}
})
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("volume-expand", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("volume-expand", getDriverTimeouts(driver))

View File

@ -59,18 +59,13 @@ type volumeIOTestSuite struct {
tsInfo TestSuiteInfo tsInfo TestSuiteInfo
} }
var _ TestSuite = &volumeIOTestSuite{} // InitCustomVolumeIOTestSuite returns volumeIOTestSuite that implements TestSuite interface
// using custom test patterns
// InitVolumeIOTestSuite returns volumeIOTestSuite that implements TestSuite interface func InitCustomVolumeIOTestSuite(patterns []testpatterns.TestPattern) TestSuite {
func InitVolumeIOTestSuite() TestSuite {
return &volumeIOTestSuite{ return &volumeIOTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "volumeIO", Name: "volumeIO",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.DefaultFsInlineVolume,
testpatterns.DefaultFsPreprovisionedPV,
testpatterns.DefaultFsDynamicPV,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi", Min: "1Mi",
}, },
@ -78,11 +73,22 @@ func InitVolumeIOTestSuite() TestSuite {
} }
} }
// InitVolumeIOTestSuite returns volumeIOTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitVolumeIOTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.DefaultFsInlineVolume,
testpatterns.DefaultFsPreprovisionedPV,
testpatterns.DefaultFsDynamicPV,
}
return InitCustomVolumeIOTestSuite(patterns)
}
func (t *volumeIOTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (t *volumeIOTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return t.tsInfo return t.tsInfo
} }
func (t *volumeIOTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (t *volumeIOTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap( skipVolTypePatterns(pattern, driver, testpatterns.NewVolTypeMap(
testpatterns.PreprovisionedPV, testpatterns.PreprovisionedPV,
testpatterns.InlineVolume)) testpatterns.InlineVolume))
@ -102,11 +108,7 @@ func (t *volumeIOTestSuite) DefineTests(driver TestDriver, pattern testpatterns.
l local l local
) )
// No preconditions to test. Normally they would be in a BeforeEach here. // Beware that it also registers an AfterEach which renders f unusable. Any code using
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("volumeio", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("volumeio", getDriverTimeouts(driver))

View File

@ -57,24 +57,49 @@ type volumeStressTest struct {
var _ TestSuite = &volumeStressTestSuite{} var _ TestSuite = &volumeStressTestSuite{}
// InitVolumeStressTestSuite returns volumeStressTestSuite that implements TestSuite interface // InitCustomVolumeStressTestSuite returns volumeStressTestSuite that implements TestSuite interface
func InitVolumeStressTestSuite() TestSuite { // using custom test patterns
func InitCustomVolumeStressTestSuite(patterns []testpatterns.TestPattern) TestSuite {
return &volumeStressTestSuite{ return &volumeStressTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "volume-stress", Name: "volume-stress",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.DefaultFsDynamicPV,
testpatterns.BlockVolModeDynamicPV,
},
}, },
} }
} }
// InitVolumeStressTestSuite returns volumeStressTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitVolumeStressTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.DefaultFsDynamicPV,
testpatterns.BlockVolModeDynamicPV,
}
return InitCustomVolumeStressTestSuite(patterns)
}
func (t *volumeStressTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (t *volumeStressTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return t.tsInfo return t.tsInfo
} }
func (t *volumeStressTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (t *volumeStressTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
dInfo := driver.GetDriverInfo()
if dInfo.StressTestOptions == nil {
e2eskipper.Skipf("Driver %s doesn't specify stress test options -- skipping", dInfo.Name)
}
if dInfo.StressTestOptions.NumPods <= 0 {
framework.Failf("NumPods in stress test options must be a positive integer, received: %d", dInfo.StressTestOptions.NumPods)
}
if dInfo.StressTestOptions.NumRestarts <= 0 {
framework.Failf("NumRestarts in stress test options must be a positive integer, received: %d", dInfo.StressTestOptions.NumRestarts)
}
if _, ok := driver.(DynamicPVTestDriver); !ok {
e2eskipper.Skipf("Driver %s doesn't implement DynamicPVTestDriver -- skipping", dInfo.Name)
}
if !driver.GetDriverInfo().Capabilities[CapBlock] && pattern.VolMode == v1.PersistentVolumeBlock {
e2eskipper.Skipf("Driver %q does not support block volume mode - skipping", dInfo.Name)
}
} }
func (t *volumeStressTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (t *volumeStressTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -84,30 +109,7 @@ func (t *volumeStressTestSuite) DefineTests(driver TestDriver, pattern testpatte
l *volumeStressTest l *volumeStressTest
) )
// Check preconditions before setting up namespace via framework below. // Beware that it also registers an AfterEach which renders f unusable. Any code using
ginkgo.BeforeEach(func() {
if dInfo.StressTestOptions == nil {
e2eskipper.Skipf("Driver %s doesn't specify stress test options -- skipping", dInfo.Name)
}
if dInfo.StressTestOptions.NumPods <= 0 {
framework.Failf("NumPods in stress test options must be a positive integer, received: %d", dInfo.StressTestOptions.NumPods)
}
if dInfo.StressTestOptions.NumRestarts <= 0 {
framework.Failf("NumRestarts in stress test options must be a positive integer, received: %d", dInfo.StressTestOptions.NumRestarts)
}
if _, ok := driver.(DynamicPVTestDriver); !ok {
e2eskipper.Skipf("Driver %s doesn't implement DynamicPVTestDriver -- skipping", dInfo.Name)
}
if !driver.GetDriverInfo().Capabilities[CapBlock] && pattern.VolMode == v1.PersistentVolumeBlock {
e2eskipper.Skipf("Driver %q does not support block volume mode - skipping", dInfo.Name)
}
})
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("stress", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("stress", getDriverTimeouts(driver))

View File

@ -57,23 +57,31 @@ const (
var _ TestSuite = &volumeLimitsTestSuite{} var _ TestSuite = &volumeLimitsTestSuite{}
// InitVolumeLimitsTestSuite returns volumeLimitsTestSuite that implements TestSuite interface // InitCustomVolumeLimitsTestSuite returns volumeLimitsTestSuite that implements TestSuite interface
func InitVolumeLimitsTestSuite() TestSuite { // using custom test patterns
func InitCustomVolumeLimitsTestSuite(patterns []testpatterns.TestPattern) TestSuite {
return &volumeLimitsTestSuite{ return &volumeLimitsTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "volumeLimits", Name: "volumeLimits",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.FsVolModeDynamicPV,
},
}, },
} }
} }
// InitVolumeLimitsTestSuite returns volumeLimitsTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitVolumeLimitsTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.FsVolModeDynamicPV,
}
return InitCustomVolumeLimitsTestSuite(patterns)
}
func (t *volumeLimitsTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (t *volumeLimitsTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return t.tsInfo return t.tsInfo
} }
func (t *volumeLimitsTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (t *volumeLimitsTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
} }
func (t *volumeLimitsTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (t *volumeLimitsTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -99,7 +107,8 @@ func (t *volumeLimitsTestSuite) DefineTests(driver TestDriver, pattern testpatte
l local l local
) )
// No preconditions to test. Normally they would be in a BeforeEach here. // Beware that it also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("volumelimits", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("volumelimits", getDriverTimeouts(driver))
// This checks that CSIMaxVolumeLimitChecker works as expected. // This checks that CSIMaxVolumeLimitChecker works as expected.

View File

@ -54,17 +54,13 @@ type volumeModeTestSuite struct {
var _ TestSuite = &volumeModeTestSuite{} var _ TestSuite = &volumeModeTestSuite{}
// InitVolumeModeTestSuite returns volumeModeTestSuite that implements TestSuite interface // InitCustomVolumeModeTestSuite returns volumeModeTestSuite that implements TestSuite interface
func InitVolumeModeTestSuite() TestSuite { // using custom test patterns
func InitCustomVolumeModeTestSuite(patterns []testpatterns.TestPattern) TestSuite {
return &volumeModeTestSuite{ return &volumeModeTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "volumeMode", Name: "volumeMode",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
testpatterns.FsVolModePreprovisionedPV,
testpatterns.FsVolModeDynamicPV,
testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi", Min: "1Mi",
}, },
@ -72,11 +68,23 @@ func InitVolumeModeTestSuite() TestSuite {
} }
} }
// InitVolumeModeTestSuite returns volumeModeTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitVolumeModeTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
testpatterns.FsVolModePreprovisionedPV,
testpatterns.FsVolModeDynamicPV,
testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV,
}
return InitCustomVolumeModeTestSuite(patterns)
}
func (t *volumeModeTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (t *volumeModeTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return t.tsInfo return t.tsInfo
} }
func (t *volumeModeTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (t *volumeModeTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
} }
func (t *volumeModeTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) { func (t *volumeModeTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
@ -96,11 +104,7 @@ func (t *volumeModeTestSuite) DefineTests(driver TestDriver, pattern testpattern
l local l local
) )
// No preconditions to test. Normally they would be in a BeforeEach here. // Beware that it also registers an AfterEach which renders f unusable. Any code using
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("volumemode", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("volumemode", getDriverTimeouts(driver))

View File

@ -44,36 +44,13 @@ type volumesTestSuite struct {
var _ TestSuite = &volumesTestSuite{} var _ TestSuite = &volumesTestSuite{}
// InitVolumesTestSuite returns volumesTestSuite that implements TestSuite interface // InitCustomVolumesTestSuite returns volumesTestSuite that implements TestSuite interface
func InitVolumesTestSuite() TestSuite { // using custom test patterns
func InitCustomVolumesTestSuite(patterns []testpatterns.TestPattern) TestSuite {
return &volumesTestSuite{ return &volumesTestSuite{
tsInfo: TestSuiteInfo{ tsInfo: TestSuiteInfo{
Name: "volumes", Name: "volumes",
TestPatterns: []testpatterns.TestPattern{ TestPatterns: patterns,
// Default fsType
testpatterns.DefaultFsInlineVolume,
testpatterns.DefaultFsPreprovisionedPV,
testpatterns.DefaultFsDynamicPV,
// ext3
testpatterns.Ext3InlineVolume,
testpatterns.Ext3PreprovisionedPV,
testpatterns.Ext3DynamicPV,
// ext4
testpatterns.Ext4InlineVolume,
testpatterns.Ext4PreprovisionedPV,
testpatterns.Ext4DynamicPV,
// xfs
testpatterns.XfsInlineVolume,
testpatterns.XfsPreprovisionedPV,
testpatterns.XfsDynamicPV,
// ntfs
testpatterns.NtfsInlineVolume,
testpatterns.NtfsPreprovisionedPV,
testpatterns.NtfsDynamicPV,
// block volumes
testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV,
},
SupportedSizeRange: e2evolume.SizeRange{ SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi", Min: "1Mi",
}, },
@ -81,11 +58,45 @@ func InitVolumesTestSuite() TestSuite {
} }
} }
// InitVolumesTestSuite returns volumesTestSuite that implements TestSuite interface
// using testsuite default patterns
func InitVolumesTestSuite() TestSuite {
patterns := []testpatterns.TestPattern{
// Default fsType
testpatterns.DefaultFsInlineVolume,
testpatterns.DefaultFsPreprovisionedPV,
testpatterns.DefaultFsDynamicPV,
// ext3
testpatterns.Ext3InlineVolume,
testpatterns.Ext3PreprovisionedPV,
testpatterns.Ext3DynamicPV,
// ext4
testpatterns.Ext4InlineVolume,
testpatterns.Ext4PreprovisionedPV,
testpatterns.Ext4DynamicPV,
// xfs
testpatterns.XfsInlineVolume,
testpatterns.XfsPreprovisionedPV,
testpatterns.XfsDynamicPV,
// ntfs
testpatterns.NtfsInlineVolume,
testpatterns.NtfsPreprovisionedPV,
testpatterns.NtfsDynamicPV,
// block volumes
testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV,
}
return InitCustomVolumesTestSuite(patterns)
}
func (t *volumesTestSuite) GetTestSuiteInfo() TestSuiteInfo { func (t *volumesTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return t.tsInfo return t.tsInfo
} }
func (t *volumesTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) { func (t *volumesTestSuite) SkipUnsupportedTests(driver TestDriver, pattern testpatterns.TestPattern) {
if pattern.VolMode == v1.PersistentVolumeBlock {
skipTestIfBlockNotSupported(driver)
}
} }
func skipExecTest(driver TestDriver) { func skipExecTest(driver TestDriver) {
@ -114,11 +125,7 @@ func (t *volumesTestSuite) DefineTests(driver TestDriver, pattern testpatterns.T
var dInfo = driver.GetDriverInfo() var dInfo = driver.GetDriverInfo()
var l local var l local
// No preconditions to test. Normally they would be in a BeforeEach here. // Beware that it also registers an AfterEach which renders f unusable. Any code using
// This intentionally comes after checking the preconditions because it
// registers its own BeforeEach which creates the namespace. Beware that it
// also registers an AfterEach which renders f unusable. Any code using
// f must run inside an It or Context callback. // f must run inside an It or Context callback.
f := framework.NewFrameworkWithCustomTimeouts("volume", getDriverTimeouts(driver)) f := framework.NewFrameworkWithCustomTimeouts("volume", getDriverTimeouts(driver))
@ -149,10 +156,6 @@ func (t *volumesTestSuite) DefineTests(driver TestDriver, pattern testpatterns.T
} }
ginkgo.It("should store data", func() { ginkgo.It("should store data", func() {
if pattern.VolMode == v1.PersistentVolumeBlock {
skipTestIfBlockNotSupported(driver)
}
init() init()
defer func() { defer func() {
e2evolume.TestServerCleanup(f, convertTestConfig(l.config)) e2evolume.TestServerCleanup(f, convertTestConfig(l.config))