mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-09-03 06:37:11 +00:00
Merge pull request #6368 from Lyndon-Li/issue-fix-6341
Add UT for pkg/util
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Add UT for pkg/util
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -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 {
|
||||
@@ -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 {
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import (
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
clientTesting "k8s.io/client-go/testing"
|
||||
|
||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||
)
|
||||
|
||||
func TestEnsureDeletePod(t *testing.T) {
|
||||
@@ -91,3 +93,253 @@ func TestEnsureDeletePod(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsPodRunning(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pod *corev1api.Pod
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "pod is nil",
|
||||
err: "invalid input pod",
|
||||
},
|
||||
{
|
||||
name: "pod is not scheduled",
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pod",
|
||||
},
|
||||
Status: corev1api.PodStatus{
|
||||
Phase: "fake-phase",
|
||||
},
|
||||
},
|
||||
err: "pod is not scheduled, name=fake-pod, namespace=fake-ns, phase=fake-phase",
|
||||
},
|
||||
{
|
||||
name: "pod is not running",
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pod",
|
||||
},
|
||||
Spec: corev1api.PodSpec{
|
||||
NodeName: "fake-node",
|
||||
},
|
||||
Status: corev1api.PodStatus{
|
||||
Phase: "fake-phase",
|
||||
},
|
||||
},
|
||||
err: "pod is not in the expected status, name=fake-pod, namespace=fake-ns, phase=fake-phase: pod is not running",
|
||||
},
|
||||
{
|
||||
name: "pod is being deleted",
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pod",
|
||||
DeletionTimestamp: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
Spec: corev1api.PodSpec{
|
||||
NodeName: "fake-node",
|
||||
},
|
||||
Status: corev1api.PodStatus{
|
||||
Phase: corev1api.PodRunning,
|
||||
},
|
||||
},
|
||||
err: "pod is being terminated, name=fake-pod, namespace=fake-ns, phase=Running",
|
||||
},
|
||||
{
|
||||
name: "success",
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pod",
|
||||
},
|
||||
Spec: corev1api.PodSpec{
|
||||
NodeName: "fake-node",
|
||||
},
|
||||
Status: corev1api.PodStatus{
|
||||
Phase: corev1api.PodRunning,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := IsPodRunning(test.pod)
|
||||
if err != nil {
|
||||
assert.EqualError(t, err, test.err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsPodScheduled(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pod *corev1api.Pod
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "pod is nil",
|
||||
err: "invalid input pod",
|
||||
},
|
||||
{
|
||||
name: "pod is not scheduled",
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pod",
|
||||
},
|
||||
Status: corev1api.PodStatus{
|
||||
Phase: "fake-phase",
|
||||
},
|
||||
},
|
||||
err: "pod is not scheduled, name=fake-pod, namespace=fake-ns, phase=fake-phase",
|
||||
},
|
||||
{
|
||||
name: "pod is not running or pending",
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pod",
|
||||
},
|
||||
Spec: corev1api.PodSpec{
|
||||
NodeName: "fake-node",
|
||||
},
|
||||
Status: corev1api.PodStatus{
|
||||
Phase: "fake-phase",
|
||||
},
|
||||
},
|
||||
err: "pod is not in the expected status, name=fake-pod, namespace=fake-ns, phase=fake-phase: pod is not running or pending",
|
||||
},
|
||||
{
|
||||
name: "pod is being deleted",
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pod",
|
||||
DeletionTimestamp: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
Spec: corev1api.PodSpec{
|
||||
NodeName: "fake-node",
|
||||
},
|
||||
Status: corev1api.PodStatus{
|
||||
Phase: corev1api.PodRunning,
|
||||
},
|
||||
},
|
||||
err: "pod is being terminated, name=fake-pod, namespace=fake-ns, phase=Running",
|
||||
},
|
||||
{
|
||||
name: "success on running",
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pod",
|
||||
},
|
||||
Spec: corev1api.PodSpec{
|
||||
NodeName: "fake-node",
|
||||
},
|
||||
Status: corev1api.PodStatus{
|
||||
Phase: corev1api.PodRunning,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "success on pending",
|
||||
pod: &corev1api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pod",
|
||||
},
|
||||
Spec: corev1api.PodSpec{
|
||||
NodeName: "fake-node",
|
||||
},
|
||||
Status: corev1api.PodStatus{
|
||||
Phase: corev1api.PodPending,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := IsPodScheduled(test.pod)
|
||||
if err != nil {
|
||||
assert.EqualError(t, err, test.err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeletePodIfAny(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
podName string
|
||||
podNamespace string
|
||||
kubeClientObj []runtime.Object
|
||||
kubeReactors []reactor
|
||||
logMessage string
|
||||
logLevel string
|
||||
logError string
|
||||
}{
|
||||
{
|
||||
name: "get fail",
|
||||
podName: "fake-pod",
|
||||
podNamespace: "fake-namespace",
|
||||
logMessage: "Abort deleting pod, it doesn't exist fake-namespace/fake-pod",
|
||||
logLevel: "level=debug",
|
||||
},
|
||||
{
|
||||
name: "delete fail",
|
||||
podName: "fake-pod",
|
||||
podNamespace: "fake-namespace",
|
||||
kubeReactors: []reactor{
|
||||
{
|
||||
verb: "delete",
|
||||
resource: "pods",
|
||||
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("fake-delete-error")
|
||||
},
|
||||
},
|
||||
},
|
||||
logMessage: "Failed to delete pod fake-namespace/fake-pod",
|
||||
logLevel: "level=error",
|
||||
logError: "error=fake-delete-error",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fakeKubeClient := fake.NewSimpleClientset(test.kubeClientObj...)
|
||||
|
||||
for _, reactor := range test.kubeReactors {
|
||||
fakeKubeClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
|
||||
}
|
||||
|
||||
var kubeClient kubernetes.Interface = fakeKubeClient
|
||||
|
||||
logMessage := ""
|
||||
DeletePodIfAny(context.Background(), kubeClient.CoreV1(), test.podName, test.podNamespace, 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -31,6 +32,8 @@ import (
|
||||
storagev1api "k8s.io/api/storage/v1"
|
||||
|
||||
clientTesting "k8s.io/client-go/testing"
|
||||
|
||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||
)
|
||||
|
||||
type reactor struct {
|
||||
@@ -284,3 +287,550 @@ func TestWaitPVCConsumed(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeletePVCIfAny(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pvcName string
|
||||
pvcNamespace string
|
||||
kubeClientObj []runtime.Object
|
||||
kubeReactors []reactor
|
||||
logMessage string
|
||||
logLevel string
|
||||
logError string
|
||||
}{
|
||||
{
|
||||
name: "get fail",
|
||||
pvcName: "fake-pvc",
|
||||
pvcNamespace: "fake-namespace",
|
||||
logMessage: "Abort deleting PVC, it doesn't exist, fake-namespace/fake-pvc",
|
||||
logLevel: "level=debug",
|
||||
},
|
||||
{
|
||||
name: "delete fail",
|
||||
pvcName: "fake-pvc",
|
||||
pvcNamespace: "fake-namespace",
|
||||
kubeReactors: []reactor{
|
||||
{
|
||||
verb: "delete",
|
||||
resource: "persistentvolumeclaims",
|
||||
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("fake-delete-error")
|
||||
},
|
||||
},
|
||||
},
|
||||
logMessage: "Failed to delete pvc fake-namespace/fake-pvc",
|
||||
logLevel: "level=error",
|
||||
logError: "error=fake-delete-error",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fakeKubeClient := fake.NewSimpleClientset(test.kubeClientObj...)
|
||||
|
||||
for _, reactor := range test.kubeReactors {
|
||||
fakeKubeClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
|
||||
}
|
||||
|
||||
var kubeClient kubernetes.Interface = fakeKubeClient
|
||||
|
||||
logMessage := ""
|
||||
DeletePVCIfAny(context.Background(), kubeClient.CoreV1(), test.pvcName, test.pvcNamespace, 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 TestDeletePVIfAny(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pvName string
|
||||
kubeClientObj []runtime.Object
|
||||
kubeReactors []reactor
|
||||
logMessage string
|
||||
logLevel string
|
||||
logError string
|
||||
}{
|
||||
{
|
||||
name: "get fail",
|
||||
pvName: "fake-pv",
|
||||
logMessage: "Abort deleting PV, it doesn't exist, fake-pv",
|
||||
logLevel: "level=debug",
|
||||
},
|
||||
{
|
||||
name: "delete fail",
|
||||
pvName: "fake-pv",
|
||||
kubeReactors: []reactor{
|
||||
{
|
||||
verb: "delete",
|
||||
resource: "persistentvolumes",
|
||||
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("fake-delete-error")
|
||||
},
|
||||
},
|
||||
},
|
||||
logMessage: "Failed to delete PV fake-pv",
|
||||
logLevel: "level=error",
|
||||
logError: "error=fake-delete-error",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fakeKubeClient := fake.NewSimpleClientset(test.kubeClientObj...)
|
||||
|
||||
for _, reactor := range test.kubeReactors {
|
||||
fakeKubeClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
|
||||
}
|
||||
|
||||
var kubeClient kubernetes.Interface = fakeKubeClient
|
||||
|
||||
logMessage := ""
|
||||
DeletePVIfAny(context.Background(), kubeClient.CoreV1(), test.pvName, 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 TestEnsureDeletePVC(t *testing.T) {
|
||||
pvcObject := &corev1api.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pvc",
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
clientObj []runtime.Object
|
||||
pvcName string
|
||||
namespace string
|
||||
reactors []reactor
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "delete fail",
|
||||
pvcName: "fake-pvc",
|
||||
namespace: "fake-ns",
|
||||
err: "error to delete pvc fake-pvc: persistentvolumeclaims \"fake-pvc\" not found",
|
||||
},
|
||||
{
|
||||
name: "wait fail",
|
||||
pvcName: "fake-pvc",
|
||||
namespace: "fake-ns",
|
||||
clientObj: []runtime.Object{pvcObject},
|
||||
reactors: []reactor{
|
||||
{
|
||||
verb: "get",
|
||||
resource: "persistentvolumeclaims",
|
||||
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("fake-get-error")
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "error to retrieve pvc info for fake-pvc: error to get pvc fake-pvc: fake-get-error",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fakeKubeClient := fake.NewSimpleClientset(test.clientObj...)
|
||||
|
||||
for _, reactor := range test.reactors {
|
||||
fakeKubeClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
|
||||
}
|
||||
|
||||
var kubeClient kubernetes.Interface = fakeKubeClient
|
||||
|
||||
err := EnsureDeletePVC(context.Background(), kubeClient.CoreV1(), test.pvcName, test.namespace, time.Millisecond)
|
||||
if err != nil {
|
||||
assert.EqualError(t, err, test.err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRebindPVC(t *testing.T) {
|
||||
pvcObject := &corev1api.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pvc",
|
||||
Annotations: map[string]string{
|
||||
KubeAnnBindCompleted: "true",
|
||||
KubeAnnBoundByController: "true",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
clientObj []runtime.Object
|
||||
pvc *corev1api.PersistentVolumeClaim
|
||||
pv string
|
||||
reactors []reactor
|
||||
result *corev1api.PersistentVolumeClaim
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "path fail",
|
||||
pvc: pvcObject,
|
||||
pv: "fake-pv",
|
||||
clientObj: []runtime.Object{pvcObject},
|
||||
reactors: []reactor{
|
||||
{
|
||||
verb: "patch",
|
||||
resource: "persistentvolumeclaims",
|
||||
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("fake-patch-error")
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "error patching PVC: fake-patch-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
pvc: pvcObject,
|
||||
pv: "fake-pv",
|
||||
clientObj: []runtime.Object{pvcObject},
|
||||
result: &corev1api.PersistentVolumeClaim{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pvc",
|
||||
},
|
||||
Spec: corev1api.PersistentVolumeClaimSpec{
|
||||
VolumeName: "fake-pv",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fakeKubeClient := fake.NewSimpleClientset(test.clientObj...)
|
||||
|
||||
for _, reactor := range test.reactors {
|
||||
fakeKubeClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
|
||||
}
|
||||
|
||||
var kubeClient kubernetes.Interface = fakeKubeClient
|
||||
|
||||
result, err := RebindPVC(context.Background(), kubeClient.CoreV1(), test.pvc, test.pv)
|
||||
if err != nil {
|
||||
assert.EqualError(t, err, test.err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
assert.Equal(t, test.result, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResetPVBinding(t *testing.T) {
|
||||
pvObject := &corev1api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-pv",
|
||||
Annotations: map[string]string{
|
||||
KubeAnnBoundByController: "true",
|
||||
},
|
||||
},
|
||||
Spec: corev1api.PersistentVolumeSpec{
|
||||
ClaimRef: &corev1api.ObjectReference{
|
||||
Kind: "fake-kind",
|
||||
Namespace: "fake-ns",
|
||||
Name: "fake-pvc",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
clientObj []runtime.Object
|
||||
pv *corev1api.PersistentVolume
|
||||
labels map[string]string
|
||||
reactors []reactor
|
||||
result *corev1api.PersistentVolume
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "path fail",
|
||||
pv: pvObject,
|
||||
clientObj: []runtime.Object{pvObject},
|
||||
reactors: []reactor{
|
||||
{
|
||||
verb: "patch",
|
||||
resource: "persistentvolumes",
|
||||
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("fake-patch-error")
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "error patching PV: fake-patch-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
pv: pvObject,
|
||||
labels: map[string]string{
|
||||
"fake-label-1": "fake-value-1",
|
||||
"fake-label-2": "fake-value-2",
|
||||
},
|
||||
clientObj: []runtime.Object{pvObject},
|
||||
result: &corev1api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-pv",
|
||||
Labels: map[string]string{
|
||||
"fake-label-1": "fake-value-1",
|
||||
"fake-label-2": "fake-value-2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fakeKubeClient := fake.NewSimpleClientset(test.clientObj...)
|
||||
|
||||
for _, reactor := range test.reactors {
|
||||
fakeKubeClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
|
||||
}
|
||||
|
||||
var kubeClient kubernetes.Interface = fakeKubeClient
|
||||
|
||||
result, err := ResetPVBinding(context.Background(), kubeClient.CoreV1(), test.pv, test.labels)
|
||||
if err != nil {
|
||||
assert.EqualError(t, err, test.err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
assert.Equal(t, test.result, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetPVReclaimPolicy(t *testing.T) {
|
||||
pvObject := &corev1api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-pv",
|
||||
},
|
||||
Spec: corev1api.PersistentVolumeSpec{
|
||||
PersistentVolumeReclaimPolicy: corev1api.PersistentVolumeReclaimRetain,
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
clientObj []runtime.Object
|
||||
pv *corev1api.PersistentVolume
|
||||
policy corev1api.PersistentVolumeReclaimPolicy
|
||||
reactors []reactor
|
||||
result *corev1api.PersistentVolume
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "policy not changed",
|
||||
pv: pvObject,
|
||||
policy: corev1api.PersistentVolumeReclaimRetain,
|
||||
},
|
||||
{
|
||||
name: "path fail",
|
||||
pv: pvObject,
|
||||
policy: corev1api.PersistentVolumeReclaimDelete,
|
||||
clientObj: []runtime.Object{pvObject},
|
||||
reactors: []reactor{
|
||||
{
|
||||
verb: "patch",
|
||||
resource: "persistentvolumes",
|
||||
reactorFunc: func(action clientTesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("fake-patch-error")
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "error patching PV: fake-patch-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
pv: pvObject,
|
||||
policy: corev1api.PersistentVolumeReclaimDelete,
|
||||
clientObj: []runtime.Object{pvObject},
|
||||
result: &corev1api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-pv",
|
||||
},
|
||||
Spec: corev1api.PersistentVolumeSpec{
|
||||
PersistentVolumeReclaimPolicy: corev1api.PersistentVolumeReclaimDelete,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fakeKubeClient := fake.NewSimpleClientset(test.clientObj...)
|
||||
|
||||
for _, reactor := range test.reactors {
|
||||
fakeKubeClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
|
||||
}
|
||||
|
||||
var kubeClient kubernetes.Interface = fakeKubeClient
|
||||
|
||||
result, err := SetPVReclaimPolicy(context.Background(), kubeClient.CoreV1(), test.pv, test.policy)
|
||||
if err != nil {
|
||||
assert.EqualError(t, err, test.err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
assert.Equal(t, test.result, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitPVBound(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pvName string
|
||||
pvcName string
|
||||
pvcNamespace string
|
||||
kubeClientObj []runtime.Object
|
||||
kubeReactors []reactor
|
||||
expectedPV *corev1api.PersistentVolume
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "get pv error",
|
||||
pvName: "fake-pv",
|
||||
err: "error to wait for bound of PV: failed to get pv fake-pv: persistentvolumes \"fake-pv\" not found",
|
||||
},
|
||||
{
|
||||
name: "pvc claimRef miss",
|
||||
pvName: "fake-pv",
|
||||
kubeClientObj: []runtime.Object{
|
||||
&corev1api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-pv",
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "error to wait for bound of PV: timed out waiting for the condition",
|
||||
},
|
||||
{
|
||||
name: "pvc claimRef pvc name mismatch",
|
||||
pvName: "fake-pv",
|
||||
pvcName: "fake-pvc",
|
||||
kubeClientObj: []runtime.Object{
|
||||
&corev1api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-pv",
|
||||
},
|
||||
Spec: corev1api.PersistentVolumeSpec{
|
||||
ClaimRef: &corev1api.ObjectReference{
|
||||
Kind: "fake-kind",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "error to wait for bound of PV: timed out waiting for the condition",
|
||||
},
|
||||
{
|
||||
name: "pvc claimRef pvc namespace mismatch",
|
||||
pvName: "fake-pv",
|
||||
pvcName: "fake-pvc",
|
||||
pvcNamespace: "fake-ns",
|
||||
kubeClientObj: []runtime.Object{
|
||||
&corev1api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-pv",
|
||||
},
|
||||
Spec: corev1api.PersistentVolumeSpec{
|
||||
ClaimRef: &corev1api.ObjectReference{
|
||||
Kind: "fake-kind",
|
||||
Name: "fake-pvc",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: "error to wait for bound of PV: timed out waiting for the condition",
|
||||
},
|
||||
{
|
||||
name: "success",
|
||||
pvName: "fake-pv",
|
||||
pvcName: "fake-pvc",
|
||||
pvcNamespace: "fake-ns",
|
||||
kubeClientObj: []runtime.Object{
|
||||
&corev1api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-pv",
|
||||
},
|
||||
Spec: corev1api.PersistentVolumeSpec{
|
||||
ClaimRef: &corev1api.ObjectReference{
|
||||
Kind: "fake-kind",
|
||||
Name: "fake-pvc",
|
||||
Namespace: "fake-ns",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedPV: &corev1api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "fake-pv",
|
||||
},
|
||||
Spec: corev1api.PersistentVolumeSpec{
|
||||
ClaimRef: &corev1api.ObjectReference{
|
||||
Kind: "fake-kind",
|
||||
Name: "fake-pvc",
|
||||
Namespace: "fake-ns",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fakeKubeClient := fake.NewSimpleClientset(test.kubeClientObj...)
|
||||
|
||||
for _, reactor := range test.kubeReactors {
|
||||
fakeKubeClient.Fake.PrependReactor(reactor.verb, reactor.resource, reactor.reactorFunc)
|
||||
}
|
||||
|
||||
var kubeClient kubernetes.Interface = fakeKubeClient
|
||||
|
||||
pv, err := WaitPVBound(context.Background(), kubeClient.CoreV1(), test.pvName, test.pvcName, test.pvcNamespace, time.Millisecond)
|
||||
|
||||
if err != nil {
|
||||
assert.EqualError(t, err, test.err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
assert.Equal(t, test.expectedPV, pv)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
@@ -57,6 +58,12 @@ func TestEnabled(t *testing.T) {
|
||||
zapLevel: zapcore.InfoLevel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "check warn again warn",
|
||||
level: logrus.WarnLevel,
|
||||
zapLevel: zapcore.WarnLevel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "check info again error",
|
||||
level: logrus.ErrorLevel,
|
||||
@@ -69,12 +76,24 @@ func TestEnabled(t *testing.T) {
|
||||
zapLevel: zapcore.ErrorLevel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "check dppanic again panic",
|
||||
level: logrus.PanicLevel,
|
||||
zapLevel: zapcore.DPanicLevel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "check panic again error",
|
||||
level: logrus.ErrorLevel,
|
||||
zapLevel: zapcore.PanicLevel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "check fatal again fatal",
|
||||
level: logrus.FatalLevel,
|
||||
zapLevel: zapcore.FatalLevel,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -89,7 +108,7 @@ func TestEnabled(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrite(t *testing.T) {
|
||||
func TestLogrusFieldsForWrite(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
module string
|
||||
@@ -151,6 +170,65 @@ func TestWrite(t *testing.T) {
|
||||
"logger name": "logger-name-01",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "info with function name",
|
||||
module: "module-05",
|
||||
zapEntry: zapcore.Entry{
|
||||
Level: zapcore.InfoLevel,
|
||||
Caller: zapcore.EntryCaller{
|
||||
Function: "function-name-01",
|
||||
},
|
||||
},
|
||||
zapFields: nil,
|
||||
expected: logrus.Fields{
|
||||
"logModule": "kopia/module-05",
|
||||
"function": "function-name-01",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "info with undefined path",
|
||||
module: "module-06",
|
||||
zapEntry: zapcore.Entry{
|
||||
Level: zapcore.InfoLevel,
|
||||
Caller: zapcore.EntryCaller{
|
||||
Defined: false,
|
||||
},
|
||||
},
|
||||
zapFields: nil,
|
||||
expected: logrus.Fields{
|
||||
"logModule": "kopia/module-06",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "info with defined path",
|
||||
module: "module-06",
|
||||
zapEntry: zapcore.Entry{
|
||||
Level: zapcore.InfoLevel,
|
||||
Caller: zapcore.EntryCaller{
|
||||
Defined: true,
|
||||
File: "file-name-01",
|
||||
Line: 100,
|
||||
},
|
||||
},
|
||||
zapFields: nil,
|
||||
expected: logrus.Fields{
|
||||
"logModule": "kopia/module-06",
|
||||
"path": "file-name-01:100",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "info with stack",
|
||||
module: "module-07",
|
||||
zapEntry: zapcore.Entry{
|
||||
Level: zapcore.InfoLevel,
|
||||
Stack: "fake-stack",
|
||||
},
|
||||
zapFields: nil,
|
||||
expected: logrus.Fields{
|
||||
"logModule": "kopia/module-07",
|
||||
"stack": "fake-stack",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -165,3 +243,107 @@ func TestWrite(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrite(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
ent zapcore.Entry
|
||||
logMessage string
|
||||
logLevel string
|
||||
shouldPanic bool
|
||||
}{
|
||||
{
|
||||
name: "write debug",
|
||||
ent: zapcore.Entry{
|
||||
Level: zapcore.DebugLevel,
|
||||
Message: "fake-message",
|
||||
},
|
||||
logMessage: "fake-message",
|
||||
logLevel: "level=debug",
|
||||
},
|
||||
{
|
||||
name: "write info",
|
||||
ent: zapcore.Entry{
|
||||
Level: zapcore.InfoLevel,
|
||||
Message: "fake-message",
|
||||
},
|
||||
logMessage: "fake-message",
|
||||
logLevel: "level=info",
|
||||
},
|
||||
{
|
||||
name: "write warn",
|
||||
ent: zapcore.Entry{
|
||||
Level: zapcore.WarnLevel,
|
||||
Message: "fake-message",
|
||||
},
|
||||
logMessage: "fake-message",
|
||||
logLevel: "level=warn",
|
||||
},
|
||||
{
|
||||
name: "write error",
|
||||
ent: zapcore.Entry{
|
||||
Level: zapcore.ErrorLevel,
|
||||
Message: "fake-message",
|
||||
},
|
||||
logMessage: "fake-message",
|
||||
logLevel: "level=warn",
|
||||
},
|
||||
{
|
||||
name: "write DPanic",
|
||||
ent: zapcore.Entry{
|
||||
Level: zapcore.DPanicLevel,
|
||||
Message: "fake-message",
|
||||
},
|
||||
logMessage: "fake-message",
|
||||
logLevel: "level=panic",
|
||||
shouldPanic: true,
|
||||
},
|
||||
{
|
||||
name: "write panic",
|
||||
ent: zapcore.Entry{
|
||||
Level: zapcore.PanicLevel,
|
||||
Message: "fake-message",
|
||||
},
|
||||
logMessage: "fake-message",
|
||||
logLevel: "level=panic",
|
||||
shouldPanic: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
logMessage := ""
|
||||
|
||||
log := kopiaLog{
|
||||
logger: test.NewSingleLogger(&logMessage),
|
||||
}
|
||||
|
||||
if tc.shouldPanic {
|
||||
defer func() {
|
||||
r := recover()
|
||||
assert.NotNil(t, r)
|
||||
|
||||
if len(tc.logMessage) > 0 {
|
||||
assert.Contains(t, logMessage, tc.logMessage)
|
||||
}
|
||||
|
||||
if len(tc.logLevel) > 0 {
|
||||
assert.Contains(t, logMessage, tc.logLevel)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
err := log.Write(tc.ent, nil)
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
if len(tc.logMessage) > 0 {
|
||||
assert.Contains(t, logMessage, tc.logMessage)
|
||||
}
|
||||
|
||||
if len(tc.logLevel) > 0 {
|
||||
assert.Contains(t, logMessage, tc.logLevel)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user