719 lines
18 KiB
Go
719 lines
18 KiB
Go
/*
|
|
Copyright the Velero contributors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package output
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
"text/tabwriter"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
corev1api "k8s.io/api/core/v1"
|
|
|
|
"github.com/vmware-tanzu/velero/internal/volume"
|
|
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
|
velerov2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
|
"github.com/vmware-tanzu/velero/pkg/builder"
|
|
"github.com/vmware-tanzu/velero/pkg/itemoperation"
|
|
)
|
|
|
|
func TestDescribeUploaderConfig(t *testing.T) {
|
|
input := builder.ForBackup("test-ns", "test-backup-1").ParallelFilesUpload(10).Result().Spec
|
|
d := &Describer{
|
|
Prefix: "",
|
|
out: &tabwriter.Writer{},
|
|
buf: &bytes.Buffer{},
|
|
}
|
|
d.out.Init(d.buf, 0, 8, 2, ' ', 0)
|
|
DescribeUploaderConfigForBackup(d, input)
|
|
d.out.Flush()
|
|
expect := `Uploader config:
|
|
Parallel files upload: 10
|
|
`
|
|
assert.Equal(t, expect, d.buf.String())
|
|
}
|
|
|
|
func TestDescribeResourcePolicies(t *testing.T) {
|
|
input := &corev1api.TypedLocalObjectReference{
|
|
Kind: "configmap",
|
|
Name: "test-resource-policy",
|
|
}
|
|
d := &Describer{
|
|
Prefix: "",
|
|
out: &tabwriter.Writer{},
|
|
buf: &bytes.Buffer{},
|
|
}
|
|
d.out.Init(d.buf, 0, 8, 2, ' ', 0)
|
|
DescribeResourcePolicies(d, input)
|
|
d.out.Flush()
|
|
expect := `Resource policies:
|
|
Type: configmap
|
|
Name: test-resource-policy
|
|
`
|
|
assert.Equal(t, expect, d.buf.String())
|
|
}
|
|
|
|
func TestDescribeBackupSpec(t *testing.T) {
|
|
input1 := builder.ForBackup("test-ns", "test-backup-1").
|
|
IncludedNamespaces("inc-ns-1", "inc-ns-2").
|
|
ExcludedNamespaces("exc-ns-1", "exc-ns-2").
|
|
IncludedResources("inc-res-1", "inc-res-2").
|
|
ExcludedResources("exc-res-1", "exc-res-2").
|
|
StorageLocation("backup-location").
|
|
TTL(72 * time.Hour).
|
|
CSISnapshotTimeout(10 * time.Minute).
|
|
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,
|
|
},
|
|
},
|
|
},
|
|
IncludedNamespaces: []string{"hook-inc-ns-1", "hook-inc-ns-2"},
|
|
ExcludedNamespaces: []string{"hook-exc-ns-1", "hook-exc-ns-2"},
|
|
IncludedResources: []string{"hook-inc-res-1", "hook-inc-res-2"},
|
|
ExcludedResources: []string{"hook-exc-res-1", "hook-exc-res-2"},
|
|
},
|
|
},
|
|
}).Result().Spec
|
|
|
|
expect1 := `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
|
|
Cluster-scoped: auto
|
|
|
|
Label selector: <none>
|
|
|
|
Or label selector: <none>
|
|
|
|
Storage Location: backup-location
|
|
|
|
Velero-Native Snapshot PVs: auto
|
|
Snapshot Move Data: auto
|
|
Data Mover: mover
|
|
|
|
TTL: 72h0m0s
|
|
|
|
CSISnapshotTimeout: 10m0s
|
|
ItemOperationTimeout: 0s
|
|
|
|
Hooks:
|
|
Resources:
|
|
hook-1:
|
|
Namespaces:
|
|
Included: hook-inc-ns-1, hook-inc-ns-2
|
|
Excluded: hook-exc-ns-1, hook-exc-ns-2
|
|
|
|
Resources:
|
|
Included: hook-inc-res-1, hook-inc-res-2
|
|
Excluded: hook-exc-res-1, hook-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").
|
|
IncludedNamespaces("inc-ns-1", "inc-ns-2").
|
|
ExcludedNamespaces("exc-ns-1", "exc-ns-2").
|
|
IncludedClusterScopedResources("inc-cluster-res-1", "inc-cluster-res-2").
|
|
IncludedNamespaceScopedResources("inc-ns-res-1", "inc-ns-res-2").
|
|
ExcludedClusterScopedResources("exc-cluster-res-1", "exc-cluster-res-2").
|
|
ExcludedNamespaceScopedResources("exc-ns-res-1", "exc-ns-res-2").
|
|
StorageLocation("backup-location").
|
|
TTL(72 * time.Hour).
|
|
CSISnapshotTimeout(10 * time.Minute).
|
|
DataMover("mover").
|
|
Result().Spec
|
|
|
|
expect2 := `Namespaces:
|
|
Included: inc-ns-1, inc-ns-2
|
|
Excluded: exc-ns-1, exc-ns-2
|
|
|
|
Resources:
|
|
Included cluster-scoped: inc-cluster-res-1, inc-cluster-res-2
|
|
Excluded cluster-scoped: exc-cluster-res-1, exc-cluster-res-2
|
|
Included namespace-scoped: inc-ns-res-1, inc-ns-res-2
|
|
Excluded namespace-scoped: exc-ns-res-1, exc-ns-res-2
|
|
|
|
Label selector: <none>
|
|
|
|
Or label selector: <none>
|
|
|
|
Storage Location: backup-location
|
|
|
|
Velero-Native Snapshot PVs: auto
|
|
Snapshot Move Data: auto
|
|
Data Mover: mover
|
|
|
|
TTL: 72h0m0s
|
|
|
|
CSISnapshotTimeout: 10m0s
|
|
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>
|
|
|
|
Or label selector: <none>
|
|
|
|
Storage Location: backup-location
|
|
|
|
Velero-Native Snapshot PVs: auto
|
|
Snapshot Move Data: auto
|
|
Data Mover: velero
|
|
|
|
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 with hooks",
|
|
input: input1,
|
|
expect: expect1,
|
|
},
|
|
{
|
|
name: "new resource filter",
|
|
input: input2,
|
|
expect: expect2,
|
|
},
|
|
{
|
|
name: "old resource filter with hooks and ordered resources",
|
|
input: input3,
|
|
expect: expect3,
|
|
},
|
|
}
|
|
|
|
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)
|
|
DescribeBackupSpec(d, tc.input)
|
|
d.out.Flush()
|
|
assert.Equal(tt, tc.expect, d.buf.String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDescribeNativeSnapshots(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
volumeInfo []*volume.BackupVolumeInfo
|
|
inputDetails bool
|
|
expect string
|
|
}{
|
|
{
|
|
name: "no details",
|
|
volumeInfo: []*volume.BackupVolumeInfo{
|
|
{
|
|
BackupMethod: volume.NativeSnapshot,
|
|
PVName: "pv-1",
|
|
NativeSnapshotInfo: &volume.NativeSnapshotInfo{
|
|
SnapshotHandle: "snapshot-1",
|
|
VolumeType: "ebs",
|
|
VolumeAZ: "us-east-2",
|
|
IOPS: "1000 mbps",
|
|
},
|
|
},
|
|
},
|
|
expect: ` Velero-Native Snapshots:
|
|
pv-1: specify --details for more information
|
|
`,
|
|
},
|
|
{
|
|
name: "details",
|
|
volumeInfo: []*volume.BackupVolumeInfo{
|
|
{
|
|
BackupMethod: volume.NativeSnapshot,
|
|
PVName: "pv-1",
|
|
Result: volume.VolumeResultSucceeded,
|
|
NativeSnapshotInfo: &volume.NativeSnapshotInfo{
|
|
SnapshotHandle: "snapshot-1",
|
|
VolumeType: "ebs",
|
|
VolumeAZ: "us-east-2",
|
|
IOPS: "1000 mbps",
|
|
},
|
|
},
|
|
},
|
|
inputDetails: true,
|
|
expect: ` Velero-Native Snapshots:
|
|
pv-1:
|
|
Snapshot ID: snapshot-1
|
|
Type: ebs
|
|
Availability Zone: us-east-2
|
|
IOPS: 1000 mbps
|
|
Result: succeeded
|
|
`,
|
|
},
|
|
}
|
|
|
|
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)
|
|
describeNativeSnapshots(d, tc.inputDetails, tc.volumeInfo)
|
|
d.out.Flush()
|
|
assert.Equal(t, tc.expect, d.buf.String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCSISnapshots(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
volumeInfo []*volume.BackupVolumeInfo
|
|
inputDetails bool
|
|
expect string
|
|
legacyInfoSource bool
|
|
}{
|
|
{
|
|
name: "empty info, not legacy",
|
|
volumeInfo: []*volume.BackupVolumeInfo{},
|
|
expect: ` CSI Snapshots: <none included>
|
|
`,
|
|
},
|
|
{
|
|
name: "empty info, legacy",
|
|
volumeInfo: []*volume.BackupVolumeInfo{},
|
|
legacyInfoSource: true,
|
|
expect: ` CSI Snapshots: <none included or not detectable>
|
|
`,
|
|
},
|
|
{
|
|
name: "no details, local snapshot",
|
|
volumeInfo: []*volume.BackupVolumeInfo{
|
|
{
|
|
BackupMethod: volume.CSISnapshot,
|
|
PVCNamespace: "pvc-ns-1",
|
|
PVCName: "pvc-1",
|
|
PreserveLocalSnapshot: true,
|
|
CSISnapshotInfo: &volume.CSISnapshotInfo{
|
|
SnapshotHandle: "snapshot-1",
|
|
Size: 1024,
|
|
Driver: "fake-driver",
|
|
VSCName: "vsc-1",
|
|
OperationID: "fake-operation-1",
|
|
},
|
|
},
|
|
},
|
|
expect: ` CSI Snapshots:
|
|
pvc-ns-1/pvc-1:
|
|
Snapshot: included, specify --details for more information
|
|
`,
|
|
},
|
|
{
|
|
name: "details, local snapshot",
|
|
volumeInfo: []*volume.BackupVolumeInfo{
|
|
{
|
|
BackupMethod: volume.CSISnapshot,
|
|
PVCNamespace: "pvc-ns-2",
|
|
PVCName: "pvc-2",
|
|
PreserveLocalSnapshot: true,
|
|
Result: volume.VolumeResultSucceeded,
|
|
CSISnapshotInfo: &volume.CSISnapshotInfo{
|
|
SnapshotHandle: "snapshot-2",
|
|
Size: 1024,
|
|
Driver: "fake-driver",
|
|
VSCName: "vsc-2",
|
|
OperationID: "fake-operation-2",
|
|
},
|
|
},
|
|
},
|
|
inputDetails: true,
|
|
expect: ` CSI Snapshots:
|
|
pvc-ns-2/pvc-2:
|
|
Snapshot:
|
|
Operation ID: fake-operation-2
|
|
Snapshot Content Name: vsc-2
|
|
Storage Snapshot ID: snapshot-2
|
|
Snapshot Size (bytes): 1024
|
|
CSI Driver: fake-driver
|
|
Result: succeeded
|
|
`,
|
|
},
|
|
{
|
|
name: "no details, data movement",
|
|
volumeInfo: []*volume.BackupVolumeInfo{
|
|
{
|
|
BackupMethod: volume.CSISnapshot,
|
|
PVCNamespace: "pvc-ns-3",
|
|
PVCName: "pvc-3",
|
|
SnapshotDataMoved: true,
|
|
SnapshotDataMovementInfo: &volume.SnapshotDataMovementInfo{
|
|
DataMover: "velero",
|
|
UploaderType: "fake-uploader",
|
|
SnapshotHandle: "fake-repo-id-3",
|
|
OperationID: "fake-operation-3",
|
|
},
|
|
},
|
|
},
|
|
expect: ` CSI Snapshots:
|
|
pvc-ns-3/pvc-3:
|
|
Data Movement: included, specify --details for more information
|
|
`,
|
|
},
|
|
{
|
|
name: "details, data movement",
|
|
volumeInfo: []*volume.BackupVolumeInfo{
|
|
{
|
|
BackupMethod: volume.CSISnapshot,
|
|
PVCNamespace: "pvc-ns-4",
|
|
PVCName: "pvc-4",
|
|
SnapshotDataMoved: true,
|
|
Result: volume.VolumeResultSucceeded,
|
|
SnapshotDataMovementInfo: &volume.SnapshotDataMovementInfo{
|
|
DataMover: "velero",
|
|
UploaderType: "fake-uploader",
|
|
SnapshotHandle: "fake-repo-id-4",
|
|
OperationID: "fake-operation-4",
|
|
},
|
|
},
|
|
},
|
|
inputDetails: true,
|
|
expect: ` CSI Snapshots:
|
|
pvc-ns-4/pvc-4:
|
|
Data Movement:
|
|
Operation ID: fake-operation-4
|
|
Data Mover: velero
|
|
Uploader Type: fake-uploader
|
|
Moved data Size (bytes): 0
|
|
Result: succeeded
|
|
`,
|
|
},
|
|
{
|
|
name: "details, data movement, data mover is empty",
|
|
volumeInfo: []*volume.BackupVolumeInfo{
|
|
{
|
|
BackupMethod: volume.CSISnapshot,
|
|
PVCNamespace: "pvc-ns-5",
|
|
PVCName: "pvc-5",
|
|
Result: volume.VolumeResultFailed,
|
|
SnapshotDataMoved: true,
|
|
SnapshotDataMovementInfo: &volume.SnapshotDataMovementInfo{
|
|
UploaderType: "fake-uploader",
|
|
SnapshotHandle: "fake-repo-id-5",
|
|
OperationID: "fake-operation-5",
|
|
Size: 100,
|
|
Phase: velerov2alpha1.DataUploadPhaseFailed,
|
|
},
|
|
},
|
|
},
|
|
inputDetails: true,
|
|
expect: ` CSI Snapshots:
|
|
pvc-ns-5/pvc-5:
|
|
Data Movement:
|
|
Operation ID: fake-operation-5
|
|
Data Mover: velero
|
|
Uploader Type: fake-uploader
|
|
Moved data Size (bytes): 100
|
|
Result: failed
|
|
`,
|
|
},
|
|
}
|
|
|
|
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)
|
|
describeCSISnapshots(d, tc.inputDetails, tc.volumeInfo, tc.legacyInfoSource)
|
|
d.out.Flush()
|
|
assert.Equal(t, tc.expect, d.buf.String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDescribePodVolumeBackups(t *testing.T) {
|
|
pvb1 := builder.ForPodVolumeBackup("test-ns", "test-pvb1").
|
|
UploaderType("kopia").
|
|
Phase(velerov1api.PodVolumeBackupPhaseCompleted).
|
|
BackupStorageLocation("bsl-1").
|
|
Volume("vol-1").
|
|
PodName("pod-1").
|
|
PodNamespace("pod-ns-1").
|
|
SnapshotID("snap-1").Result()
|
|
pvb2 := builder.ForPodVolumeBackup("test-ns1", "test-pvb2").
|
|
UploaderType("kopia").
|
|
Phase(velerov1api.PodVolumeBackupPhaseCompleted).
|
|
BackupStorageLocation("bsl-1").
|
|
Volume("vol-2").
|
|
PodName("pod-2").
|
|
PodNamespace("pod-ns-1").
|
|
SnapshotID("snap-2").Result()
|
|
|
|
testcases := []struct {
|
|
name string
|
|
inputPVBList []velerov1api.PodVolumeBackup
|
|
inputDetails bool
|
|
expect string
|
|
}{
|
|
{
|
|
name: "empty list",
|
|
inputPVBList: []velerov1api.PodVolumeBackup{},
|
|
inputDetails: true,
|
|
expect: ` Pod Volume Backups: <none included>
|
|
`,
|
|
},
|
|
{
|
|
name: "2 completed pvbs no details",
|
|
inputPVBList: []velerov1api.PodVolumeBackup{*pvb1, *pvb2},
|
|
inputDetails: false,
|
|
expect: ` Pod Volume Backups - kopia (specify --details for more information):
|
|
Completed: 2
|
|
`,
|
|
},
|
|
{
|
|
name: "2 completed pvbs with details",
|
|
inputPVBList: []velerov1api.PodVolumeBackup{*pvb1, *pvb2},
|
|
inputDetails: true,
|
|
expect: ` Pod Volume Backups - kopia:
|
|
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)
|
|
describePodVolumeBackups(d, tc.inputDetails, tc.inputPVBList)
|
|
d.out.Flush()
|
|
assert.Equal(tt, tc.expect, d.buf.String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDescribeDeleteBackupRequests(t *testing.T) {
|
|
t1, err1 := time.Parse("2006-Jan-02", "2023-Jun-26")
|
|
require.NoError(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.NoError(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.NoError(t, err1)
|
|
t2, err2 := time.Parse("2006-Jan-02", "2023-Jun-25")
|
|
require.NoError(t, err2)
|
|
t3, err3 := time.Parse("2006-Jan-02", "2023-Jun-24")
|
|
require.NoError(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())
|
|
}
|