Skip to content

Commit

Permalink
Merge pull request #6368 from Lyndon-Li/issue-fix-6341
Browse files Browse the repository at this point in the history
Add UT for pkg/util
  • Loading branch information
Lyndon-Li committed Jun 15, 2023
2 parents cace727 + 75b7599 commit e3e0ce3
Show file tree
Hide file tree
Showing 7 changed files with 1,239 additions and 9 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/6368-Lyndon-Li
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add UT for pkg/util
16 changes: 16 additions & 0 deletions pkg/test/test_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,19 @@ func NewLoggerWithLevel(level logrus.Level) logrus.FieldLogger {
logger.Level = level
return logrus.NewEntry(logger)
}

type singleLogRecorder struct {
buffer *string
}

func (s *singleLogRecorder) Write(p []byte) (n int, err error) {
*s.buffer = string(p[:])
return len(p), nil
}

func NewSingleLogger(buffer *string) logrus.FieldLogger {
logger := logrus.New()
logger.Out = &singleLogRecorder{buffer: buffer}
logger.Level = logrus.TraceLevel
return logrus.NewEntry(logger)
}
13 changes: 5 additions & 8 deletions pkg/util/csi/volume_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,12 @@ func RetainVSC(ctx context.Context, snapshotClient snapshotter.SnapshotV1Interfa

// DeleteVolumeSnapshotContentIfAny deletes a VSC by name if it exists, and log an error when the deletion fails
func DeleteVolumeSnapshotContentIfAny(ctx context.Context, snapshotClient snapshotter.SnapshotV1Interface, vscName string, log logrus.FieldLogger) {
vsc, err := snapshotClient.VolumeSnapshotContents().Get(ctx, vscName, metav1.GetOptions{})
err := snapshotClient.VolumeSnapshotContents().Delete(ctx, vscName, metav1.DeleteOptions{})
if err != nil {
if !apierrors.IsNotFound(err) {
log.WithError(err).Warnf("Abort deleting VSC, it doesn't exist %s", vscName)
}
} else {
err = snapshotClient.VolumeSnapshotContents().Delete(ctx, vsc.Name, metav1.DeleteOptions{})
if err != nil {
log.WithError(err).Warnf("Failed to delete volume snapshot content %s", vsc.Name)
if apierrors.IsNotFound(err) {
log.WithError(err).Debugf("Abort deleting VSC, it doesn't exist %s", vscName)
} else {
log.WithError(err).Errorf("Failed to delete volume snapshot content %s", vscName)
}
}
}
Expand Down
232 changes: 232 additions & 0 deletions pkg/util/csi/volume_snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import (
clientTesting "k8s.io/client-go/testing"

"github.com/vmware-tanzu/velero/pkg/util/boolptr"

velerotest "github.com/vmware-tanzu/velero/pkg/test"
)

type reactor struct {
Expand Down Expand Up @@ -282,6 +284,12 @@ func TestEnsureDeleteVS(t *testing.T) {
},
err: "error to assure VolumeSnapshot is deleted, fake-vs: error to get VolumeSnapshot fake-vs: fake-get-error",
},
{
name: "success",
vsName: "fake-vs",
namespace: "fake-ns",
clientObj: []runtime.Object{vsObj},
},
}

for _, test := range tests {
Expand Down Expand Up @@ -336,6 +344,11 @@ func TestEnsureDeleteVSC(t *testing.T) {
},
err: "error to assure VolumeSnapshotContent is deleted, fake-vsc: error to get VolumeSnapshotContent fake-vsc: fake-get-error",
},
{
name: "success",
vscName: "fake-vsc",
clientObj: []runtime.Object{vscObj},
},
}

for _, test := range tests {
Expand All @@ -355,3 +368,222 @@ func TestEnsureDeleteVSC(t *testing.T) {
})
}
}

func TestDeleteVolumeSnapshotContentIfAny(t *testing.T) {
tests := []struct {
name string
clientObj []runtime.Object
reactors []reactor
vscName string
logMessage string
logLevel string
logError string
}{
{
name: "vsc not exist",
vscName: "fake-vsc",
logMessage: "Abort deleting VSC, it doesn't exist fake-vsc",
logLevel: "level=debug",
},
{
name: "deleete fail",
vscName: "fake-vsc",
reactors: []reactor{
{
verb: "delete",
resource: "volumesnapshotcontents",
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, errors.New("fake-delete-error")
},
},
},
logMessage: "Failed to delete volume snapshot content fake-vsc",
logLevel: "level=error",
logError: "error=fake-delete-error",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fakeSnapshotClient := snapshotFake.NewSimpleClientset(test.clientObj...)

for _, reactor := range test.reactors {
fakeSnapshotClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
}

logMessage := ""

DeleteVolumeSnapshotContentIfAny(context.Background(), fakeSnapshotClient.SnapshotV1(), test.vscName, velerotest.NewSingleLogger(&logMessage))

if len(test.logMessage) > 0 {
assert.Contains(t, logMessage, test.logMessage)
}

if len(test.logLevel) > 0 {
assert.Contains(t, logMessage, test.logLevel)
}

if len(test.logError) > 0 {
assert.Contains(t, logMessage, test.logError)
}
})
}
}

func TestDeleteVolumeSnapshotIfAny(t *testing.T) {
tests := []struct {
name string
clientObj []runtime.Object
reactors []reactor
vsName string
vsNamespace string
logMessage string
logLevel string
logError string
}{
{
name: "vs not exist",
vsName: "fake-vs",
vsNamespace: "fake-ns",
logMessage: "Abort deleting volume snapshot, it doesn't exist fake-ns/fake-vs",
logLevel: "level=debug",
},
{
name: "delete fail",
vsName: "fake-vs",
vsNamespace: "fake-ns",
reactors: []reactor{
{
verb: "delete",
resource: "volumesnapshots",
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, errors.New("fake-delete-error")
},
},
},
logMessage: "Failed to delete volume snapshot fake-ns/fake-vs",
logLevel: "level=error",
logError: "error=fake-delete-error",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fakeSnapshotClient := snapshotFake.NewSimpleClientset(test.clientObj...)

for _, reactor := range test.reactors {
fakeSnapshotClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
}

logMessage := ""

DeleteVolumeSnapshotIfAny(context.Background(), fakeSnapshotClient.SnapshotV1(), test.vsName, test.vsNamespace, velerotest.NewSingleLogger(&logMessage))

if len(test.logMessage) > 0 {
assert.Contains(t, logMessage, test.logMessage)
}

if len(test.logLevel) > 0 {
assert.Contains(t, logMessage, test.logLevel)
}

if len(test.logError) > 0 {
assert.Contains(t, logMessage, test.logError)
}
})
}
}

func TestRetainVSC(t *testing.T) {
vscObj := &snapshotv1api.VolumeSnapshotContent{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-vsc",
},
}

tests := []struct {
name string
clientObj []runtime.Object
reactors []reactor
vsc *snapshotv1api.VolumeSnapshotContent
updated *snapshotv1api.VolumeSnapshotContent
err string
}{
{
name: "already retained",
vsc: &snapshotv1api.VolumeSnapshotContent{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-vsc",
},
Spec: snapshotv1api.VolumeSnapshotContentSpec{
DeletionPolicy: snapshotv1api.VolumeSnapshotContentRetain,
},
},
},
{
name: "path vsc fail",
vsc: &snapshotv1api.VolumeSnapshotContent{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-vsc",
},
Spec: snapshotv1api.VolumeSnapshotContentSpec{
DeletionPolicy: snapshotv1api.VolumeSnapshotContentDelete,
},
},
reactors: []reactor{
{
verb: "patch",
resource: "volumesnapshotcontents",
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, errors.New("fake-patch-error")
},
},
},
err: "error patching VSC: fake-patch-error",
},
{
name: "success",
vsc: &snapshotv1api.VolumeSnapshotContent{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-vsc",
},
Spec: snapshotv1api.VolumeSnapshotContentSpec{
DeletionPolicy: snapshotv1api.VolumeSnapshotContentDelete,
},
},
clientObj: []runtime.Object{vscObj},
updated: &snapshotv1api.VolumeSnapshotContent{
ObjectMeta: metav1.ObjectMeta{
Name: "fake-vsc",
},
Spec: snapshotv1api.VolumeSnapshotContentSpec{
DeletionPolicy: snapshotv1api.VolumeSnapshotContentRetain,
},
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fakeSnapshotClient := snapshotFake.NewSimpleClientset(test.clientObj...)

for _, reactor := range test.reactors {
fakeSnapshotClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
}

returned, err := RetainVSC(context.Background(), fakeSnapshotClient.SnapshotV1(), test.vsc)

if len(test.err) == 0 {
assert.NoError(t, err)
} else {
assert.EqualError(t, err, test.err)
}

if test.updated != nil {
assert.Equal(t, *test.updated, *returned)
} else {
assert.Nil(t, returned)
}
})
}
}
Loading

0 comments on commit e3e0ce3

Please sign in to comment.