/* Copyright 2019 The Rook Authors. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package k8sutil import ( "fmt" "testing" "time" "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" ) func TestDeleteResource(t *testing.T) { var deleteError error stubDelete := func() error { return deleteError } k8sNotFoundError := errors.NewNotFound(schema.GroupResource{Group: "group", Resource: "resource"}, "test") var verifyCount int var verifyReturnDeletedAtCount int stubVerify := func() error { verifyCount++ fmt.Println("verifyCount:", verifyCount, " - returnNilAt:", verifyReturnDeletedAtCount) if verifyCount == verifyReturnDeletedAtCount { return k8sNotFoundError } return fmt.Errorf("still not verified") } defaultWaitOpts := &WaitOptions{RetryCount: 2, RetryInterval: 1 * time.Millisecond} // Failure to delete should return error deleteError = fmt.Errorf("err on delete") err := DeleteResource(stubDelete, stubVerify, "test resource name", &DeleteOptions{}, defaultWaitOpts) assert.Error(t, err) // NotFound error should return error if DeleteOptions.MustDelete is set deleteError = k8sNotFoundError err = DeleteResource(stubDelete, stubVerify, "test resource name", &DeleteOptions{MustDelete: true}, defaultWaitOpts) assert.Error(t, err) // Default behavior should be to continue if resource doesn't exist deleteError = k8sNotFoundError err = DeleteResource(stubDelete, stubVerify, "test resource name", &DeleteOptions{}, defaultWaitOpts) assert.NoError(t, err) // Default behavior should be to NOT wait to verify resource deleteError = nil verifyCount = 0 err = DeleteResource(stubDelete, stubVerify, "test resource name", &DeleteOptions{}, defaultWaitOpts) assert.NoError(t, err) assert.Zero(t, verifyCount) // Verify that the default wait options are picked up // And that the verify function is called one time more than the retry count // And that delete can report error on timeout deleteError = nil verifyCount = 0 verifyReturnDeletedAtCount = 1000000 // do not return verify success deleteOpts := &DeleteOptions{} deleteOpts.Wait = true deleteOpts.ErrorOnTimeout = true err = DeleteResource(stubDelete, stubVerify, "test resource name", deleteOpts, defaultWaitOpts) assert.Error(t, err) assert.Equal(t, 3, verifyCount) assert.Equal(t, 1*time.Millisecond, unitTestRetryIntervalRecord) // Test that delete will not report error on timeout if so configured deleteOpts.ErrorOnTimeout = false err = DeleteResource(stubDelete, stubVerify, "test resource name", deleteOpts, defaultWaitOpts) assert.NoError(t, err) // Verify that delete will return successfully after some retries verifyCount = 0 verifyReturnDeletedAtCount = 2 deleteOpts = &DeleteOptions{} deleteOpts.Wait = true deleteOpts.ErrorOnTimeout = true err = DeleteResource(stubDelete, stubVerify, "test resource name", deleteOpts, defaultWaitOpts) assert.NoError(t, err) // Verify that specified retry count and interval in delete opts are picked up deleteError = nil verifyCount = 0 verifyReturnDeletedAtCount = 1000000 // do not return verify success deleteOpts = &DeleteOptions{} deleteOpts.Wait = true deleteOpts.ErrorOnTimeout = true deleteOpts.RetryCount = 5 deleteOpts.RetryInterval = 2 * time.Millisecond err = DeleteResource(stubDelete, stubVerify, "test resource name", deleteOpts, defaultWaitOpts) assert.Error(t, err) assert.Equal(t, 6, verifyCount) assert.Equal(t, 2*time.Millisecond, unitTestRetryIntervalRecord) }