Merge pull request #110612 from mattcary/ss-integration

Add TestAutodeleteOwnerRefs statefulset integration test
This commit is contained in:
Kubernetes Prow Robot 2022-06-21 15:29:42 -07:00 committed by GitHub
commit 3beb8dc596
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 2 deletions

View File

@ -403,3 +403,89 @@ func TestStatefulSetStatusWithPodFail(t *testing.T) {
t.Fatalf("StatefulSet %s status has %d replicas, want replicas %d: %v", sts.Name, gotReplicas, wantReplicas, err) t.Fatalf("StatefulSet %s status has %d replicas, want replicas %d: %v", sts.Name, gotReplicas, wantReplicas, err)
} }
} }
func TestAutodeleteOwnerRefs(t *testing.T) {
tests := []struct {
name string
policy appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy
expectPodOwnerRef bool
expectSetOwnerRef bool
}{
{
name: "always retain",
policy: appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{
WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType,
WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType,
},
expectPodOwnerRef: false,
expectSetOwnerRef: false,
},
{
name: "delete on scaledown only",
policy: appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{
WhenDeleted: appsv1.RetainPersistentVolumeClaimRetentionPolicyType,
WhenScaled: appsv1.DeletePersistentVolumeClaimRetentionPolicyType,
},
expectPodOwnerRef: true,
expectSetOwnerRef: false,
},
{
name: "delete with set only",
policy: appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{
WhenDeleted: appsv1.DeletePersistentVolumeClaimRetentionPolicyType,
WhenScaled: appsv1.RetainPersistentVolumeClaimRetentionPolicyType,
},
expectPodOwnerRef: false,
expectSetOwnerRef: true,
},
{
name: "always delete",
policy: appsv1.StatefulSetPersistentVolumeClaimRetentionPolicy{
WhenDeleted: appsv1.DeletePersistentVolumeClaimRetentionPolicyType,
WhenScaled: appsv1.DeletePersistentVolumeClaimRetentionPolicyType,
},
expectPodOwnerRef: true,
expectSetOwnerRef: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StatefulSetAutoDeletePVC, true)()
closeFn, rm, informers, c := scSetup(t)
defer closeFn()
ns := framework.CreateNamespaceOrDie(c, "test-autodelete-ownerrefs", t)
defer framework.DeleteNamespaceOrDie(c, ns, t)
cancel := runControllerAndInformers(rm, informers)
defer cancel()
sts := newSTS("sts", ns.Name, 3)
sts.Spec.PersistentVolumeClaimRetentionPolicy = &test.policy
stss, _ := createSTSsPods(t, c, []*appsv1.StatefulSet{sts}, []*v1.Pod{})
sts = stss[0]
waitSTSStable(t, c, sts)
// Verify StatefulSet ownerref has been added as appropriate.
pvcClient := c.CoreV1().PersistentVolumeClaims(ns.Name)
pvcs := getStatefulSetPVCs(t, pvcClient, sts)
for _, pvc := range pvcs {
verifyOwnerRef(t, pvc, "StatefulSet", test.expectSetOwnerRef)
verifyOwnerRef(t, pvc, "Pod", false)
}
// Scale down to 1 pod and verify Pod ownerrefs as appropriate.
one := int32(1)
sts.Spec.Replicas = &one
waitSTSStable(t, c, sts)
pvcs = getStatefulSetPVCs(t, pvcClient, sts)
for i, pvc := range pvcs {
verifyOwnerRef(t, pvc, "StatefulSet", test.expectSetOwnerRef)
if i == 0 {
verifyOwnerRef(t, pvc, "Pod", false)
} else {
verifyOwnerRef(t, pvc, "Pod", test.expectPodOwnerRef)
}
}
})
}
}

View File

@ -110,8 +110,8 @@ func newSTS(name, namespace string, replicas int) *appsv1.StatefulSet {
{ {
Name: "datadir", Name: "datadir",
VolumeSource: v1.VolumeSource{ VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{ PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
Path: fmt.Sprintf("/tmp/%v", "datadir"), ClaimName: "fake-pvc-name",
}, },
}, },
}, },
@ -279,6 +279,35 @@ func getPods(t *testing.T, podClient typedv1.PodInterface, labelMap map[string]s
return pods return pods
} }
func getStatefulSetPVCs(t *testing.T, pvcClient typedv1.PersistentVolumeClaimInterface, sts *appsv1.StatefulSet) []*v1.PersistentVolumeClaim {
pvcs := []*v1.PersistentVolumeClaim{}
for i := int32(0); i < *sts.Spec.Replicas; i++ {
pvcName := fmt.Sprintf("%s-%s-%d", sts.Spec.VolumeClaimTemplates[0].Name, sts.Name, i)
pvc, err := pvcClient.Get(context.TODO(), pvcName, metav1.GetOptions{})
if err != nil {
t.Fatalf("failed to get PVC %s: %v", pvcName, err)
}
pvcs = append(pvcs, pvc)
}
return pvcs
}
func verifyOwnerRef(t *testing.T, pvc *v1.PersistentVolumeClaim, kind string, expected bool) {
found := false
for _, ref := range pvc.GetOwnerReferences() {
if ref.Kind == kind {
if expected {
found = true
} else {
t.Fatalf("Found %s ref but expected none for PVC %s", kind, pvc.Name)
}
}
}
if expected && !found {
t.Fatalf("Expected %s ref but found none for PVC %s", kind, pvc.Name)
}
}
func updateSTS(t *testing.T, stsClient typedappsv1.StatefulSetInterface, stsName string, updateFunc func(*appsv1.StatefulSet)) *appsv1.StatefulSet { func updateSTS(t *testing.T, stsClient typedappsv1.StatefulSetInterface, stsName string, updateFunc func(*appsv1.StatefulSet)) *appsv1.StatefulSet {
var sts *appsv1.StatefulSet var sts *appsv1.StatefulSet
if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {