mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 21:17:23 +00:00
Merge pull request #79796 from jsafrane/block-test-mismatch
Add test for mismatched usage of filesystem/block volumes
This commit is contained in:
commit
0d579bfecf
@ -20,12 +20,14 @@ go_library(
|
|||||||
importpath = "k8s.io/kubernetes/test/e2e/storage/testsuites",
|
importpath = "k8s.io/kubernetes/test/e2e/storage/testsuites",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//pkg/kubelet/events:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
|
@ -24,9 +24,12 @@ 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"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/fields"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/events"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
||||||
|
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||||
"k8s.io/kubernetes/test/e2e/storage/testpatterns"
|
"k8s.io/kubernetes/test/e2e/storage/testpatterns"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -94,6 +97,11 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
|
|||||||
// Now do the more expensive test initialization.
|
// Now do the more expensive test initialization.
|
||||||
l.config, l.testCleanup = driver.PrepareTest(f)
|
l.config, l.testCleanup = driver.PrepareTest(f)
|
||||||
l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName)
|
l.intreeOps, l.migratedOps = getMigrationVolumeOpCounts(f.ClientSet, dInfo.InTreePluginName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// manualInit initializes l.genericVolumeTestResource without creating the PV & PVC objects.
|
||||||
|
manualInit := func() {
|
||||||
|
init()
|
||||||
|
|
||||||
fsType := pattern.FsType
|
fsType := pattern.FsType
|
||||||
volBindMode := storagev1.VolumeBindingImmediate
|
volBindMode := storagev1.VolumeBindingImmediate
|
||||||
@ -167,7 +175,7 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
|
|||||||
case testpatterns.PreprovisionedPV:
|
case testpatterns.PreprovisionedPV:
|
||||||
if pattern.VolMode == v1.PersistentVolumeBlock && !isBlockSupported {
|
if pattern.VolMode == v1.PersistentVolumeBlock && !isBlockSupported {
|
||||||
ginkgo.It("should fail to create pod by failing to mount volume [Slow]", func() {
|
ginkgo.It("should fail to create pod by failing to mount volume [Slow]", func() {
|
||||||
init()
|
manualInit()
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -196,13 +204,12 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
|
|||||||
}()
|
}()
|
||||||
framework.ExpectError(err)
|
framework.ExpectError(err)
|
||||||
})
|
})
|
||||||
// TODO(mkimuram): Add more tests
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case testpatterns.DynamicPV:
|
case testpatterns.DynamicPV:
|
||||||
if pattern.VolMode == v1.PersistentVolumeBlock && !isBlockSupported {
|
if pattern.VolMode == v1.PersistentVolumeBlock && !isBlockSupported {
|
||||||
ginkgo.It("should fail in binding dynamic provisioned PV to PVC [Slow]", func() {
|
ginkgo.It("should fail in binding dynamic provisioned PV to PVC [Slow]", func() {
|
||||||
init()
|
manualInit()
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -218,12 +225,57 @@ func (t *volumeModeTestSuite) defineTests(driver TestDriver, pattern testpattern
|
|||||||
err = framework.WaitForPersistentVolumeClaimPhase(v1.ClaimBound, l.cs, l.pvc.Namespace, l.pvc.Name, framework.Poll, framework.ClaimProvisionTimeout)
|
err = framework.WaitForPersistentVolumeClaimPhase(v1.ClaimBound, l.cs, l.pvc.Namespace, l.pvc.Name, framework.Poll, framework.ClaimProvisionTimeout)
|
||||||
framework.ExpectError(err)
|
framework.ExpectError(err)
|
||||||
})
|
})
|
||||||
// TODO(mkimuram): Add more tests
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
e2elog.Failf("Volume mode test doesn't support volType: %v", pattern.VolType)
|
e2elog.Failf("Volume mode test doesn't support volType: %v", pattern.VolType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ginkgo.It("should fail to use a volume in a pod with mismatched mode [Slow]", func() {
|
||||||
|
skipBlockTest(driver)
|
||||||
|
init()
|
||||||
|
l.genericVolumeTestResource = *createGenericVolumeTestResource(driver, l.config, pattern)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
ginkgo.By("Creating pod")
|
||||||
|
var err error
|
||||||
|
pod := framework.MakeSecPod(l.ns.Name, []*v1.PersistentVolumeClaim{l.pvc}, nil, false, "", false, false, framework.SELinuxLabel, nil)
|
||||||
|
// Change volumeMounts to volumeDevices and the other way around
|
||||||
|
pod = swapVolumeMode(pod)
|
||||||
|
|
||||||
|
// Run the pod
|
||||||
|
pod, err = l.cs.CoreV1().Pods(l.ns.Name).Create(pod)
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
defer func() {
|
||||||
|
framework.ExpectNoError(framework.DeletePodWithWait(f, l.cs, pod))
|
||||||
|
}()
|
||||||
|
|
||||||
|
ginkgo.By("Waiting for pod to fail")
|
||||||
|
// Wait for an event that the pod is invalid.
|
||||||
|
eventSelector := fields.Set{
|
||||||
|
"involvedObject.kind": "Pod",
|
||||||
|
"involvedObject.name": pod.Name,
|
||||||
|
"involvedObject.namespace": l.ns.Name,
|
||||||
|
"reason": events.FailedMountVolume,
|
||||||
|
}.AsSelector().String()
|
||||||
|
|
||||||
|
var msg string
|
||||||
|
if pattern.VolMode == v1.PersistentVolumeBlock {
|
||||||
|
msg = "has volumeMode Block, but is specified in volumeMounts"
|
||||||
|
} else {
|
||||||
|
msg = "has volumeMode Filesystem, but is specified in volumeDevices"
|
||||||
|
}
|
||||||
|
err = e2epod.WaitTimeoutForPodEvent(l.cs, pod.Name, l.ns.Name, eventSelector, msg, framework.PodStartTimeout)
|
||||||
|
// Events are unreliable, don't depend on them. They're used only to speed up the test.
|
||||||
|
if err != nil {
|
||||||
|
e2elog.Logf("Warning: did not get event about mismatched volume use")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the pod is still not running
|
||||||
|
p, err := l.cs.CoreV1().Pods(l.ns.Name).Get(pod.Name, metav1.GetOptions{})
|
||||||
|
framework.ExpectNoError(err, "could not re-read the pod after event (or timeout)")
|
||||||
|
framework.ExpectEqual(p.Status.Phase, v1.PodPending)
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateConfigsForPreprovisionedPVTest(scName string, volBindMode storagev1.VolumeBindingMode,
|
func generateConfigsForPreprovisionedPVTest(scName string, volBindMode storagev1.VolumeBindingMode,
|
||||||
@ -254,3 +306,29 @@ func generateConfigsForPreprovisionedPVTest(scName string, volBindMode storagev1
|
|||||||
|
|
||||||
return scConfig, pvConfig, pvcConfig
|
return scConfig, pvConfig, pvcConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swapVolumeMode changes volumeMounts to volumeDevices and the other way around
|
||||||
|
func swapVolumeMode(podTemplate *v1.Pod) *v1.Pod {
|
||||||
|
pod := podTemplate.DeepCopy()
|
||||||
|
for c := range pod.Spec.Containers {
|
||||||
|
container := &pod.Spec.Containers[c]
|
||||||
|
container.VolumeDevices = []v1.VolumeDevice{}
|
||||||
|
container.VolumeMounts = []v1.VolumeMount{}
|
||||||
|
|
||||||
|
// Change VolumeMounts to VolumeDevices
|
||||||
|
for _, volumeMount := range podTemplate.Spec.Containers[c].VolumeMounts {
|
||||||
|
container.VolumeDevices = append(container.VolumeDevices, v1.VolumeDevice{
|
||||||
|
Name: volumeMount.Name,
|
||||||
|
DevicePath: volumeMount.MountPath,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Change VolumeDevices to VolumeMounts
|
||||||
|
for _, volumeDevice := range podTemplate.Spec.Containers[c].VolumeDevices {
|
||||||
|
container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{
|
||||||
|
Name: volumeDevice.Name,
|
||||||
|
MountPath: volumeDevice.DevicePath,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pod
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user