Unverified Commit 34d75d77 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #67963 from ddebroy/gce-tests-delayed

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions here: https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md. E2E tests for DynamicProvisioningScheduling support for GCE PD and RePD **What this PR does / why we need it**: Add end2end tests to exercise DynamicProvisioningScheduling features for GCE PD and RePD. The tests make sure WaitForFirstConsumer and AllowedTopologies specified in a GCE PD/RePD storage class has the desired effect. **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes # **Special notes for your reviewer**: Tests features added in https://github.com/kubernetes/kubernetes/pull/67530/commits/a2de7d2d8daf730ce943f4b28decf70dc2cea488 **Release note**: ```release-note NONE ``` /sig storage cc @msau42
parents d97ece0f 10f652ab
...@@ -34,6 +34,7 @@ import ( ...@@ -34,6 +34,7 @@ import (
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
podutil "k8s.io/kubernetes/pkg/api/v1/pod" podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/kubelet/apis" "k8s.io/kubernetes/pkg/kubelet/apis"
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/storage/utils" "k8s.io/kubernetes/test/e2e/storage/utils"
...@@ -65,10 +66,21 @@ var _ = utils.SIGDescribe("Regional PD", func() { ...@@ -65,10 +66,21 @@ var _ = utils.SIGDescribe("Regional PD", func() {
testVolumeProvisioning(c, ns) testVolumeProvisioning(c, ns)
}) })
It("should provision storage with delayed binding [Slow] [Feature:DynamicProvisioningScheduling]", func() {
testRegionalDelayedBinding(c, ns)
})
It("should provision storage in the allowedTopologies [Slow] [Feature:DynamicProvisioningScheduling]", func() {
testRegionalAllowedTopologies(c, ns)
})
It("should provision storage in the allowedTopologies with delayed binding [Slow] [Feature:DynamicProvisioningScheduling]", func() {
testRegionalAllowedTopologiesWithDelayedBinding(c, ns)
})
It("should failover to a different zone when all nodes in one zone become unreachable [Slow] [Disruptive]", func() { It("should failover to a different zone when all nodes in one zone become unreachable [Slow] [Disruptive]", func() {
testZonalFailover(c, ns) testZonalFailover(c, ns)
}) })
}) })
}) })
...@@ -264,6 +276,94 @@ func testZonalFailover(c clientset.Interface, ns string) { ...@@ -264,6 +276,94 @@ func testZonalFailover(c clientset.Interface, ns string) {
} }
func testRegionalDelayedBinding(c clientset.Interface, ns string) {
test := storageClassTest{
name: "Regional PD storage class with waitForFirstConsumer test on GCE",
provisioner: "kubernetes.io/gce-pd",
parameters: map[string]string{
"type": "pd-standard",
"replication-type": "regional-pd",
},
claimSize: "2Gi",
delayBinding: true,
}
suffix := "delayed-regional"
class := newStorageClass(test, ns, suffix)
claim := newClaim(test, ns, suffix)
claim.Spec.StorageClassName = &class.Name
pv, node := testBindingWaitForFirstConsumer(c, claim, class)
if node == nil {
framework.Failf("unexpected nil node found")
}
zone, ok := node.Labels[kubeletapis.LabelZoneFailureDomain]
if !ok {
framework.Failf("label %s not found on Node", kubeletapis.LabelZoneFailureDomain)
}
checkZoneFromLabelAndAffinity(pv, zone, false)
}
func testRegionalAllowedTopologies(c clientset.Interface, ns string) {
test := storageClassTest{
name: "Regional PD storage class with allowedTopologies test on GCE",
provisioner: "kubernetes.io/gce-pd",
parameters: map[string]string{
"type": "pd-standard",
"replication-type": "regional-pd",
},
claimSize: "2Gi",
expectedSize: "2Gi",
}
suffix := "topo-regional"
class := newStorageClass(test, ns, suffix)
zones := getTwoRandomZones(c)
addAllowedTopologiesToStorageClass(c, class, zones)
claim := newClaim(test, ns, suffix)
claim.Spec.StorageClassName = &class.Name
pv := testDynamicProvisioning(test, c, claim, class)
checkZonesFromLabelAndAffinity(pv, sets.NewString(zones...), true)
}
func testRegionalAllowedTopologiesWithDelayedBinding(c clientset.Interface, ns string) {
test := storageClassTest{
name: "Regional PD storage class with allowedTopologies and waitForFirstConsumer test on GCE",
provisioner: "kubernetes.io/gce-pd",
parameters: map[string]string{
"type": "pd-standard",
"replication-type": "regional-pd",
},
claimSize: "2Gi",
delayBinding: true,
}
suffix := "topo-delayed-regional"
class := newStorageClass(test, ns, suffix)
topoZones := getTwoRandomZones(c)
addAllowedTopologiesToStorageClass(c, class, topoZones)
claim := newClaim(test, ns, suffix)
claim.Spec.StorageClassName = &class.Name
pv, node := testBindingWaitForFirstConsumer(c, claim, class)
if node == nil {
framework.Failf("unexpected nil node found")
}
nodeZone, ok := node.Labels[kubeletapis.LabelZoneFailureDomain]
if !ok {
framework.Failf("label %s not found on Node", kubeletapis.LabelZoneFailureDomain)
}
zoneFound := false
for _, zone := range topoZones {
if zone == nodeZone {
zoneFound = true
break
}
}
if !zoneFound {
framework.Failf("zones specified in AllowedTopologies: %v does not contain zone of node where PV got provisioned: %s", topoZones, nodeZone)
}
checkZonesFromLabelAndAffinity(pv, sets.NewString(topoZones...), true)
}
func getPVC(c clientset.Interface, ns string, pvcLabels map[string]string) *v1.PersistentVolumeClaim { func getPVC(c clientset.Interface, ns string, pvcLabels map[string]string) *v1.PersistentVolumeClaim {
selector := labels.Set(pvcLabels).AsSelector() selector := labels.Set(pvcLabels).AsSelector()
options := metav1.ListOptions{LabelSelector: selector.String()} options := metav1.ListOptions{LabelSelector: selector.String()}
...@@ -284,6 +384,18 @@ func getPod(c clientset.Interface, ns string, podLabels map[string]string) *v1.P ...@@ -284,6 +384,18 @@ func getPod(c clientset.Interface, ns string, podLabels map[string]string) *v1.P
return &podList.Items[0] return &podList.Items[0]
} }
func addAllowedTopologiesToStorageClass(c clientset.Interface, sc *storage.StorageClass, zones []string) {
term := v1.TopologySelectorTerm{
MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
{
Key: kubeletapis.LabelZoneFailureDomain,
Values: zones,
},
},
}
sc.AllowedTopologies = append(sc.AllowedTopologies, term)
}
// Generates the spec of a StatefulSet with 1 replica that mounts a Regional PD. // Generates the spec of a StatefulSet with 1 replica that mounts a Regional PD.
func newStatefulSet(claimTemplate *v1.PersistentVolumeClaim, ns string) (sts *appsv1.StatefulSet, svc *v1.Service, labels map[string]string) { func newStatefulSet(claimTemplate *v1.PersistentVolumeClaim, ns string) (sts *appsv1.StatefulSet, svc *v1.Service, labels map[string]string) {
var replicas int32 = 1 var replicas int32 = 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment