Merge pull request #70756 from msau42/add-io-exec-test

Add e2e test for file exec
This commit is contained in:
k8s-ci-robot 2018-11-30 08:19:48 -08:00 committed by GitHub
commit 0955c930be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 180 additions and 73 deletions

View File

@ -76,6 +76,16 @@ type DynamicPVTestDriver interface {
GetDynamicProvisionStorageClass(fsType string) *storagev1.StorageClass GetDynamicProvisionStorageClass(fsType string) *storagev1.StorageClass
} }
// Capability represents a feature that a volume plugin supports
type Capability string
const (
CapPersistence Capability = "persistence" // data is persisted across pod restarts
CapBlock Capability = "block" // raw block mode
CapFsGroup Capability = "fsGroup" // volume ownership via fsGroup
CapExec Capability = "exec" // exec a file in the volume
)
// DriverInfo represents a combination of parameters to be used in implementation of TestDriver // DriverInfo represents a combination of parameters to be used in implementation of TestDriver
type DriverInfo struct { type DriverInfo struct {
Name string // Name of the driver Name string // Name of the driver
@ -85,9 +95,7 @@ type DriverInfo struct {
SupportedFsType sets.String // Map of string for supported fs type SupportedFsType sets.String // Map of string for supported fs type
SupportedMountOption sets.String // Map of string for supported mount option SupportedMountOption sets.String // Map of string for supported mount option
RequiredMountOption sets.String // Map of string for required mount option (Optional) RequiredMountOption sets.String // Map of string for required mount option (Optional)
IsPersistent bool // Flag to represent whether it provides persistency Capabilities map[Capability]bool // Map that represents plugin capabilities
IsFsGroupSupported bool // Flag to represent whether it supports fsGroup
IsBlockSupported bool // Flag to represent whether it supports Block Volume
// Parameters below will be set inside test loop by using SetCommonDriverParameters. // Parameters below will be set inside test loop by using SetCommonDriverParameters.
// Drivers that implement TestDriver is required to set all the above parameters // Drivers that implement TestDriver is required to set all the above parameters

View File

@ -67,9 +67,9 @@ func InitHostPathCSIDriver() TestDriver {
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: false, CapPersistence: true,
IsBlockSupported: false, },
}, },
} }
} }
@ -153,9 +153,9 @@ func InitHostV0PathCSIDriver() TestDriver {
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: false, CapPersistence: true,
IsBlockSupported: false, },
}, },
} }
} }
@ -243,9 +243,11 @@ func InitGcePDCSIDriver() TestDriver {
"ext4", "ext4",
"xfs", "xfs",
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: true, CapPersistence: true,
IsBlockSupported: false, CapFsGroup: true,
CapExec: true,
},
}, },
} }
} }
@ -334,9 +336,11 @@ func InitGcePDExternalCSIDriver() TestDriver {
"ext4", "ext4",
"xfs", "xfs",
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: true, CapPersistence: true,
IsBlockSupported: false, CapFsGroup: true,
CapExec: true,
},
}, },
} }
} }

View File

@ -90,9 +90,10 @@ func InitNFSDriver() TestDriver {
), ),
SupportedMountOption: sets.NewString("proto=tcp", "relatime"), SupportedMountOption: sets.NewString("proto=tcp", "relatime"),
RequiredMountOption: sets.NewString("vers=4.1"), RequiredMountOption: sets.NewString("vers=4.1"),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: false, CapPersistence: true,
IsBlockSupported: false, CapExec: true,
},
}, },
} }
} }
@ -235,9 +236,10 @@ func InitGlusterFSDriver() TestDriver {
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: false, CapPersistence: true,
IsBlockSupported: false, CapExec: true,
},
}, },
} }
} }
@ -356,9 +358,12 @@ func InitISCSIDriver() TestDriver {
//"ext3", //"ext3",
"ext4", "ext4",
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: true, CapPersistence: true,
IsBlockSupported: true, CapFsGroup: true,
CapBlock: true,
CapExec: true,
},
}, },
} }
} }
@ -465,9 +470,13 @@ func InitRbdDriver() TestDriver {
//"ext3", //"ext3",
"ext4", "ext4",
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: true, CapPersistence: true,
IsBlockSupported: true}, CapFsGroup: true,
CapBlock: true,
CapExec: true,
},
},
} }
} }
@ -585,9 +594,10 @@ func InitCephFSDriver() TestDriver {
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: false, CapPersistence: true,
IsBlockSupported: false, CapExec: true,
},
}, },
} }
} }
@ -684,9 +694,9 @@ func InitHostPathDriver() TestDriver {
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: false, CapPersistence: true,
IsBlockSupported: false, },
}, },
} }
} }
@ -756,9 +766,9 @@ func InitHostPathSymlinkDriver() TestDriver {
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: false, CapPersistence: true,
IsBlockSupported: false, },
}, },
} }
} }
@ -896,9 +906,9 @@ func InitEmptydirDriver() TestDriver {
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
"", // Default fsType "", // Default fsType
), ),
IsPersistent: false, Capabilities: map[Capability]bool{
IsFsGroupSupported: false, CapExec: true,
IsBlockSupported: false, },
}, },
} }
} }
@ -963,9 +973,11 @@ func InitCinderDriver() TestDriver {
"", // Default fsType "", // Default fsType
"ext3", "ext3",
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: true, CapPersistence: true,
IsBlockSupported: false, CapFsGroup: true,
CapExec: true,
},
}, },
} }
} }
@ -1121,9 +1133,12 @@ func InitGcePdDriver() TestDriver {
"xfs", "xfs",
), ),
SupportedMountOption: sets.NewString("debug", "nouid32"), SupportedMountOption: sets.NewString("debug", "nouid32"),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: true, CapPersistence: true,
IsBlockSupported: true, CapFsGroup: true,
CapBlock: true,
CapExec: true,
},
}, },
} }
} }
@ -1235,9 +1250,11 @@ func InitVSphereDriver() TestDriver {
"", // Default fsType "", // Default fsType
"ext4", "ext4",
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: true, CapPersistence: true,
IsBlockSupported: false, CapFsGroup: true,
CapExec: true,
},
}, },
} }
} }
@ -1351,9 +1368,12 @@ func InitAzureDriver() TestDriver {
"", // Default fsType "", // Default fsType
"ext4", "ext4",
), ),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: true, CapPersistence: true,
IsBlockSupported: true, CapFsGroup: true,
CapBlock: true,
CapExec: true,
},
}, },
} }
} }
@ -1464,9 +1484,12 @@ func InitAwsDriver() TestDriver {
"ext3", "ext3",
), ),
SupportedMountOption: sets.NewString("debug", "nouid32"), SupportedMountOption: sets.NewString("debug", "nouid32"),
IsPersistent: true, Capabilities: map[Capability]bool{
IsFsGroupSupported: true, CapPersistence: true,
IsBlockSupported: true, CapFsGroup: true,
CapBlock: true,
CapExec: true,
},
}, },
} }
} }

View File

@ -187,7 +187,7 @@ func testProvisioning(input *provisioningTestInput) {
}) })
It("should create and delete block persistent volumes", func() { It("should create and delete block persistent volumes", func() {
if !input.dInfo.IsBlockSupported { if !input.dInfo.Capabilities[drivers.CapBlock] {
framework.Skipf("Driver %q does not support BlockVolume - skipping", input.dInfo.Name) framework.Skipf("Driver %q does not support BlockVolume - skipping", input.dInfo.Name)
} }
block := v1.PersistentVolumeBlock block := v1.PersistentVolumeBlock

View File

@ -90,7 +90,7 @@ func createVolumeIOTestInput(pattern testpatterns.TestPattern, resource genericV
framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name) framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name)
} }
if dInfo.IsFsGroupSupported { if dInfo.Capabilities[drivers.CapFsGroup] {
fsGroupVal := int64(1234) fsGroupVal := int64(1234)
fsGroup = &fsGroupVal fsGroup = &fsGroupVal
} }

View File

@ -78,13 +78,13 @@ func createVolumeModeTestInput(pattern testpatterns.TestPattern, resource volume
testVolType: pattern.VolType, testVolType: pattern.VolType,
nodeName: dInfo.Config.ClientNodeName, nodeName: dInfo.Config.ClientNodeName,
volMode: pattern.VolMode, volMode: pattern.VolMode,
isBlockSupported: dInfo.IsBlockSupported, isBlockSupported: dInfo.Capabilities[drivers.CapBlock],
} }
} }
func getVolumeModeTestFunc(pattern testpatterns.TestPattern, driver drivers.TestDriver) func(*volumeModeTestInput) { func getVolumeModeTestFunc(pattern testpatterns.TestPattern, driver drivers.TestDriver) func(*volumeModeTestInput) {
dInfo := driver.GetDriverInfo() dInfo := driver.GetDriverInfo()
isBlockSupported := dInfo.IsBlockSupported isBlockSupported := dInfo.Capabilities[drivers.CapBlock]
volMode := pattern.VolMode volMode := pattern.VolMode
volType := pattern.VolType volType := pattern.VolType

View File

@ -23,11 +23,17 @@ package testsuites
import ( import (
"fmt" "fmt"
"path/filepath"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/storage/drivers" "k8s.io/kubernetes/test/e2e/storage/drivers"
"k8s.io/kubernetes/test/e2e/storage/testpatterns" "k8s.io/kubernetes/test/e2e/storage/testpatterns"
imageutils "k8s.io/kubernetes/test/utils/image"
) )
type volumesTestSuite struct { type volumesTestSuite struct {
@ -68,12 +74,22 @@ func (t *volumesTestSuite) getTestSuiteInfo() TestSuiteInfo {
} }
func (t *volumesTestSuite) skipUnsupportedTest(pattern testpatterns.TestPattern, driver drivers.TestDriver) { func (t *volumesTestSuite) skipUnsupportedTest(pattern testpatterns.TestPattern, driver drivers.TestDriver) {
}
func skipPersistenceTest(driver drivers.TestDriver) {
dInfo := driver.GetDriverInfo() dInfo := driver.GetDriverInfo()
if !dInfo.IsPersistent { if !dInfo.Capabilities[drivers.CapPersistence] {
framework.Skipf("Driver %q does not provide persistency - skipping", dInfo.Name) framework.Skipf("Driver %q does not provide persistency - skipping", dInfo.Name)
} }
} }
func skipExecTest(driver drivers.TestDriver) {
dInfo := driver.GetDriverInfo()
if !dInfo.Capabilities[drivers.CapExec] {
framework.Skipf("Driver %q does not support exec - skipping", dInfo.Name)
}
}
func createVolumesTestInput(pattern testpatterns.TestPattern, resource genericVolumeTestResource) volumesTestInput { func createVolumesTestInput(pattern testpatterns.TestPattern, resource genericVolumeTestResource) volumesTestInput {
var fsGroup *int64 var fsGroup *int64
driver := resource.driver driver := resource.driver
@ -85,7 +101,7 @@ func createVolumesTestInput(pattern testpatterns.TestPattern, resource genericVo
framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name) framework.Skipf("Driver %q does not define volumeSource - skipping", dInfo.Name)
} }
if dInfo.IsFsGroupSupported { if dInfo.Capabilities[drivers.CapFsGroup] {
fsGroupVal := int64(1234) fsGroupVal := int64(1234)
fsGroup = &fsGroupVal fsGroup = &fsGroupVal
} }
@ -95,6 +111,7 @@ func createVolumesTestInput(pattern testpatterns.TestPattern, resource genericVo
name: dInfo.Name, name: dInfo.Name,
config: dInfo.Config, config: dInfo.Config,
fsGroup: fsGroup, fsGroup: fsGroup,
resource: resource,
tests: []framework.VolumeTest{ tests: []framework.VolumeTest{
{ {
Volume: *volSource, Volume: *volSource,
@ -145,6 +162,7 @@ type volumesTestInput struct {
config framework.VolumeTestConfig config framework.VolumeTestConfig
fsGroup *int64 fsGroup *int64
tests []framework.VolumeTest tests []framework.VolumeTest
resource genericVolumeTestResource
} }
func testVolumes(input *volumesTestInput) { func testVolumes(input *volumesTestInput) {
@ -153,8 +171,62 @@ func testVolumes(input *volumesTestInput) {
cs := f.ClientSet cs := f.ClientSet
defer framework.VolumeTestCleanup(f, input.config) defer framework.VolumeTestCleanup(f, input.config)
skipPersistenceTest(input.resource.driver)
volumeTest := input.tests volumeTest := input.tests
framework.InjectHtml(cs, input.config, volumeTest[0].Volume, volumeTest[0].ExpectedContent) framework.InjectHtml(cs, input.config, volumeTest[0].Volume, volumeTest[0].ExpectedContent)
framework.TestVolumeClient(cs, input.config, input.fsGroup, input.tests) framework.TestVolumeClient(cs, input.config, input.fsGroup, input.tests)
}) })
It("should allow exec of files on the volume", func() {
f := input.f
skipExecTest(input.resource.driver)
testScriptInPod(f, input.resource.volType, input.resource.volSource)
})
}
func testScriptInPod(f *framework.Framework, volumeType string, source *v1.VolumeSource) {
const (
volPath = "/vol1"
volName = "vol1"
)
suffix := generateSuffixForPodName(volumeType)
scriptName := fmt.Sprintf("test-%s.sh", suffix)
fullPath := filepath.Join(volPath, scriptName)
cmd := fmt.Sprintf("echo \"ls %s\" > %s; chmod u+x %s; %s", volPath, fullPath, fullPath, fullPath)
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("exec-volume-test-%s", suffix),
Namespace: f.Namespace.Name,
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: fmt.Sprintf("exec-container-%s", suffix),
Image: imageutils.GetE2EImage(imageutils.Nginx),
Command: []string{"/bin/sh", "-ec", cmd},
VolumeMounts: []v1.VolumeMount{
{
Name: volName,
MountPath: volPath,
},
},
},
},
Volumes: []v1.Volume{
{
Name: volName,
VolumeSource: *source,
},
},
RestartPolicy: v1.RestartPolicyNever,
},
}
By(fmt.Sprintf("Creating pod %s", pod.Name))
f.TestContainerOutput("exec-volume-test", pod, 0, []string{scriptName})
By(fmt.Sprintf("Deleting pod %s", pod.Name))
err := framework.DeletePodWithWait(f, f.ClientSet, pod)
Expect(err).NotTo(HaveOccurred(), "while deleting pod")
} }