e2e storage: public API for testsuites, support CSIInlineVolume type for generic resource

Implementing a test suite was impossible outside of the
k8s.io/kubernetes/test/e2e/storage/testsuites package because all
interfaces and structs used by them were private.

As part of revamping the API, genericVolumeTestResource also gets
exported because it is useful for other test suites. Because the
TestResource interface became obsolete a while ago and isn't used
anymore, the new name is just testsuites.VolumeResource.

testpatterns.CSIInlineVolume needs special handling in a few places.
It can now be used in a test pattern for a test suite that uses a
VolumeResource instance.
This commit is contained in:
Patrick Ohly
2019-11-22 10:46:04 +01:00
parent bea2ca73f3
commit 160da35b23
15 changed files with 332 additions and 297 deletions

View File

@@ -57,36 +57,36 @@ var _ TestSuite = &volumeModeTestSuite{}
func InitVolumeModeTestSuite() TestSuite {
return &volumeModeTestSuite{
tsInfo: TestSuiteInfo{
name: "volumeMode",
testPatterns: []testpatterns.TestPattern{
Name: "volumeMode",
TestPatterns: []testpatterns.TestPattern{
testpatterns.FsVolModePreprovisionedPV,
testpatterns.FsVolModeDynamicPV,
testpatterns.BlockVolModePreprovisionedPV,
testpatterns.BlockVolModeDynamicPV,
},
supportedSizeRange: volume.SizeRange{
SupportedSizeRange: volume.SizeRange{
Min: "1Mi",
},
},
}
}
func (t *volumeModeTestSuite) getTestSuiteInfo() TestSuiteInfo {
func (t *volumeModeTestSuite) GetTestSuiteInfo() TestSuiteInfo {
return t.tsInfo
}
func (t *volumeModeTestSuite) skipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) {
func (t *volumeModeTestSuite) SkipRedundantSuite(driver TestDriver, pattern testpatterns.TestPattern) {
}
func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpatterns.TestPattern) {
func (t *volumeModeTestSuite) DefineTests(driver TestDriver, pattern testpatterns.TestPattern) {
type local struct {
config *PerTestConfig
driverCleanup func()
cs clientset.Interface
ns *v1.Namespace
// genericVolumeTestResource contains pv, pvc, sc, etc., owns cleaning that up
genericVolumeTestResource
// VolumeResource contains pv, pvc, sc, etc., owns cleaning that up
VolumeResource
intreeOps opCounts
migratedOps opCounts
@@ -114,7 +114,7 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName)
}
// manualInit initializes l.genericVolumeTestResource without creating the PV & PVC objects.
// manualInit initializes l.VolumeResource without creating the PV & PVC objects.
manualInit := func() {
init()
@@ -127,14 +127,13 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
volumeNodeAffinity *v1.VolumeNodeAffinity
)
l.genericVolumeTestResource = genericVolumeTestResource{
driver: driver,
config: l.config,
pattern: pattern,
l.VolumeResource = VolumeResource{
Config: l.config,
Pattern: pattern,
}
// Create volume for pre-provisioned volume tests
l.volume = CreateVolume(driver, l.config, pattern.VolType)
l.Volume = CreateVolume(driver, l.config, pattern.VolType)
switch pattern.VolType {
case testpatterns.PreprovisionedPV:
@@ -144,31 +143,31 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
scName = fmt.Sprintf("%s-%s-sc-for-file", l.ns.Name, dInfo.Name)
}
if pDriver, ok := driver.(PreprovisionedPVTestDriver); ok {
pvSource, volumeNodeAffinity = pDriver.GetPersistentVolumeSource(false, fsType, l.volume)
pvSource, volumeNodeAffinity = pDriver.GetPersistentVolumeSource(false, fsType, l.Volume)
if pvSource == nil {
framework.Skipf("Driver %q does not define PersistentVolumeSource - skipping", dInfo.Name)
}
storageClass, pvConfig, pvcConfig := generateConfigsForPreprovisionedPVTest(scName, volBindMode, pattern.VolMode, *pvSource, volumeNodeAffinity)
l.sc = storageClass
l.pv = e2epv.MakePersistentVolume(pvConfig)
l.pvc = e2epv.MakePersistentVolumeClaim(pvcConfig, l.ns.Name)
l.Sc = storageClass
l.Pv = e2epv.MakePersistentVolume(pvConfig)
l.Pvc = e2epv.MakePersistentVolumeClaim(pvcConfig, l.ns.Name)
}
case testpatterns.DynamicPV:
if dDriver, ok := driver.(DynamicPVTestDriver); ok {
l.sc = dDriver.GetDynamicProvisionStorageClass(l.config, fsType)
if l.sc == nil {
l.Sc = dDriver.GetDynamicProvisionStorageClass(l.config, fsType)
if l.Sc == nil {
framework.Skipf("Driver %q does not define Dynamic Provision StorageClass - skipping", dInfo.Name)
}
l.sc.VolumeBindingMode = &volBindMode
testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange
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: claimSize,
StorageClassName: &(l.sc.Name),
StorageClassName: &(l.Sc.Name),
VolumeMode: &pattern.VolMode,
}, l.ns.Name)
}
@@ -179,7 +178,7 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
cleanup := func() {
var errs []error
errs = append(errs, l.cleanupResource())
errs = append(errs, l.CleanupResource())
errs = append(errs, tryFunc(l.driverCleanup))
l.driverCleanup = nil
framework.ExpectNoError(errors.NewAggregate(errs), "while cleaning up resource")
@@ -198,22 +197,22 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
var err error
ginkgo.By("Creating sc")
l.sc, err = l.cs.StorageV1().StorageClasses().Create(l.sc)
l.Sc, err = l.cs.StorageV1().StorageClasses().Create(l.Sc)
framework.ExpectNoError(err, "Failed to create sc")
ginkgo.By("Creating pv and pvc")
l.pv, err = l.cs.CoreV1().PersistentVolumes().Create(l.pv)
l.Pv, err = l.cs.CoreV1().PersistentVolumes().Create(l.Pv)
framework.ExpectNoError(err, "Failed to create pv")
// Prebind pv
l.pvc.Spec.VolumeName = l.pv.Name
l.pvc, err = l.cs.CoreV1().PersistentVolumeClaims(l.ns.Name).Create(l.pvc)
l.Pvc.Spec.VolumeName = l.Pv.Name
l.Pvc, err = l.cs.CoreV1().PersistentVolumeClaims(l.ns.Name).Create(l.Pvc)
framework.ExpectNoError(err, "Failed to create pvc")
framework.ExpectNoError(e2epv.WaitOnPVandPVC(l.cs, l.ns.Name, l.pv, l.pvc), "Failed to bind pv and pvc")
framework.ExpectNoError(e2epv.WaitOnPVandPVC(l.cs, l.ns.Name, l.Pv, l.Pvc), "Failed to bind pv and pvc")
ginkgo.By("Creating pod")
pod := e2epod.MakeSecPod(l.ns.Name, []*v1.PersistentVolumeClaim{l.pvc}, nil, false, "", false, false, e2epv.SELinuxLabel, nil)
pod := e2epod.MakeSecPod(l.ns.Name, []*v1.PersistentVolumeClaim{l.Pvc}, nil, false, "", false, false, e2epv.SELinuxLabel, nil)
// Setting node
pod.Spec.NodeName = l.config.ClientNodeName
pod, err = l.cs.CoreV1().Pods(l.ns.Name).Create(pod)
@@ -252,16 +251,16 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
var err error
ginkgo.By("Creating sc")
l.sc, err = l.cs.StorageV1().StorageClasses().Create(l.sc)
l.Sc, err = l.cs.StorageV1().StorageClasses().Create(l.Sc)
framework.ExpectNoError(err, "Failed to create sc")
ginkgo.By("Creating pv and pvc")
l.pvc, err = l.cs.CoreV1().PersistentVolumeClaims(l.ns.Name).Create(l.pvc)
l.Pvc, err = l.cs.CoreV1().PersistentVolumeClaims(l.ns.Name).Create(l.Pvc)
framework.ExpectNoError(err, "Failed to create pvc")
eventSelector := fields.Set{
"involvedObject.kind": "PersistentVolumeClaim",
"involvedObject.name": l.pvc.Name,
"involvedObject.name": l.Pvc.Name,
"involvedObject.namespace": l.ns.Name,
"reason": volevents.ProvisioningFailed,
}.AsSelector().String()
@@ -274,7 +273,7 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
}
// Check the pvc is still pending
pvc, err := l.cs.CoreV1().PersistentVolumeClaims(l.ns.Name).Get(l.pvc.Name, metav1.GetOptions{})
pvc, err := l.cs.CoreV1().PersistentVolumeClaims(l.ns.Name).Get(l.Pvc.Name, metav1.GetOptions{})
framework.ExpectNoError(err, "Failed to re-read the pvc after event (or timeout)")
framework.ExpectEqual(pvc.Status.Phase, v1.ClaimPending, "PVC phase isn't pending")
})
@@ -286,13 +285,13 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
ginkgo.It("should fail to use a volume in a pod with mismatched mode [Slow]", func() {
skipTestIfBlockNotSupported(driver)
init()
testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange
l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange)
testVolumeSizeRange := t.GetTestSuiteInfo().SupportedSizeRange
l.VolumeResource = *CreateVolumeResource(driver, l.config, pattern, testVolumeSizeRange)
defer cleanup()
ginkgo.By("Creating pod")
var err error
pod := e2epod.MakeSecPod(l.ns.Name, []*v1.PersistentVolumeClaim{l.pvc}, nil, false, "", false, false, e2epv.SELinuxLabel, nil)
pod := e2epod.MakeSecPod(l.ns.Name, []*v1.PersistentVolumeClaim{l.Pvc}, nil, false, "", false, false, e2epv.SELinuxLabel, nil)
// Change volumeMounts to volumeDevices and the other way around
pod = swapVolumeMode(pod)
@@ -335,13 +334,13 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
skipTestIfBlockNotSupported(driver)
}
init()
testVolumeSizeRange := t.getTestSuiteInfo().supportedSizeRange
l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern, testVolumeSizeRange)
testVolumeSizeRange := t.GetTestSuiteInfo().SupportedSizeRange
l.VolumeResource = *CreateVolumeResource(driver, l.config, pattern, testVolumeSizeRange)
defer cleanup()
ginkgo.By("Creating pod")
var err error
pod := e2epod.MakeSecPod(l.ns.Name, []*v1.PersistentVolumeClaim{l.pvc}, nil, false, "", false, false, e2epv.SELinuxLabel, nil)
pod := e2epod.MakeSecPod(l.ns.Name, []*v1.PersistentVolumeClaim{l.Pvc}, nil, false, "", false, false, e2epv.SELinuxLabel, nil)
for i := range pod.Spec.Containers {
pod.Spec.Containers[i].VolumeDevices = nil
pod.Spec.Containers[i].VolumeMounts = nil