Repository: kubernetes/kubernetes
File: test/e2e/storage/framework/volume_group_snapshot_resource.go (Go)

Code before:
		}

		// Delete VolumeSnapshotContent
		err = dc.Resource(utils.SnapshotContentGVR).Delete(ctx, contentName, metav1.DeleteOptions{})
		if err != nil && !apierrors.IsNotFound(err) {
			framework.Logf("Warning: failed to delete VolumeSnapshotContent %q: %v", contentName, err)
		}
	}

	// Wait for all VolumeSnapshotContents to be deleted
	framework.Logf("Waiting for VolumeSnapshotContents to be deleted")
	for _, contentName := range contentNames.UnsortedList() {
		if err := utils.WaitForGVRDeletion(ctx, dc, utils.SnapshotContentGVR, contentName, framework.Poll, timeouts.SnapshotDelete); err != nil {
			framework.Logf("Warning: VolumeSnapshotContent %q may not be fully deleted: %v", contentName, err)
		}
	}
}

// cleanupRetainedVGSContent forcibly deletes VolumeGroupSnapshotContent with Retain policy
func (r *VolumeGroupSnapshotResource) cleanupRetainedVGSContent(ctx context.Context, dc dynamic.Interface, vgscName string, timeouts *framework.TimeoutContext) {
	framework.Logf("Deleting VGSContent %q", vgscName)

	// Refetch the latest version to avoid resource conflict
	boundVGSContent, err := dc.Resource(utils.VolumeGroupSnapshotContentGVR).Get(ctx, vgscName, metav1.GetOptions{})
	if err != nil && !apierrors.IsNotFound(err) {
		framework.Logf("Warning: failed to refetch VGSContent %q: %v", vgscName, err)
	}

	// Update deletion policy to Delete if we successfully fetched it
	if boundVGSContent != nil && err == nil {
		spec := boundVGSContent.Object["spec"].(map[string]interface{})
		spec["deletionPolicy"] = "Delete"
		_, err = dc.Resource(utils.VolumeGroupSnapshotContentGVR).Update(ctx, boundVGSContent, metav1.UpdateOptions{})
		if err != nil && !apierrors.IsNotFound(err) {
			framework.Logf("Warning: failed to update VGSContent %q deletion policy: %v", vgscName, err)
		}
	}

	// Delete VGSContent
	err = dc.Resource(utils.VolumeGroupSnapshotContentGVR).Delete(ctx, vgscName, metav1.DeleteOptions{})
	if err != nil && !apierrors.IsNotFound(err) {
		framework.Logf("Warning: failed to delete VGSContent %q: %v", vgscName, err)
	}

	// Wait for VGSContent to be deleted
	framework.Logf("Waiting for VGSContent %q to be deleted", vgscName)
	err = utils.WaitForGVRDeletion(ctx, dc, utils.VolumeGroupSnapshotContentGVR, vgscName, framework.Poll, timeouts.SnapshotDelete)
	if err != nil && !apierrors.IsNotFound(err) {
		framework.Logf("Warning: VGSContent %q may not be fully deleted: %v", vgscName, err)
	}
}

Review comment (bug):
Please throw an error + return. We expect the content to exist and it's a bug somewhere if it does not,

Code after:
	}

	// Wait for all VolumeSnapshotContents to be deleted
	framework.Logf("Waiting for VolumeSnapshotContents to be deleted")
	for _, contentName := range contentNames.UnsortedList() {
		if err := utils.WaitForGVRDeletion(ctx, dc, utils.SnapshotContentGVR, contentName, framework.Poll, timeouts.SnapshotDelete); err != nil {
			framework.Failf("VolumeSnapshotContent %q was not fully deleted: %v", contentName, err)
			return
		}
	}
}

// cleanupRetainedVGSContent forcibly deletes VolumeGroupSnapshotContent with Retain policy
func (r *VolumeGroupSnapshotResource) cleanupRetainedVGSContent(ctx context.Context, dc dynamic.Interface, vgscName string, timeouts *framework.TimeoutContext) {
	framework.Logf("Deleting VGSContent %q", vgscName)

	// Patch deletion policy to Delete
	patchData := []byte(`{"spec":{"deletionPolicy":"Delete"}}`)
	_, err := dc.Resource(utils.VolumeGroupSnapshotContentGVR).Patch(ctx, vgscName, types.MergePatchType, patchData, metav1.PatchOptions{})
	if err != nil {
		framework.Failf("Failed to patch VGSContent %q deletion policy: %v", vgscName, err)
		return
	}

	// Delete VGSContent
	err = dc.Resource(utils.VolumeGroupSnapshotContentGVR).Delete(ctx, vgscName, metav1.DeleteOptions{})
	if err != nil {
		framework.Failf("Failed to delete VGSContent %q: %v", vgscName, err)
		return
	}

	// Wait for VGSContent to be deleted
	framework.Logf("Waiting for VGSContent %q to be deleted", vgscName)
	err = utils.WaitForGVRDeletion(ctx, dc, utils.VolumeGroupSnapshotContentGVR, vgscName, framework.Poll, timeouts.SnapshotDelete)
	if err != nil {
		framework.Failf("VGSContent %q was not fully deleted: %v", vgscName, err)
		return
	}
}

// verifyVolumeSnapshotContentsDeletion verifies that all VolumeSnapshotContents have been deleted
func (r *VolumeGroupSnapshotResource) verifyVolumeSnapshotContentsDeletion(ctx context.Context, dc dynamic.Interface, contentNames sets.Set[string], timeouts *framework.TimeoutContext) {
	ginkgo.By("Verifying all VolumeSnapshotContents have been deleted")
	var verifyErrs []error
	for _, contentName := range contentNames.UnsortedList() {
		err := utils.EnsureGVRDeletion(ctx, dc, utils.SnapshotContentGVR, contentName, framework.Poll, timeouts.SnapshotDelete, "")
		if err != nil {
			verifyErrs = append(verifyErrs, fmt.Errorf("VolumeSnapshotContent %q should be deleted: %w", contentName, err))
		}
	}
	if len(verifyErrs) > 0 {