New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add multi PVC versions of e2e tests for WaitForFirstConsumer #70362
Conversation
/assign @msau42 |
/assign @marun |
/assign @verult |
Multiple PVC tests for regional PDs with delayed binding is now in. Tests for multi-PVCs with EBS and GCE PD are passing. So the multi PVC tests and utils is ready to be reviewed. The remaining portion is the tests with node selectors and taints which will build on this. |
test/e2e/framework/util.go
Outdated
return WaitForPersistentVolumeClaimsPhase(phase, c, ns, []string{pvcName}, Poll, timeout, true) | ||
} | ||
|
||
// WaitForPersistentVolumeClaimPhase waits for any or all of the PersistentVolumeClaims to be in a specific phase or until timeout occurs, whichever comes first. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "waits for any (if matchAny
is true) or all (if matchAny
is false)..."
test/e2e/framework/util.go
Outdated
} | ||
} | ||
if phaseFoundInAllClaims && len(pvcNames) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have a separate error for len(pvcNames) == 0
?
) | ||
|
||
func testBindingWaitForFirstConsumer(client clientset.Interface, claim *v1.PersistentVolumeClaim, class *storage.StorageClass) (*v1.PersistentVolume, *v1.Node) { | ||
pvs, node := testBindingWaitForFirstConsumerMultiPVC(client, []*v1.PersistentVolumeClaim{claim}, class) | ||
return pvs[0], node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expect(len(pvs)).ToNot(Equal(0))
Expect(err).NotTo(HaveOccurred()) | ||
By("creating claims") | ||
var createdClaims []*v1.PersistentVolumeClaim | ||
var claimNames []string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: combine the two slices into a map
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The functions used below like WaitForPersistentVolumeClaimsPhase
, CreatePod
need access to the slices createdClaims
and claimNames
. So putting them into a map will require extracting the keys and values as slices multiple times down below. To avoid doing that and given we don't need to look up claim through names, I am keeping it as two separate slices that can be directly passed to the functions used below.
defer func() { | ||
framework.ExpectNoError(framework.DeletePersistentVolumeClaim(client, claim.Name, claim.Namespace), "Failed to delete PVC ", claim.Name) | ||
for _, claim := range createdClaims { | ||
framework.ExpectNoError(framework.DeletePersistentVolumeClaim(client, claim.Name, claim.Namespace), "Failed to delete PVC ", claim.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would a single deletion error stop other deletions? Should we issue all deletes first and check errors later?
Expect(err).To(HaveOccurred()) | ||
for _, claim := range createdClaims { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could this be simplified to framework.WaitForPersistentVolumeClaimsPhase(v1.ClaimPending)
and a very short timeout? If there's another function that just checks the instantaneous phase that'd be even better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Waiting and checking that the claim did not bind for a while is necessary to verify that the WaitForFirstConsumer is indeed taking effect. If we wait for an extremely short period (through something like framework.WaitForPersistentVolumeClaimsPhase(v1.ClaimPending)
), the verification that WaitForFirstConsumer
is indeed taking effect will not be effective as a PVC with Immediate binding mode also stay Pending for a little while (as the PV is created, attached, mounted etc.) before switching to bound.
|
||
return pv, node | ||
zone, ok := node.Labels[kubeletapis.LabelZoneFailureDomain] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes the function unusable for CSI drivers. IMO we should leave label/affinity checking outside the function for now. Maybe in the future we could have each volume plugin under test implement a callback check for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In volume_provisioning.go
, the zone checks have been moved out of testBindingWaitForFirstConsumerMultiPVC
. So I think this should be good already.
node, err := client.CoreV1().Nodes().Get(pod.Spec.NodeName, metav1.GetOptions{}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
pv, err := client.CoreV1().PersistentVolumes().Get(claim.Spec.VolumeName, metav1.GetOptions{}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
By("re-checking the claims to see they binded") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the label and node affinity check is left here, update the By()
message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not necessary as the node affinity/label checks have been moved out.
@@ -885,6 +911,52 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() { | |||
} | |||
}) | |||
}) | |||
Describe("DynamicProvisioner delayed binding with multiple PVCs [Slow]", func() { | |||
It("should create multiple persistent volumes in the same zone as node after a pod mounting the claims is started", func() { | |||
tests := []testsuites.StorageClassTest{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this test be pulled into a common function instead?
@@ -965,7 +1037,57 @@ var _ = utils.SIGDescribe("Dynamic Provisioning", func() { | |||
} | |||
}) | |||
}) | |||
|
|||
Describe("DynamicProvisioner delayed binding with allowedTopologies with multiple PVCs [Slow]", func() { | |||
It("should create multiple persistent volumes in the same zone as specified in allowedTopologies after a pod mounting the claims is started", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto (common function)
test/e2e/storage/regional_pd.go
Outdated
@@ -74,15 +74,17 @@ var _ = utils.SIGDescribe("Regional PD", func() { | |||
}) | |||
|
|||
It("should provision storage with delayed binding [Slow]", func() { | |||
testRegionalDelayedBinding(c, ns) | |||
testRegionalDelayedBinding(c, ns, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: 1 /* pvcCount */
Thanks for reviewing @verult. Code review comments so far addressed. |
/retest |
@@ -251,6 +261,101 @@ func checkGCEPD(volume *v1.PersistentVolume, volumeType string) error { | |||
return nil | |||
} | |||
|
|||
func testZonalDelayedBinding(c clientset.Interface, ns string, pvcCount int) { | |||
tests := []testsuites.StorageClassTest{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
testZonalDelayedBinding()
and testZonalDelayedBindingWithAllowedTopology()
share a lot of code, and their StorageClassTest
s are the same too. I was thinking we could combine these two functions
mostly LGTM, some minor comments! |
@verult latest CR comments addressed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
just a minor comment
@@ -261,17 +261,22 @@ func checkGCEPD(volume *v1.PersistentVolume, volumeType string) error { | |||
return nil | |||
} | |||
|
|||
func testZonalDelayedBinding(c clientset.Interface, ns string, pvcCount int) { | |||
func testZonalDelayedBinding(c clientset.Interface, ns string, specifyAllowedTopology bool, pvcCount int) { | |||
storageClassNameFmt := "Delayed binding %s storage class test %s" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
storageClassTestNameFmt
Signed-off-by: Deep Debroy <ddebroy@docker.com>
Thanks for reviewing @verult . Addressed the last review comment above and squashed all commits so far. PTAL and add back the LGTM if all looks good. |
/lgtm |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ddebroy, saad-ali The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/milestone v1.13 |
/retest Review the full test history for this PR. Silence the bot with an |
What type of PR is this?
/kind bug
What this PR does / why we need it:
This PR adds e2e tests that exercise creation of pods with multiple PVCs associated with storage classes configured with volume binding mode
WaitForFirstConsumer
. The tests ensure all PVs get provisioned in the same zone as the pod due to delayed binding.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 #68517
Special notes for your reviewer:
RePD versions of these tests will be added to this PR. This is currently read to review for PD and EBS.
Does this PR introduce a user-facing change?:
"NONE"
/sig storage