Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/result/kyma/usecase/use_cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ const (
DeleteManifests result.UseCase = "DeleteManifests"
DeleteMetrics result.UseCase = "DeleteMetrics"
RemoveKymaFinalizers result.UseCase = "RemoveKymaFinalizers"
ProcessKymaDeletion result.UseCase = "ProcessKymaDeletion"
)
7 changes: 5 additions & 2 deletions internal/service/kyma/deletion/deletion_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/kyma-project/lifecycle-manager/api/v1beta2"
"github.com/kyma-project/lifecycle-manager/internal/result"
"github.com/kyma-project/lifecycle-manager/internal/result/kyma/usecase"
)

var (
Expand Down Expand Up @@ -42,7 +43,8 @@ func (s *Service) Delete(ctx context.Context, kyma *v1beta2.Kyma) result.Result
isApplicable, err := step.IsApplicable(ctx, kyma)
if err != nil {
return result.Result{
Err: errors.Join(ErrUnableToDetermineUsecaseApplicability, err),
UseCase: step.Name(),
Err: errors.Join(ErrUnableToDetermineUsecaseApplicability, err),
}
}
if isApplicable {
Expand All @@ -51,6 +53,7 @@ func (s *Service) Delete(ctx context.Context, kyma *v1beta2.Kyma) result.Result
}

return result.Result{
Err: ErrNoUseCaseApplicable,
UseCase: usecase.ProcessKymaDeletion,
Err: ErrNoUseCaseApplicable,
}
}
217 changes: 217 additions & 0 deletions internal/service/kyma/deletion/deletion_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
package deletion_test

import (
"context"
"fmt"
"testing"

Check failure on line 7 in internal/service/kyma/deletion/deletion_service_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not properly formatted (gci)
"github.com/kyma-project/lifecycle-manager/api/v1beta2"
"github.com/kyma-project/lifecycle-manager/internal/result"
"github.com/kyma-project/lifecycle-manager/internal/result/kyma/usecase"
"github.com/kyma-project/lifecycle-manager/internal/service/kyma/deletion"

Check failure on line 11 in internal/service/kyma/deletion/deletion_service_test.go

View workflow job for this annotation

GitHub Actions / lint

import "github.com/kyma-project/lifecycle-manager/internal/service/kyma/deletion" imported without alias but must be with alias "kymadeletionsvc" according to config (importas)
"github.com/kyma-project/lifecycle-manager/pkg/testutils/random"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func Test_Delete_ReturnsError_WhenIsApplicableReturnsError(t *testing.T) {
kyma := &v1beta2.Kyma{}
uc1 := &useCaseStub{isApplicable: true, err: assert.AnError}

svc := deletion.NewService(
uc1,
nil,
nil,
)

result := svc.Delete(t.Context(), kyma)

require.ErrorIs(t, result.Err, assert.AnError)
assert.Equal(t, uc1.Name(), result.UseCase)
assert.True(t, uc1.isApplicableCalled)
assert.False(t, uc1.executeCalled)
assert.Equal(t, kyma, uc1.receivedKyma)
}

func Test_Delete_ReturnsEarly_WhenIsApplicableReturnsError(t *testing.T) {
kyma := &v1beta2.Kyma{}
uc1 := &useCaseStub{isApplicable: false, err: nil}
uc2 := &useCaseStub{isApplicable: true, err: assert.AnError}
uc3 := &useCaseStub{isApplicable: false, err: nil}

svc := deletion.NewService(
uc1,
uc2,
uc3,
)

result := svc.Delete(t.Context(), kyma)

require.ErrorIs(t, result.Err, assert.AnError)
assert.Equal(t, uc2.Name(), result.UseCase)
assert.True(t, uc1.isApplicableCalled)
assert.False(t, uc1.executeCalled)
assert.True(t, uc2.isApplicableCalled)
assert.False(t, uc2.executeCalled)
assert.False(t, uc3.isApplicableCalled)
assert.False(t, uc3.executeCalled)
assert.Equal(t, kyma, uc1.receivedKyma)
assert.Equal(t, kyma, uc2.receivedKyma)
}

func Test_Delete_ExecutesOnlyFirstApplicableUseCase(t *testing.T) {
kyma := &v1beta2.Kyma{}
uc1 := &useCaseStub{isApplicable: false, err: nil}
uc2 := &useCaseStub{isApplicable: true, err: nil}
uc3 := &useCaseStub{isApplicable: true, err: nil}

svc := deletion.NewService(
uc1,
uc2,
uc3,
)

result := svc.Delete(t.Context(), kyma)

require.NoError(t, result.Err)
assert.Equal(t, uc2.Name(), result.UseCase)
assert.True(t, uc1.isApplicableCalled)
assert.False(t, uc1.executeCalled)
assert.True(t, uc2.isApplicableCalled)
assert.True(t, uc2.executeCalled)
assert.False(t, uc3.isApplicableCalled)
assert.False(t, uc3.executeCalled)
assert.Equal(t, kyma, uc1.receivedKyma)
assert.Equal(t, kyma, uc2.receivedKyma)
}

func Test_Delete_Fallthrough_WhenNoUseCaseIsApplicable(t *testing.T) {
kyma := &v1beta2.Kyma{}
uc1 := &useCaseStub{isApplicable: false, err: nil}
uc2 := &useCaseStub{isApplicable: false, err: nil}
uc3 := &useCaseStub{isApplicable: false, err: nil}

svc := deletion.NewService(
uc1,
uc2,
uc3,
)

result := svc.Delete(t.Context(), kyma)

require.ErrorIs(t, result.Err, deletion.ErrNoUseCaseApplicable)
assert.Equal(t, usecase.ProcessKymaDeletion, result.UseCase)
assert.True(t, uc1.isApplicableCalled)
assert.False(t, uc1.executeCalled)
assert.True(t, uc2.isApplicableCalled)
assert.False(t, uc2.executeCalled)
assert.True(t, uc3.isApplicableCalled)
assert.False(t, uc3.executeCalled)
assert.Equal(t, kyma, uc1.receivedKyma)
assert.Equal(t, kyma, uc2.receivedKyma)
assert.Equal(t, kyma, uc3.receivedKyma)
}

func Test_Delete_ExecutesCorrectOrderOfUseCases(t *testing.T) {
kyma := &v1beta2.Kyma{}

recordedOrder := []string{}
uc1 := &orderRecordingUseCaseStub{recorder: &recordedOrder}
uc2 := &orderRecordingUseCaseStub{recorder: &recordedOrder}
uc3 := &orderRecordingUseCaseStub{recorder: &recordedOrder}

executionOrder := []string{
fmt.Sprintf("%s-%s", uc1.Name(), "isApplicable"),
fmt.Sprintf("%s-%s", uc1.Name(), "execute"),
fmt.Sprintf("%s-%s", uc1.Name(), "isApplicable"),
fmt.Sprintf("%s-%s", uc2.Name(), "isApplicable"),
fmt.Sprintf("%s-%s", uc2.Name(), "execute"),
fmt.Sprintf("%s-%s", uc1.Name(), "isApplicable"),
fmt.Sprintf("%s-%s", uc2.Name(), "isApplicable"),
fmt.Sprintf("%s-%s", uc3.Name(), "isApplicable"),
fmt.Sprintf("%s-%s", uc3.Name(), "execute"),
}

svc := deletion.NewService(
uc1,
uc2,
uc3,
)

_ = svc.Delete(t.Context(), kyma)
_ = svc.Delete(t.Context(), kyma)
_ = svc.Delete(t.Context(), kyma)

require.Equal(t, executionOrder, recordedOrder)
}

type useCaseStub struct {
receivedKyma *v1beta2.Kyma
name result.UseCase

isApplicableCalled bool
executeCalled bool

isApplicable bool
err error
}

func (u *useCaseStub) IsApplicable(_ context.Context, kyma *v1beta2.Kyma) (bool, error) {
u.receivedKyma = kyma
u.isApplicableCalled = true
return u.isApplicable, u.err
}

func (u *useCaseStub) Execute(_ context.Context, kyma *v1beta2.Kyma) result.Result {
u.receivedKyma = kyma
u.executeCalled = true
return result.Result{
UseCase: u.Name(),
Err: u.err,
}
}

func (u *useCaseStub) Name() result.UseCase {
if u.name == "" {
u.name = result.UseCase(random.Name())
}

return u.name
}

type orderRecordingUseCaseStub struct {
name result.UseCase
appliedOnce bool
recorder *[]string
}

func (u *orderRecordingUseCaseStub) IsApplicable(_ context.Context, _ *v1beta2.Kyma) (bool, error) {
u.record("isApplicable")

if !u.appliedOnce {
u.appliedOnce = true
return true, nil
}

return false, nil
}

func (u *orderRecordingUseCaseStub) Execute(_ context.Context, _ *v1beta2.Kyma) result.Result {
u.record("execute")
return result.Result{
UseCase: u.Name(),
Err: nil,
}
}

func (u *orderRecordingUseCaseStub) Name() result.UseCase {
if u.name == "" {
u.name = result.UseCase(random.Name())
}

return u.name
}

func (u *orderRecordingUseCaseStub) record(phase string) {
*u.recorder = append(*u.recorder, fmt.Sprintf("%s-%s", u.Name(), phase))
}
Loading