Merge pull request #6424 from reasonerjt/ut-cmd-output
Add more unit test cases for cmd/util/outputpull/6432/head
commit
ef1908f8ff
|
@ -0,0 +1,59 @@
|
|||
package builder
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
)
|
||||
|
||||
// DeleteBackupRequestBuilder builds DeleteBackupRequest objects
|
||||
type DeleteBackupRequestBuilder struct {
|
||||
object *velerov1api.DeleteBackupRequest
|
||||
}
|
||||
|
||||
// ForDeleteBackupRequest is the constructor for a DeleteBackupRequestBuilder.
|
||||
func ForDeleteBackupRequest(ns, name string) *DeleteBackupRequestBuilder {
|
||||
return &DeleteBackupRequestBuilder{
|
||||
object: &velerov1api.DeleteBackupRequest{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: velerov1api.SchemeGroupVersion.String(),
|
||||
Kind: "DeleteBackupRequest",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: ns,
|
||||
Name: name,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Result returns the built DeleteBackupRequest.
|
||||
func (b *DeleteBackupRequestBuilder) Result() *velerov1api.DeleteBackupRequest {
|
||||
return b.object
|
||||
}
|
||||
|
||||
// ObjectMeta applies functional options to the DeleteBackupRequest's ObjectMeta.
|
||||
func (b *DeleteBackupRequestBuilder) ObjectMeta(opts ...ObjectMetaOpt) *DeleteBackupRequestBuilder {
|
||||
for _, opt := range opts {
|
||||
opt(b.object)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// BackupName sets the DeleteBackupRequest's backup name.
|
||||
func (b *DeleteBackupRequestBuilder) BackupName(name string) *DeleteBackupRequestBuilder {
|
||||
b.object.Spec.BackupName = name
|
||||
return b
|
||||
}
|
||||
|
||||
// Phase sets the DeleteBackupRequest's phase.
|
||||
func (b *DeleteBackupRequestBuilder) Phase(phase velerov1api.DeleteBackupRequestPhase) *DeleteBackupRequestBuilder {
|
||||
b.object.Status.Phase = phase
|
||||
return b
|
||||
}
|
||||
|
||||
// Errors sets the DeleteBackupRequest's errors.
|
||||
func (b *DeleteBackupRequestBuilder) Errors(errors ...string) *DeleteBackupRequestBuilder {
|
||||
b.object.Status.Errors = errors
|
||||
return b
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
package builder
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/itemoperation"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
)
|
||||
|
||||
// OperationStatusBuilder builds OperationStatus objects
|
||||
type OperationStatusBuilder struct {
|
||||
object *itemoperation.OperationStatus
|
||||
}
|
||||
|
||||
// ForOperationStatus is the constructor for a OperationStatusBuilder.
|
||||
func ForOperationStatus() *OperationStatusBuilder {
|
||||
return &OperationStatusBuilder{
|
||||
object: &itemoperation.OperationStatus{},
|
||||
}
|
||||
}
|
||||
|
||||
// Result returns the built OperationStatus.
|
||||
func (osb *OperationStatusBuilder) Result() *itemoperation.OperationStatus {
|
||||
return osb.object
|
||||
}
|
||||
|
||||
// Phase sets the OperationStatus's phase.
|
||||
func (osb *OperationStatusBuilder) Phase(phase itemoperation.OperationPhase) *OperationStatusBuilder {
|
||||
osb.object.Phase = phase
|
||||
return osb
|
||||
}
|
||||
|
||||
// Error sets the OperationStatus's error.
|
||||
func (osb *OperationStatusBuilder) Error(err string) *OperationStatusBuilder {
|
||||
osb.object.Error = err
|
||||
return osb
|
||||
}
|
||||
|
||||
// Progress sets the OperationStatus's progress.
|
||||
func (osb *OperationStatusBuilder) Progress(nComplete int64, nTotal int64, operationUnits string) *OperationStatusBuilder {
|
||||
osb.object.NCompleted = nComplete
|
||||
osb.object.NTotal = nTotal
|
||||
osb.object.OperationUnits = operationUnits
|
||||
return osb
|
||||
}
|
||||
|
||||
// Description sets the OperationStatus's description.
|
||||
func (osb *OperationStatusBuilder) Description(desc string) *OperationStatusBuilder {
|
||||
osb.object.Description = desc
|
||||
return osb
|
||||
}
|
||||
|
||||
// Created sets the OperationStatus's creation timestamp.
|
||||
func (osb *OperationStatusBuilder) Created(t time.Time) *OperationStatusBuilder {
|
||||
osb.object.Created = &metav1.Time{Time: t}
|
||||
return osb
|
||||
}
|
||||
|
||||
// Updated sets the OperationStatus's last update timestamp.
|
||||
func (osb *OperationStatusBuilder) Updated(t time.Time) *OperationStatusBuilder {
|
||||
osb.object.Updated = &metav1.Time{Time: t}
|
||||
return osb
|
||||
}
|
||||
|
||||
// Started sets the OperationStatus's start timestamp.
|
||||
func (osb *OperationStatusBuilder) Started(t time.Time) *OperationStatusBuilder {
|
||||
osb.object.Started = &metav1.Time{Time: t}
|
||||
return osb
|
||||
}
|
||||
|
||||
// BackupOperationBuilder builds BackupOperation objects
|
||||
type BackupOperationBuilder struct {
|
||||
object *itemoperation.BackupOperation
|
||||
}
|
||||
|
||||
// ForBackupOperation is the constructor for a BackupOperationBuilder.
|
||||
func ForBackupOperation() *BackupOperationBuilder {
|
||||
return &BackupOperationBuilder{
|
||||
object: &itemoperation.BackupOperation{},
|
||||
}
|
||||
}
|
||||
|
||||
// Result returns the built BackupOperation.
|
||||
func (bb *BackupOperationBuilder) Result() *itemoperation.BackupOperation {
|
||||
return bb.object
|
||||
}
|
||||
|
||||
// BackupName sets the BackupOperation's backup name.
|
||||
func (bb *BackupOperationBuilder) BackupName(name string) *BackupOperationBuilder {
|
||||
bb.object.Spec.BackupName = name
|
||||
return bb
|
||||
}
|
||||
|
||||
// OperationID sets the BackupOperation's operation ID.
|
||||
func (bb *BackupOperationBuilder) OperationID(id string) *BackupOperationBuilder {
|
||||
bb.object.Spec.OperationID = id
|
||||
return bb
|
||||
}
|
||||
|
||||
// Status sets the BackupOperation's status.
|
||||
func (bb *BackupOperationBuilder) Status(status itemoperation.OperationStatus) *BackupOperationBuilder {
|
||||
bb.object.Status = status
|
||||
return bb
|
||||
}
|
||||
|
||||
// ResourceIdentifier sets the BackupOperation's resource identifier.
|
||||
func (bb *BackupOperationBuilder) ResourceIdentifier(group, resource, ns, name string) *BackupOperationBuilder {
|
||||
bb.object.Spec.ResourceIdentifier = velero.ResourceIdentifier{
|
||||
GroupResource: schema.GroupResource{
|
||||
Group: group,
|
||||
Resource: resource,
|
||||
},
|
||||
Namespace: ns,
|
||||
Name: name,
|
||||
}
|
||||
return bb
|
||||
}
|
||||
|
||||
// BackupItemAction sets the BackupOperation's backup item action.
|
||||
func (bb *BackupOperationBuilder) BackupItemAction(bia string) *BackupOperationBuilder {
|
||||
bb.object.Spec.BackupItemAction = bia
|
||||
return bb
|
||||
}
|
||||
|
||||
// PostOperationItem adds a post-operation item to the BackupOperation's list of post-operation items.
|
||||
func (bb *BackupOperationBuilder) PostOperationItem(group, resource, ns, name string) *BackupOperationBuilder {
|
||||
bb.object.Spec.PostOperationItems = append(bb.object.Spec.PostOperationItems, velero.ResourceIdentifier{
|
||||
GroupResource: schema.GroupResource{
|
||||
Group: group,
|
||||
Resource: resource,
|
||||
},
|
||||
Namespace: ns,
|
||||
Name: name,
|
||||
})
|
||||
return bb
|
||||
}
|
||||
|
||||
// RestoreOperationBuilder builds RestoreOperation objects
|
||||
type RestoreOperationBuilder struct {
|
||||
object *itemoperation.RestoreOperation
|
||||
}
|
||||
|
||||
// ForRestoreOperation is the constructor for a RestoreOperationBuilder.
|
||||
func ForRestoreOperation() *RestoreOperationBuilder {
|
||||
return &RestoreOperationBuilder{
|
||||
object: &itemoperation.RestoreOperation{},
|
||||
}
|
||||
}
|
||||
|
||||
// Result returns the built RestoreOperation.
|
||||
func (rb *RestoreOperationBuilder) Result() *itemoperation.RestoreOperation {
|
||||
return rb.object
|
||||
}
|
||||
|
||||
// RestoreName sets the RestoreOperation's restore name.
|
||||
func (rb *RestoreOperationBuilder) RestoreName(name string) *RestoreOperationBuilder {
|
||||
rb.object.Spec.RestoreName = name
|
||||
return rb
|
||||
}
|
||||
|
||||
// OperationID sets the RestoreOperation's operation ID.
|
||||
func (rb *RestoreOperationBuilder) OperationID(id string) *RestoreOperationBuilder {
|
||||
rb.object.Spec.OperationID = id
|
||||
return rb
|
||||
}
|
||||
|
||||
// RestoreItemAction sets the RestoreOperation's restore item action.
|
||||
func (rb *RestoreOperationBuilder) RestoreItemAction(ria string) *RestoreOperationBuilder {
|
||||
rb.object.Spec.RestoreItemAction = ria
|
||||
return rb
|
||||
}
|
||||
|
||||
// Status sets the RestoreOperation's status.
|
||||
func (rb *RestoreOperationBuilder) Status(status itemoperation.OperationStatus) *RestoreOperationBuilder {
|
||||
rb.object.Status = status
|
||||
return rb
|
||||
}
|
||||
|
||||
// ResourceIdentifier sets the RestoreOperation's resource identifier.
|
||||
func (rb *RestoreOperationBuilder) ResourceIdentifier(group, resource, ns, name string) *RestoreOperationBuilder {
|
||||
rb.object.Spec.ResourceIdentifier = velero.ResourceIdentifier{
|
||||
GroupResource: schema.GroupResource{
|
||||
Group: group,
|
||||
Resource: resource,
|
||||
},
|
||||
Namespace: ns,
|
||||
Name: name,
|
||||
}
|
||||
return rb
|
||||
}
|
|
@ -153,3 +153,10 @@ func WithManagedFields(val []metav1.ManagedFieldsEntry) func(obj metav1.Object)
|
|||
obj.SetManagedFields(val)
|
||||
}
|
||||
}
|
||||
|
||||
// WithCreationTimestamp is a functional option that applies the specified creationTimestamp
|
||||
func WithCreationTimestamp(t time.Time) func(obj metav1.Object) {
|
||||
return func(obj metav1.Object) {
|
||||
obj.SetCreationTimestamp(metav1.Time{Time: t})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ func (b *PodVolumeBackupBuilder) ObjectMeta(opts ...ObjectMetaOpt) *PodVolumeBac
|
|||
for _, opt := range opts {
|
||||
opt(b.object)
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package builder
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
)
|
||||
|
||||
// PodVolumeRestoreBuilder builds PodVolumeRestore objects.
|
||||
type PodVolumeRestoreBuilder struct {
|
||||
object *velerov1api.PodVolumeRestore
|
||||
}
|
||||
|
||||
// ForPodVolumeRestore is the constructor for a PodVolumeRestoreBuilder.
|
||||
func ForPodVolumeRestore(ns, name string) *PodVolumeRestoreBuilder {
|
||||
return &PodVolumeRestoreBuilder{
|
||||
object: &velerov1api.PodVolumeRestore{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: velerov1api.SchemeGroupVersion.String(),
|
||||
Kind: "PodVolumeRestore",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: ns,
|
||||
Name: name,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Result returns the built PodVolumeRestore.
|
||||
func (b *PodVolumeRestoreBuilder) Result() *velerov1api.PodVolumeRestore {
|
||||
return b.object
|
||||
}
|
||||
|
||||
// ObjectMeta applies functional options to the PodVolumeRestore's ObjectMeta.
|
||||
func (b *PodVolumeRestoreBuilder) ObjectMeta(opts ...ObjectMetaOpt) *PodVolumeRestoreBuilder {
|
||||
for _, opt := range opts {
|
||||
opt(b.object)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Phase sets the PodVolumeRestore's phase.
|
||||
func (b *PodVolumeRestoreBuilder) Phase(phase velerov1api.PodVolumeRestorePhase) *PodVolumeRestoreBuilder {
|
||||
b.object.Status.Phase = phase
|
||||
return b
|
||||
}
|
||||
|
||||
// BackupStorageLocation sets the PodVolumeRestore's backup storage location.
|
||||
func (b *PodVolumeRestoreBuilder) BackupStorageLocation(name string) *PodVolumeRestoreBuilder {
|
||||
b.object.Spec.BackupStorageLocation = name
|
||||
return b
|
||||
}
|
||||
|
||||
// SnapshotID sets the PodVolumeRestore's snapshot ID.
|
||||
func (b *PodVolumeRestoreBuilder) SnapshotID(snapshotID string) *PodVolumeRestoreBuilder {
|
||||
b.object.Spec.SnapshotID = snapshotID
|
||||
return b
|
||||
}
|
||||
|
||||
// PodName sets the name of the pod associated with this PodVolumeRestore.
|
||||
func (b *PodVolumeRestoreBuilder) PodName(name string) *PodVolumeRestoreBuilder {
|
||||
b.object.Spec.Pod.Name = name
|
||||
return b
|
||||
}
|
||||
|
||||
// PodNamespace sets the name of the pod associated with this PodVolumeRestore.
|
||||
func (b *PodVolumeRestoreBuilder) PodNamespace(ns string) *PodVolumeRestoreBuilder {
|
||||
b.object.Spec.Pod.Namespace = ns
|
||||
return b
|
||||
}
|
||||
|
||||
// Volume sets the name of the volume associated with this PodVolumeRestore.
|
||||
func (b *PodVolumeRestoreBuilder) Volume(volume string) *PodVolumeRestoreBuilder {
|
||||
b.object.Spec.Volume = volume
|
||||
return b
|
||||
}
|
||||
|
||||
// UploaderType sets the type of uploader to use for this PodVolumeRestore.
|
||||
func (b *PodVolumeRestoreBuilder) UploaderType(uploaderType string) *PodVolumeRestoreBuilder {
|
||||
b.object.Spec.UploaderType = uploaderType
|
||||
return b
|
||||
}
|
|
@ -6,6 +6,10 @@ import (
|
|||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/itemoperation"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
@ -46,7 +50,31 @@ func TestDescribeBackupSpec(t *testing.T) {
|
|||
TTL(72 * time.Hour).
|
||||
CSISnapshotTimeout(10 * time.Minute).
|
||||
DataMover("mover").
|
||||
Result().Spec
|
||||
Hooks(velerov1api.BackupHooks{
|
||||
Resources: []velerov1api.BackupResourceHookSpec{
|
||||
{
|
||||
Name: "hook-1",
|
||||
PreHooks: []velerov1api.BackupResourceHook{
|
||||
{
|
||||
Exec: &velerov1api.ExecHook{
|
||||
Container: "hook-container-1",
|
||||
Command: []string{"pre"},
|
||||
OnError: velerov1api.HookErrorModeContinue,
|
||||
},
|
||||
},
|
||||
},
|
||||
PostHooks: []velerov1api.BackupResourceHook{
|
||||
{
|
||||
Exec: &velerov1api.ExecHook{
|
||||
Container: "hook-container-1",
|
||||
Command: []string{"post"},
|
||||
OnError: velerov1api.HookErrorModeContinue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}).Result().Spec
|
||||
|
||||
expect1 := `Namespaces:
|
||||
Included: inc-ns-1, inc-ns-2
|
||||
|
@ -70,7 +98,30 @@ TTL: 72h0m0s
|
|||
CSISnapshotTimeout: 10m0s
|
||||
ItemOperationTimeout: 0s
|
||||
|
||||
Hooks: <none>
|
||||
Hooks:
|
||||
Resources:
|
||||
hook-1:
|
||||
Namespaces:
|
||||
Included: inc-ns-1, inc-ns-2
|
||||
Excluded: exc-ns-1, exc-ns-2
|
||||
|
||||
Resources:
|
||||
Included: inc-res-1, inc-res-2
|
||||
Excluded: exc-res-1, exc-res-2
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
Pre Exec Hook:
|
||||
Container: hook-container-1
|
||||
Command: pre
|
||||
On Error: Continue
|
||||
Timeout: 0s
|
||||
|
||||
Post Exec Hook:
|
||||
Container: hook-container-1
|
||||
Command: post
|
||||
On Error: Continue
|
||||
Timeout: 0s
|
||||
`
|
||||
|
||||
input2 := builder.ForBackup("test-ns", "test-backup-2").
|
||||
|
@ -112,13 +163,94 @@ ItemOperationTimeout: 0s
|
|||
Hooks: <none>
|
||||
`
|
||||
|
||||
input3 := builder.ForBackup("test-ns", "test-backup-3").
|
||||
StorageLocation("backup-location").
|
||||
OrderedResources(map[string]string{
|
||||
"kind1": "rs1-1, rs1-2",
|
||||
}).Hooks(velerov1api.BackupHooks{
|
||||
Resources: []velerov1api.BackupResourceHookSpec{
|
||||
{
|
||||
Name: "hook-1",
|
||||
PreHooks: []velerov1api.BackupResourceHook{
|
||||
{
|
||||
Exec: &velerov1api.ExecHook{
|
||||
Container: "hook-container-1",
|
||||
Command: []string{"pre"},
|
||||
OnError: velerov1api.HookErrorModeContinue,
|
||||
},
|
||||
},
|
||||
},
|
||||
PostHooks: []velerov1api.BackupResourceHook{
|
||||
{
|
||||
Exec: &velerov1api.ExecHook{
|
||||
Container: "hook-container-1",
|
||||
Command: []string{"post"},
|
||||
OnError: velerov1api.HookErrorModeContinue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}).Result().Spec
|
||||
|
||||
expect3 := `Namespaces:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
Storage Location: backup-location
|
||||
|
||||
Velero-Native Snapshot PVs: auto
|
||||
Snapshot Move Data: auto
|
||||
Data Mover: <none>
|
||||
|
||||
TTL: 0s
|
||||
|
||||
CSISnapshotTimeout: 0s
|
||||
ItemOperationTimeout: 0s
|
||||
|
||||
Hooks:
|
||||
Resources:
|
||||
hook-1:
|
||||
Namespaces:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
Pre Exec Hook:
|
||||
Container: hook-container-1
|
||||
Command: pre
|
||||
On Error: Continue
|
||||
Timeout: 0s
|
||||
|
||||
Post Exec Hook:
|
||||
Container: hook-container-1
|
||||
Command: post
|
||||
On Error: Continue
|
||||
Timeout: 0s
|
||||
|
||||
OrderedResources:
|
||||
kind1: rs1-1, rs1-2
|
||||
`
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
input velerov1api.BackupSpec
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
name: "old resource filter",
|
||||
name: "old resource filter with hooks",
|
||||
input: input1,
|
||||
expect: expect1,
|
||||
},
|
||||
|
@ -127,6 +259,11 @@ Hooks: <none>
|
|||
input: input2,
|
||||
expect: expect2,
|
||||
},
|
||||
{
|
||||
name: "old resource filter with hooks and ordered resources",
|
||||
input: input3,
|
||||
expect: expect3,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
|
@ -164,7 +301,6 @@ func TestDescribeSnapshot(t *testing.T) {
|
|||
|
||||
func TestDescribePodVolumeBackups(t *testing.T) {
|
||||
pvb1 := builder.ForPodVolumeBackup("test-ns", "test-pvb1").
|
||||
BackupStorageLocation("backup-location").
|
||||
UploaderType("kopia").
|
||||
Phase(velerov1api.PodVolumeBackupPhaseCompleted).
|
||||
BackupStorageLocation("bsl-1").
|
||||
|
@ -173,7 +309,6 @@ func TestDescribePodVolumeBackups(t *testing.T) {
|
|||
PodNamespace("pod-ns-1").
|
||||
SnapshotID("snap-1").Result()
|
||||
pvb2 := builder.ForPodVolumeBackup("test-ns1", "test-pvb2").
|
||||
BackupStorageLocation("backup-location").
|
||||
UploaderType("kopia").
|
||||
Phase(velerov1api.PodVolumeBackupPhaseCompleted).
|
||||
BackupStorageLocation("bsl-1").
|
||||
|
@ -289,3 +424,99 @@ Snapshot Content Name: vsc-1
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDescribeDeleteBackupRequests(t *testing.T) {
|
||||
t1, err1 := time.Parse("2006-Jan-02", "2023-Jun-26")
|
||||
require.Nil(t, err1)
|
||||
dbr1 := builder.ForDeleteBackupRequest("velero", "dbr1").
|
||||
ObjectMeta(builder.WithCreationTimestamp(t1)).
|
||||
BackupName("bak-1").
|
||||
Phase(velerov1api.DeleteBackupRequestPhaseProcessed).
|
||||
Errors("some error").Result()
|
||||
t2, err2 := time.Parse("2006-Jan-02", "2023-Jun-25")
|
||||
require.Nil(t, err2)
|
||||
dbr2 := builder.ForDeleteBackupRequest("velero", "dbr2").
|
||||
ObjectMeta(builder.WithCreationTimestamp(t2)).
|
||||
BackupName("bak-2").
|
||||
Phase(velerov1api.DeleteBackupRequestPhaseInProgress).Result()
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
input []velerov1api.DeleteBackupRequest
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
name: "empty list",
|
||||
input: []velerov1api.DeleteBackupRequest{},
|
||||
expect: `Deletion Attempts:
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "list with one failed and one in-progress request",
|
||||
input: []velerov1api.DeleteBackupRequest{*dbr1, *dbr2},
|
||||
expect: `Deletion Attempts (1 failed):
|
||||
2023-06-26 00:00:00 +0000 UTC: Processed
|
||||
Errors:
|
||||
some error
|
||||
|
||||
2023-06-25 00:00:00 +0000 UTC: InProgress
|
||||
`,
|
||||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(tt *testing.T) {
|
||||
d := &Describer{
|
||||
Prefix: "",
|
||||
out: &tabwriter.Writer{},
|
||||
buf: &bytes.Buffer{},
|
||||
}
|
||||
d.out.Init(d.buf, 0, 8, 2, ' ', 0)
|
||||
DescribeDeleteBackupRequests(d, tc.input)
|
||||
d.out.Flush()
|
||||
assert.Equal(tt, tc.expect, d.buf.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDescribeBackupItemOperation(t *testing.T) {
|
||||
t1, err1 := time.Parse("2006-Jan-02", "2023-Jun-26")
|
||||
require.Nil(t, err1)
|
||||
t2, err2 := time.Parse("2006-Jan-02", "2023-Jun-25")
|
||||
require.Nil(t, err2)
|
||||
t3, err3 := time.Parse("2006-Jan-02", "2023-Jun-24")
|
||||
require.Nil(t, err3)
|
||||
input := builder.ForBackupOperation().
|
||||
BackupName("backup-1").
|
||||
OperationID("op-1").
|
||||
BackupItemAction("action-1").
|
||||
ResourceIdentifier("group", "rs-type", "ns", "rs-name").
|
||||
Status(*builder.ForOperationStatus().
|
||||
Phase(itemoperation.OperationPhaseFailed).
|
||||
Error("operation error").
|
||||
Progress(50, 100, "bytes").
|
||||
Description("operation description").
|
||||
Created(t3).
|
||||
Started(t2).
|
||||
Updated(t1).
|
||||
Result()).Result()
|
||||
expected := ` Operation for rs-type.group ns/rs-name:
|
||||
Backup Item Action Plugin: action-1
|
||||
Operation ID: op-1
|
||||
Phase: Failed
|
||||
Operation Error: operation error
|
||||
Progress: 50 of 100 complete (bytes)
|
||||
Progress description: operation description
|
||||
Created: 2023-06-24 00:00:00 +0000 UTC
|
||||
Started: 2023-06-25 00:00:00 +0000 UTC
|
||||
Updated: 2023-06-26 00:00:00 +0000 UTC
|
||||
`
|
||||
d := &Describer{
|
||||
Prefix: "",
|
||||
out: &tabwriter.Writer{},
|
||||
buf: &bytes.Buffer{},
|
||||
}
|
||||
d.out.Init(d.buf, 0, 8, 2, ' ', 0)
|
||||
describeBackupItemOperation(d, input)
|
||||
d.out.Flush()
|
||||
assert.Equal(t, expected, d.buf.String())
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/features"
|
||||
|
@ -31,7 +33,32 @@ func TestDescribeBackupInSF(t *testing.T) {
|
|||
StorageLocation("backup-location").
|
||||
TTL(72 * time.Hour).
|
||||
CSISnapshotTimeout(10 * time.Minute).
|
||||
DataMover("mover")
|
||||
DataMover("mover").
|
||||
Hooks(velerov1api.BackupHooks{
|
||||
Resources: []velerov1api.BackupResourceHookSpec{
|
||||
{
|
||||
Name: "hook-1",
|
||||
PreHooks: []velerov1api.BackupResourceHook{
|
||||
{
|
||||
Exec: &velerov1api.ExecHook{
|
||||
Container: "hook-container-1",
|
||||
Command: []string{"pre"},
|
||||
OnError: velerov1api.HookErrorModeContinue,
|
||||
},
|
||||
},
|
||||
},
|
||||
PostHooks: []velerov1api.BackupResourceHook{
|
||||
{
|
||||
Exec: &velerov1api.ExecHook{
|
||||
Container: "hook-container-1",
|
||||
Command: []string{"post"},
|
||||
OnError: velerov1api.HookErrorModeContinue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect1 := map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
|
@ -51,13 +78,73 @@ func TestDescribeBackupInSF(t *testing.T) {
|
|||
"TTL": "72h0m0s",
|
||||
"CSISnapshotTimeout": "10m0s",
|
||||
"veleroSnapshotMoveData": "auto",
|
||||
"hooks": map[string]interface{}{
|
||||
"resources": map[string]interface{}{
|
||||
"hook-1": map[string]interface{}{
|
||||
"labelSelector": emptyDisplay,
|
||||
"namespaces": map[string]string{
|
||||
"included": "inc-ns-1, inc-ns-2",
|
||||
"excluded": "exc-ns-1, exc-ns-2",
|
||||
},
|
||||
"preExecHook": []map[string]interface{}{
|
||||
{
|
||||
"container": "hook-container-1",
|
||||
"command": "pre",
|
||||
"onError:": velerov1api.HookErrorModeContinue,
|
||||
"timeout": "0s",
|
||||
},
|
||||
},
|
||||
"postExecHook": []map[string]interface{}{
|
||||
{
|
||||
"container": "hook-container-1",
|
||||
"command": "post",
|
||||
"onError:": velerov1api.HookErrorModeContinue,
|
||||
"timeout": "0s",
|
||||
},
|
||||
},
|
||||
"resources": map[string]string{
|
||||
"included": "inc-res-1, inc-res-2",
|
||||
"excluded": "exc-res-1, exc-res-2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
DescribeBackupSpecInSF(sd, backupBuilder1.Result().Spec)
|
||||
assert.True(t, reflect.DeepEqual(sd.output, expect1))
|
||||
|
||||
backupBuilder2 := builder.ForBackup("test-ns-2", "test-backup-2")
|
||||
backupBuilder2.StorageLocation("backup-location")
|
||||
backupBuilder2 := builder.ForBackup("test-ns-2", "test-backup-2").
|
||||
StorageLocation("backup-location").
|
||||
OrderedResources(map[string]string{
|
||||
"kind1": "rs1-1, rs1-2",
|
||||
"kind2": "rs2-1, rs2-2",
|
||||
}).Hooks(velerov1api.BackupHooks{
|
||||
Resources: []velerov1api.BackupResourceHookSpec{
|
||||
{
|
||||
Name: "hook-1",
|
||||
PreHooks: []velerov1api.BackupResourceHook{
|
||||
{
|
||||
Exec: &velerov1api.ExecHook{
|
||||
Container: "hook-container-1",
|
||||
Command: []string{"pre"},
|
||||
OnError: velerov1api.HookErrorModeContinue,
|
||||
},
|
||||
},
|
||||
},
|
||||
PostHooks: []velerov1api.BackupResourceHook{
|
||||
{
|
||||
Exec: &velerov1api.ExecHook{
|
||||
Container: "hook-container-1",
|
||||
Command: []string{"post"},
|
||||
OnError: velerov1api.HookErrorModeContinue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect2 := map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"namespaces": map[string]interface{}{
|
||||
|
@ -76,6 +163,41 @@ func TestDescribeBackupInSF(t *testing.T) {
|
|||
"TTL": "0s",
|
||||
"CSISnapshotTimeout": "0s",
|
||||
"veleroSnapshotMoveData": "auto",
|
||||
"hooks": map[string]interface{}{
|
||||
"resources": map[string]interface{}{
|
||||
"hook-1": map[string]interface{}{
|
||||
"labelSelector": emptyDisplay,
|
||||
"namespaces": map[string]string{
|
||||
"included": "*",
|
||||
"excluded": emptyDisplay,
|
||||
},
|
||||
"preExecHook": []map[string]interface{}{
|
||||
{
|
||||
"container": "hook-container-1",
|
||||
"command": "pre",
|
||||
"onError:": velerov1api.HookErrorModeContinue,
|
||||
"timeout": "0s",
|
||||
},
|
||||
},
|
||||
"postExecHook": []map[string]interface{}{
|
||||
{
|
||||
"container": "hook-container-1",
|
||||
"command": "post",
|
||||
"onError:": velerov1api.HookErrorModeContinue,
|
||||
"timeout": "0s",
|
||||
},
|
||||
},
|
||||
"resources": map[string]string{
|
||||
"included": "*",
|
||||
"excluded": emptyDisplay,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"orderedResources": map[string]string{
|
||||
"kind1": "rs1-1, rs1-2",
|
||||
"kind2": "rs2-1, rs2-2",
|
||||
},
|
||||
},
|
||||
}
|
||||
DescribeBackupSpecInSF(sd, backupBuilder2.Result().Spec)
|
||||
|
@ -250,3 +372,83 @@ func TestDescribeBackupResultInSF(t *testing.T) {
|
|||
describeResultInSF(got, input)
|
||||
assert.True(t, reflect.DeepEqual(got, expect))
|
||||
}
|
||||
|
||||
func TestDescribeDeleteBackupRequestsInSF(t *testing.T) {
|
||||
t1, err1 := time.Parse("2006-Jan-02", "2023-Jun-26")
|
||||
require.Nil(t, err1)
|
||||
dbr1 := builder.ForDeleteBackupRequest("velero", "dbr1").
|
||||
ObjectMeta(builder.WithCreationTimestamp(t1)).
|
||||
BackupName("bak-1").
|
||||
Phase(velerov1api.DeleteBackupRequestPhaseProcessed).
|
||||
Errors("some error").Result()
|
||||
t2, err2 := time.Parse("2006-Jan-02", "2023-Jun-25")
|
||||
require.Nil(t, err2)
|
||||
dbr2 := builder.ForDeleteBackupRequest("velero", "dbr2").
|
||||
ObjectMeta(builder.WithCreationTimestamp(t2)).
|
||||
BackupName("bak-2").
|
||||
Phase(velerov1api.DeleteBackupRequestPhaseInProgress).Result()
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
input []velerov1api.DeleteBackupRequest
|
||||
expect map[string]interface{}
|
||||
}{
|
||||
{
|
||||
name: "empty list",
|
||||
input: []velerov1api.DeleteBackupRequest{},
|
||||
expect: map[string]interface{}{
|
||||
"deletionAttempts": map[string]interface{}{
|
||||
"deleteBackupRequests": []map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list with one failed and one in-progress request",
|
||||
input: []velerov1api.DeleteBackupRequest{*dbr1, *dbr2},
|
||||
expect: map[string]interface{}{
|
||||
"deletionAttempts": map[string]interface{}{
|
||||
"failed": int(1),
|
||||
"deleteBackupRequests": []map[string]interface{}{
|
||||
{
|
||||
"creationTimestamp": t1.String(),
|
||||
"phase": velerov1api.DeleteBackupRequestPhaseProcessed,
|
||||
"errors": []string{
|
||||
"some error",
|
||||
},
|
||||
},
|
||||
{
|
||||
"creationTimestamp": t2.String(),
|
||||
"phase": velerov1api.DeleteBackupRequestPhaseInProgress,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(tt *testing.T) {
|
||||
sd := &StructuredDescriber{
|
||||
output: make(map[string]interface{}),
|
||||
format: "",
|
||||
}
|
||||
DescribeDeleteBackupRequestsInSF(sd, tc.input)
|
||||
assert.True(tt, reflect.DeepEqual(sd.output, tc.expect))
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDescribeSnapshotInSF(t *testing.T) {
|
||||
res := map[string]interface{}{}
|
||||
iops := int64(100)
|
||||
describeSnapshotInSF("pv-1", "snapshot-1", "ebs", "us-east-2", &iops, res)
|
||||
expect := map[string]interface{}{
|
||||
"pv-1": map[string]string{
|
||||
"snapshotID": "snapshot-1",
|
||||
"type": "ebs",
|
||||
"availabilityZone": "us-east-2",
|
||||
"IOPS": "100",
|
||||
},
|
||||
}
|
||||
assert.True(t, reflect.DeepEqual(expect, res))
|
||||
}
|
||||
|
|
|
@ -47,15 +47,6 @@ func Describe(fn func(d *Describer)) string {
|
|||
return d.buf.String()
|
||||
}
|
||||
|
||||
func NewDescriber(minwidth, tabwidth, padding int, padchar byte, flags uint) *Describer {
|
||||
d := &Describer{
|
||||
out: new(tabwriter.Writer),
|
||||
buf: new(bytes.Buffer),
|
||||
}
|
||||
d.out.Init(d.buf, minwidth, tabwidth, padding, padchar, flags)
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *Describer) Printf(msg string, args ...interface{}) {
|
||||
fmt.Fprint(d.out, d.Prefix)
|
||||
fmt.Fprintf(d.out, msg, args...)
|
||||
|
|
|
@ -3,6 +3,7 @@ package output
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"text/tabwriter"
|
||||
|
||||
|
@ -132,3 +133,36 @@ func TestStructuredDescriber_JSONEncode(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStructuredDescriber_DescribeMetadata(t *testing.T) {
|
||||
d := NewStructuredDescriber("")
|
||||
input := metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "test-ns",
|
||||
Labels: map[string]string{
|
||||
"label-1": "v1",
|
||||
"label-2": "v2",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"annotation-1": "v1",
|
||||
"annotation-2": "v2",
|
||||
},
|
||||
}
|
||||
expect := map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "test",
|
||||
"namespace": "test-ns",
|
||||
"labels": map[string]string{
|
||||
"label-1": "v1",
|
||||
"label-2": "v2",
|
||||
},
|
||||
"annotations": map[string]string{
|
||||
"annotation-1": "v1",
|
||||
"annotation-2": "v2",
|
||||
},
|
||||
},
|
||||
}
|
||||
d.DescribeMetadata(input)
|
||||
|
||||
assert.True(t, reflect.DeepEqual(expect, d.output))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
package output
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
"github.com/vmware-tanzu/velero/pkg/itemoperation"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/results"
|
||||
)
|
||||
|
||||
func TestDescribeResult(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
inputName string
|
||||
inputResult results.Result
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
name: "result without ns warns",
|
||||
inputName: "restore-1",
|
||||
inputResult: results.Result{
|
||||
Velero: []string{"velero-msg-1", "velero-msg-2"},
|
||||
Cluster: []string{"cluster-msg-1", "cluster-msg-2"},
|
||||
Namespaces: map[string][]string{},
|
||||
},
|
||||
expect: `restore-1:
|
||||
Velero: velero-msg-1
|
||||
velero-msg-2
|
||||
Cluster: cluster-msg-1
|
||||
cluster-msg-2
|
||||
Namespaces: <none>
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "result with ns warns",
|
||||
inputName: "restore-2",
|
||||
inputResult: results.Result{
|
||||
Velero: []string{"velero-msg-1", "velero-msg-2"},
|
||||
Cluster: []string{"cluster-msg-1", "cluster-msg-2"},
|
||||
Namespaces: map[string][]string{
|
||||
"ns-1": {"ns-1-warn-1", "ns-1-warn-2"},
|
||||
},
|
||||
},
|
||||
expect: `restore-2:
|
||||
Velero: velero-msg-1
|
||||
velero-msg-2
|
||||
Cluster: cluster-msg-1
|
||||
cluster-msg-2
|
||||
Namespaces:
|
||||
ns-1: ns-1-warn-1
|
||||
ns-1-warn-2
|
||||
`,
|
||||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(tt *testing.T) {
|
||||
d := &Describer{
|
||||
Prefix: "",
|
||||
out: &tabwriter.Writer{},
|
||||
buf: &bytes.Buffer{},
|
||||
}
|
||||
d.out.Init(d.buf, 0, 8, 2, ' ', 0)
|
||||
describeResult(d, tc.inputName, tc.inputResult)
|
||||
d.out.Flush()
|
||||
assert.Equal(tt, tc.expect, d.buf.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDescribeRestoreItemOperation(t *testing.T) {
|
||||
t1, err1 := time.Parse("2006-Jan-02", "2023-Jun-26")
|
||||
require.Nil(t, err1)
|
||||
t2, err2 := time.Parse("2006-Jan-02", "2023-Jun-25")
|
||||
require.Nil(t, err2)
|
||||
t3, err3 := time.Parse("2006-Jan-02", "2023-Jun-24")
|
||||
require.Nil(t, err3)
|
||||
input := builder.ForRestoreOperation().
|
||||
RestoreName("restore-1").
|
||||
OperationID("op-1").
|
||||
RestoreItemAction("action-1").
|
||||
ResourceIdentifier("group", "rs-type", "ns", "rs-name").
|
||||
Status(*builder.ForOperationStatus().
|
||||
Phase(itemoperation.OperationPhaseFailed).
|
||||
Error("operation error").
|
||||
Progress(50, 100, "bytes").
|
||||
Description("operation description").
|
||||
Created(t3).
|
||||
Started(t2).
|
||||
Updated(t1).
|
||||
Result()).Result()
|
||||
expected := ` Operation for rs-type.group ns/rs-name:
|
||||
Restore Item Action Plugin: action-1
|
||||
Operation ID: op-1
|
||||
Phase: Failed
|
||||
Operation Error: operation error
|
||||
Progress: 50 of 100 complete (bytes)
|
||||
Progress description: operation description
|
||||
Created: 2023-06-24 00:00:00 +0000 UTC
|
||||
Started: 2023-06-25 00:00:00 +0000 UTC
|
||||
Updated: 2023-06-26 00:00:00 +0000 UTC
|
||||
`
|
||||
d := &Describer{
|
||||
Prefix: "",
|
||||
out: &tabwriter.Writer{},
|
||||
buf: &bytes.Buffer{},
|
||||
}
|
||||
d.out.Init(d.buf, 0, 8, 2, ' ', 0)
|
||||
describeRestoreItemOperation(d, input)
|
||||
d.out.Flush()
|
||||
assert.Equal(t, expected, d.buf.String())
|
||||
}
|
||||
|
||||
func TestDescribePodVolumeRestores(t *testing.T) {
|
||||
pvr1 := builder.ForPodVolumeRestore("velero", "pvr-1").
|
||||
UploaderType("kopia").
|
||||
Phase(velerov1api.PodVolumeRestorePhaseCompleted).
|
||||
BackupStorageLocation("bsl-1").
|
||||
Volume("vol-1").
|
||||
PodName("pod-1").
|
||||
PodNamespace("pod-ns-1").
|
||||
SnapshotID("snap-1").Result()
|
||||
pvr2 := builder.ForPodVolumeRestore("velero", "pvr-2").
|
||||
UploaderType("kopia").
|
||||
Phase(velerov1api.PodVolumeRestorePhaseCompleted).
|
||||
BackupStorageLocation("bsl-1").
|
||||
Volume("vol-2").
|
||||
PodName("pod-2").
|
||||
PodNamespace("pod-ns-1").
|
||||
SnapshotID("snap-2").Result()
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
inputPVRList []velerov1api.PodVolumeRestore
|
||||
inputDetails bool
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
name: "empty list",
|
||||
inputPVRList: []velerov1api.PodVolumeRestore{},
|
||||
inputDetails: true,
|
||||
expect: ``,
|
||||
},
|
||||
{
|
||||
name: "2 completed pvrs no details",
|
||||
inputPVRList: []velerov1api.PodVolumeRestore{*pvr1, *pvr2},
|
||||
inputDetails: false,
|
||||
expect: `kopia Restores (specify --details for more information):
|
||||
Completed: 2
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "2 completed pvrs with details",
|
||||
inputPVRList: []velerov1api.PodVolumeRestore{*pvr1, *pvr2},
|
||||
inputDetails: true,
|
||||
expect: `kopia Restores:
|
||||
Completed:
|
||||
pod-ns-1/pod-1: vol-1
|
||||
pod-ns-1/pod-2: vol-2
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(tt *testing.T) {
|
||||
d := &Describer{
|
||||
Prefix: "",
|
||||
out: &tabwriter.Writer{},
|
||||
buf: &bytes.Buffer{},
|
||||
}
|
||||
d.out.Init(d.buf, 0, 8, 2, ' ', 0)
|
||||
describePodVolumeRestores(d, tc.inputPVRList, tc.inputDetails)
|
||||
d.out.Flush()
|
||||
assert.Equal(tt, tc.expect, d.buf.String())
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package output
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
)
|
||||
|
||||
func TestDescribeSchedule(t *testing.T) {
|
||||
input1 := builder.ForSchedule("velero", "schedule-1").
|
||||
Phase(velerov1api.SchedulePhaseFailedValidation).
|
||||
ValidationError("validation failed").Result()
|
||||
expect1 := `Name: schedule-1
|
||||
Namespace: velero
|
||||
Labels: <none>
|
||||
Annotations: <none>
|
||||
|
||||
Phase: FailedValidation
|
||||
|
||||
Validation errors: validation failed
|
||||
|
||||
Paused: false
|
||||
|
||||
Schedule:
|
||||
|
||||
Backup Template:
|
||||
Namespaces:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
Storage Location:
|
||||
|
||||
Velero-Native Snapshot PVs: auto
|
||||
Snapshot Move Data: auto
|
||||
Data Mover: <none>
|
||||
|
||||
TTL: 0s
|
||||
|
||||
CSISnapshotTimeout: 0s
|
||||
ItemOperationTimeout: 0s
|
||||
|
||||
Hooks: <none>
|
||||
|
||||
Last Backup: <never>
|
||||
`
|
||||
|
||||
input2 := builder.ForSchedule("velero", "schedule-2").
|
||||
Phase(velerov1api.SchedulePhaseEnabled).
|
||||
CronSchedule("0 0 * * *").
|
||||
Template(builder.ForBackup("velero", "backup-1").Result().Spec).
|
||||
LastBackupTime("2023-06-25 15:04:05").Result()
|
||||
expect2 := `Name: schedule-2
|
||||
Namespace: velero
|
||||
Labels: <none>
|
||||
Annotations: <none>
|
||||
|
||||
Phase: Enabled
|
||||
|
||||
Paused: false
|
||||
|
||||
Schedule: 0 0 * * *
|
||||
|
||||
Backup Template:
|
||||
Namespaces:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
|
||||
Resources:
|
||||
Included: *
|
||||
Excluded: <none>
|
||||
Cluster-scoped: auto
|
||||
|
||||
Label selector: <none>
|
||||
|
||||
Storage Location:
|
||||
|
||||
Velero-Native Snapshot PVs: auto
|
||||
Snapshot Move Data: auto
|
||||
Data Mover: <none>
|
||||
|
||||
TTL: 0s
|
||||
|
||||
CSISnapshotTimeout: 0s
|
||||
ItemOperationTimeout: 0s
|
||||
|
||||
Hooks: <none>
|
||||
|
||||
Last Backup: 2023-06-25 15:04:05 +0000 UTC
|
||||
`
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
input *velerov1api.Schedule
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
name: "schedule failed in validation",
|
||||
input: input1,
|
||||
expect: expect1,
|
||||
},
|
||||
{
|
||||
name: "schedule enabled",
|
||||
input: input2,
|
||||
expect: expect2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(tt *testing.T) {
|
||||
assert.Equal(tt, tc.expect, DescribeSchedule(tc.input))
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue