Skip to content

Commit 3beb8dc

Browse files
authored
Merge pull request kubernetes#110612 from mattcary/ss-integration
Add TestAutodeleteOwnerRefs statefulset integration test
2 parents 4720f07 + 3af09ab commit 3beb8dc

File tree

2 files changed

+117
-2
lines changed

2 files changed

+117
-2
lines changed

test/integration/statefulset/statefulset_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,3 +403,89 @@ func TestStatefulSetStatusWithPodFail(t *testing.T) {
403403
t.Fatalf("StatefulSet %s status has %d replicas, want replicas %d: %v", sts.Name, gotReplicas, wantReplicas, err)
404404
}
405405
}
406+
407+
func TestAutodeleteOwnerRefs(t *testing.T) {
408+
tests := []struct {
409+
name string
410+
policy appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy
411+
expectPodOwnerRef bool
412+
expectSetOwnerRef bool
413+
}{
414+
{
415+
name: "always retain",
416+
policy: appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{
417+
WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType,
418+
WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType,
419+
},
420+
expectPodOwnerRef: false,
421+
expectSetOwnerRef: false,
422+
},
423+
{
424+
name: "delete on scaledown only",
425+
policy: appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{
426+
WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType,
427+
WhenScaled: appsv1.DeletePersistentVolumeClaimRetentionPolicyType,
428+
},
429+
expectPodOwnerRef: true,
430+
expectSetOwnerRef: false,
431+
},
432+
{
433+
name: "delete with set only",
434+
policy: appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{
435+
WhenDeleted: appsv1.DeletePersistentVolumeClaimRetentionPolicyType,
436+
WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType,
437+
},
438+
expectPodOwnerRef: false,
439+
expectSetOwnerRef: true,
440+
},
441+
{
442+
name: "always delete",
443+
policy: appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{
444+
WhenDeleted: appsv1.DeletePersistentVolumeClaimRetentionPolicyType,
445+
WhenScaled: appsv1.DeletePersistentVolumeClaimRetentionPolicyType,
446+
},
447+
expectPodOwnerRef: true,
448+
expectSetOwnerRef: true,
449+
},
450+
}
451+
for _, test := range tests {
452+
t.Run(test.name, func(t *testing.T) {
453+
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, true)()
454+
closeFn, rm, informers, c := scSetup(t)
455+
defer closeFn()
456+
ns := framework.CreateNamespaceOrDie(c, "test-autodelete-ownerrefs", t)
457+
defer framework.DeleteNamespaceOrDie(c, ns, t)
458+
cancel := runControllerAndInformers(rm, informers)
459+
defer cancel()
460+
461+
sts := newSTS("sts", ns.Name, 3)
462+
sts.Spec.PersistentVolumeClaimRetentionPolicy = &test.policy
463+
stss, _ := createSTSsPods(t, c, []*appsv1.StatefulSet{sts}, []*v1.Pod{})
464+
sts = stss[0]
465+
waitSTSStable(t, c, sts)
466+
467+
// Verify StatefulSet ownerref has been added as appropriate.
468+
pvcClient := c.CoreV1().PersistentVolumeClaims(ns.Name)
469+
pvcs := getStatefulSetPVCs(t, pvcClient, sts)
470+
for _, pvc := range pvcs {
471+
verifyOwnerRef(t, pvc, "StatefulSet", test.expectSetOwnerRef)
472+
verifyOwnerRef(t, pvc, "Pod", false)
473+
}
474+
475+
// Scale down to 1 pod and verify Pod ownerrefs as appropriate.
476+
one := int32(1)
477+
sts.Spec.Replicas = &one
478+
waitSTSStable(t, c, sts)
479+
480+
pvcs = getStatefulSetPVCs(t, pvcClient, sts)
481+
for i, pvc := range pvcs {
482+
verifyOwnerRef(t, pvc, "StatefulSet", test.expectSetOwnerRef)
483+
if i == 0 {
484+
verifyOwnerRef(t, pvc, "Pod", false)
485+
} else {
486+
verifyOwnerRef(t, pvc, "Pod", test.expectPodOwnerRef)
487+
}
488+
}
489+
})
490+
}
491+
}

test/integration/statefulset/util.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ func newSTS(name, namespace string, replicas int) *appsv1.StatefulSet {
110110
{
111111
Name: "datadir",
112112
VolumeSource: v1.VolumeSource{
113-
HostPath: &v1.HostPathVolumeSource{
114-
Path: fmt.Sprintf("/tmp/%v", "datadir"),
113+
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
114+
ClaimName: "fake-pvc-name",
115115
},
116116
},
117117
},
@@ -279,6 +279,35 @@ func getPods(t *testing.T, podClient typedv1.PodInterface, labelMap map[string]s
279279
return pods
280280
}
281281

282+
func getStatefulSetPVCs(t *testing.T, pvcClient typedv1.PersistentVolumeClaimInterface, sts *appsv1.StatefulSet) []*v1.PersistentVolumeClaim {
283+
pvcs := []*v1.PersistentVolumeClaim{}
284+
for i := int32(0); i < *sts.Spec.Replicas; i++ {
285+
pvcName := fmt.Sprintf("%s-%s-%d", sts.Spec.VolumeClaimTemplates[0].Name, sts.Name, i)
286+
pvc, err := pvcClient.Get(context.TODO(), pvcName, metav1.GetOptions{})
287+
if err != nil {
288+
t.Fatalf("failed to get PVC %s: %v", pvcName, err)
289+
}
290+
pvcs = append(pvcs, pvc)
291+
}
292+
return pvcs
293+
}
294+
295+
func verifyOwnerRef(t *testing.T, pvc *v1.PersistentVolumeClaim, kind string, expected bool) {
296+
found := false
297+
for _, ref := range pvc.GetOwnerReferences() {
298+
if ref.Kind == kind {
299+
if expected {
300+
found = true
301+
} else {
302+
t.Fatalf("Found %s ref but expected none for PVC %s", kind, pvc.Name)
303+
}
304+
}
305+
}
306+
if expected && !found {
307+
t.Fatalf("Expected %s ref but found none for PVC %s", kind, pvc.Name)
308+
}
309+
}
310+
282311
func updateSTS(t *testing.T, stsClient typedappsv1.StatefulSetInterface, stsName string, updateFunc func(*appsv1.StatefulSet)) *appsv1.StatefulSet {
283312
var sts *appsv1.StatefulSet
284313
if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {

0 commit comments

Comments
 (0)