...

Source file src/k8s.io/apiextensions-apiserver/test/integration/finalization_test.go

Documentation: k8s.io/apiextensions-apiserver/test/integration

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package integration
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/stretchr/testify/require"
    25  
    26  	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    27  	"k8s.io/apiextensions-apiserver/test/integration/fixtures"
    28  	"k8s.io/apimachinery/pkg/api/errors"
    29  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    30  	"k8s.io/apimachinery/pkg/util/wait"
    31  )
    32  
    33  func TestFinalization(t *testing.T) {
    34  	tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
    35  	require.NoError(t, err)
    36  	defer tearDown()
    37  
    38  	noxuDefinition := fixtures.NewNoxuV1CustomResourceDefinition(apiextensionsv1.ClusterScoped)
    39  	noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
    40  	require.NoError(t, err)
    41  
    42  	ns := "not-the-default"
    43  	name := "foo123"
    44  	noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition)
    45  
    46  	instance := fixtures.NewNoxuInstance(ns, name)
    47  	instance.SetFinalizers([]string{"noxu.example.com/finalizer"})
    48  	createdNoxuInstance, err := instantiateCustomResource(t, instance, noxuResourceClient, noxuDefinition)
    49  	require.NoError(t, err)
    50  
    51  	uid := createdNoxuInstance.GetUID()
    52  	err = noxuResourceClient.Delete(context.TODO(), name, metav1.DeleteOptions{
    53  		Preconditions: &metav1.Preconditions{
    54  			UID: &uid,
    55  		},
    56  	})
    57  	require.NoError(t, err)
    58  
    59  	// Deleting something with a finalizer sets deletion timestamp to a not-nil value but does not
    60  	// remove the object from the API server. Here we read it to confirm this.
    61  	gottenNoxuInstance, err := noxuResourceClient.Get(context.TODO(), name, metav1.GetOptions{})
    62  	require.NoError(t, err)
    63  
    64  	require.NotNil(t, gottenNoxuInstance.GetDeletionTimestamp())
    65  
    66  	// Trying to delete it again to confirm it will not remove the object because finalizer is still there.
    67  	err = noxuResourceClient.Delete(context.TODO(), name, metav1.DeleteOptions{
    68  		Preconditions: &metav1.Preconditions{
    69  			UID: &uid,
    70  		},
    71  	})
    72  	require.NoError(t, err)
    73  
    74  	// Removing the finalizers to allow the following delete remove the object.
    75  	// This step will fail if previous delete wrongly removed the object. The
    76  	// object will be deleted as part of the finalizer update.
    77  	for {
    78  		gottenNoxuInstance.SetFinalizers(nil)
    79  		_, err = noxuResourceClient.Update(context.TODO(), gottenNoxuInstance, metav1.UpdateOptions{})
    80  		if err == nil {
    81  			break
    82  		}
    83  		if !errors.IsConflict(err) {
    84  			require.NoError(t, err) // Fail on unexpected error
    85  		}
    86  		gottenNoxuInstance, err = noxuResourceClient.Get(context.TODO(), name, metav1.GetOptions{})
    87  		require.NoError(t, err)
    88  	}
    89  
    90  	// Check that the object is actually gone.
    91  	_, err = noxuResourceClient.Get(context.TODO(), name, metav1.GetOptions{})
    92  	require.Error(t, err)
    93  	require.True(t, errors.IsNotFound(err), "%#v", err)
    94  }
    95  
    96  func TestFinalizationAndDeletion(t *testing.T) {
    97  	tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
    98  	require.NoError(t, err)
    99  	defer tearDown()
   100  
   101  	// Create a CRD.
   102  	noxuDefinition := fixtures.NewNoxuV1CustomResourceDefinition(apiextensionsv1.ClusterScoped)
   103  	noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
   104  	require.NoError(t, err)
   105  
   106  	// Create a CR with a finalizer.
   107  	ns := "not-the-default"
   108  	name := "foo123"
   109  	noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition)
   110  
   111  	instance := fixtures.NewNoxuInstance(ns, name)
   112  	instance.SetFinalizers([]string{"noxu.example.com/finalizer"})
   113  	createdNoxuInstance, err := instantiateCustomResource(t, instance, noxuResourceClient, noxuDefinition)
   114  	require.NoError(t, err)
   115  
   116  	// Delete a CR. Because there's a finalizer, it will not get deleted now.
   117  	uid := createdNoxuInstance.GetUID()
   118  	err = noxuResourceClient.Delete(context.TODO(), name, metav1.DeleteOptions{
   119  		Preconditions: &metav1.Preconditions{
   120  			UID: &uid,
   121  		},
   122  	})
   123  	require.NoError(t, err)
   124  
   125  	// Check is the CR scheduled for deletion.
   126  	gottenNoxuInstance, err := noxuResourceClient.Get(context.TODO(), name, metav1.GetOptions{})
   127  	require.NoError(t, err)
   128  	require.NotNil(t, gottenNoxuInstance.GetDeletionTimestamp())
   129  
   130  	// Delete the CRD.
   131  	fixtures.DeleteV1CustomResourceDefinition(noxuDefinition, apiExtensionClient)
   132  
   133  	// Check is CR still there after the CRD deletion.
   134  	gottenNoxuInstance, err = noxuResourceClient.Get(context.TODO(), name, metav1.GetOptions{})
   135  	require.NoError(t, err)
   136  
   137  	// Update the CR to remove the finalizer.
   138  	for {
   139  		gottenNoxuInstance.SetFinalizers(nil)
   140  		_, err = noxuResourceClient.Update(context.TODO(), gottenNoxuInstance, metav1.UpdateOptions{})
   141  		if err == nil {
   142  			break
   143  		}
   144  		if !errors.IsConflict(err) {
   145  			require.NoError(t, err) // Fail on unexpected error
   146  		}
   147  		gottenNoxuInstance, err = noxuResourceClient.Get(context.TODO(), name, metav1.GetOptions{})
   148  		require.NoError(t, err)
   149  	}
   150  
   151  	// Verify the CR is gone.
   152  	// It should return the NonFound error.
   153  	_, err = noxuResourceClient.Get(context.TODO(), name, metav1.GetOptions{})
   154  	if !errors.IsNotFound(err) {
   155  		t.Fatalf("unable to delete cr: %v", err)
   156  	}
   157  
   158  	err = wait.Poll(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) {
   159  		_, err = apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), noxuDefinition.Name, metav1.GetOptions{})
   160  		return errors.IsNotFound(err), err
   161  	})
   162  	if !errors.IsNotFound(err) {
   163  		t.Fatalf("unable to delete crd: %v", err)
   164  	}
   165  }
   166  

View as plain text