mirror of
https://github.com/restic/restic.git
synced 2026-06-21 08:04:18 +00:00
internal/restorer: invert dependency direction to ui/restorer
The restorer imported ui/restorer which leaks ui logic into the restorer core. Swap the direction by letting the restorer use a ProgressReporter interface + associated constants.
This commit is contained in:
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/restic/restic/internal/feature"
|
||||
"github.com/restic/restic/internal/repository"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
"github.com/restic/restic/internal/ui/restore"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -56,7 +55,7 @@ type fileRestorer struct {
|
||||
filesWriter *filesWriter
|
||||
zeroChunk restic.ID
|
||||
sparse bool
|
||||
progress *restore.Progress
|
||||
progress ProgressReporter
|
||||
|
||||
allowRecursiveDelete bool
|
||||
|
||||
@@ -73,7 +72,7 @@ func newFileRestorer(dst string,
|
||||
sparse bool,
|
||||
allowRecursiveDelete bool,
|
||||
startWarmup startWarmupFn,
|
||||
progress *restore.Progress) *fileRestorer {
|
||||
progress ProgressReporter) *fileRestorer {
|
||||
|
||||
// as packs are streamed the concurrency is limited by IO
|
||||
workerCount := int(connections)
|
||||
@@ -85,7 +84,7 @@ func newFileRestorer(dst string,
|
||||
filesWriter: newFilesWriter(workerCount, allowRecursiveDelete),
|
||||
zeroChunk: repository.ZeroChunk(),
|
||||
sparse: sparse,
|
||||
progress: progress,
|
||||
progress: progressOrNoop(progress),
|
||||
allowRecursiveDelete: allowRecursiveDelete,
|
||||
workerCount: workerCount,
|
||||
dst: dst,
|
||||
@@ -398,9 +397,9 @@ func (r *fileRestorer) downloadBlobs(ctx context.Context, packID restic.ID,
|
||||
}
|
||||
|
||||
func (r *fileRestorer) reportBlobProgress(file *fileInfo, blobSize uint64) {
|
||||
action := restore.ActionFileUpdated
|
||||
action := ActionFileUpdated
|
||||
if file.state == nil {
|
||||
action = restore.ActionFileRestored
|
||||
action = ActionFileRestored
|
||||
}
|
||||
r.progress.AddProgress(file.location, action, blobSize, uint64(file.size))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package restorer
|
||||
|
||||
type ItemAction string
|
||||
|
||||
// Constants for the different CompleteItem actions.
|
||||
const (
|
||||
ActionDirRestored ItemAction = "dir restored"
|
||||
ActionFileRestored ItemAction = "file restored"
|
||||
ActionFileUpdated ItemAction = "file updated"
|
||||
ActionFileUnchanged ItemAction = "file unchanged"
|
||||
ActionOtherRestored ItemAction = "other restored"
|
||||
ActionDeleted ItemAction = "deleted"
|
||||
)
|
||||
|
||||
// ProgressReporter reports restore progress.
|
||||
type ProgressReporter interface {
|
||||
AddFile(size uint64)
|
||||
AddProgress(name string, action ItemAction, bytesWrittenPortion, bytesTotal uint64)
|
||||
AddSkippedFile(name string, size uint64)
|
||||
ReportDeletion(name string)
|
||||
}
|
||||
|
||||
type noopProgressReporter struct{}
|
||||
|
||||
var _ ProgressReporter = (*noopProgressReporter)(nil)
|
||||
|
||||
func (noopProgressReporter) AddFile(uint64) {}
|
||||
func (noopProgressReporter) AddProgress(string, ItemAction, uint64, uint64) {
|
||||
}
|
||||
func (noopProgressReporter) AddSkippedFile(string, uint64) {}
|
||||
func (noopProgressReporter) ReportDeletion(string) {}
|
||||
|
||||
func progressOrNoop(p ProgressReporter) ProgressReporter {
|
||||
if p == nil {
|
||||
return noopProgressReporter{}
|
||||
}
|
||||
return p
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package restorer
|
||||
|
||||
type progressInfoEntry struct {
|
||||
bytesWritten uint64
|
||||
bytesTotal uint64
|
||||
}
|
||||
|
||||
// progressState mirrors the state used by the restorer ui.
|
||||
type progressState struct {
|
||||
FilesFinished uint64
|
||||
FilesTotal uint64
|
||||
FilesSkipped uint64
|
||||
FilesDeleted uint64
|
||||
AllBytesWritten uint64
|
||||
AllBytesTotal uint64
|
||||
AllBytesSkipped uint64
|
||||
}
|
||||
|
||||
type testProgress struct {
|
||||
progressInfoMap map[string]progressInfoEntry
|
||||
s progressState
|
||||
}
|
||||
|
||||
var _ ProgressReporter = (*testProgress)(nil)
|
||||
|
||||
func newTestProgress() *testProgress {
|
||||
return &testProgress{
|
||||
progressInfoMap: make(map[string]progressInfoEntry),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *testProgress) AddFile(size uint64) {
|
||||
p.s.FilesTotal++
|
||||
p.s.AllBytesTotal += size
|
||||
}
|
||||
|
||||
func (p *testProgress) AddProgress(name string, _ ItemAction, bytesWrittenPortion, bytesTotal uint64) {
|
||||
entry, exists := p.progressInfoMap[name]
|
||||
if !exists {
|
||||
entry.bytesTotal = bytesTotal
|
||||
}
|
||||
entry.bytesWritten += bytesWrittenPortion
|
||||
p.progressInfoMap[name] = entry
|
||||
|
||||
p.s.AllBytesWritten += bytesWrittenPortion
|
||||
if entry.bytesWritten == entry.bytesTotal {
|
||||
delete(p.progressInfoMap, name)
|
||||
p.s.FilesFinished++
|
||||
}
|
||||
}
|
||||
|
||||
func (p *testProgress) AddSkippedFile(_ string, size uint64) {
|
||||
p.s.FilesSkipped++
|
||||
p.s.AllBytesSkipped += size
|
||||
}
|
||||
|
||||
func (p *testProgress) ReportDeletion(_ string) {
|
||||
p.s.FilesDeleted++
|
||||
}
|
||||
|
||||
func (p *testProgress) state() progressState {
|
||||
return p.s
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/restic/restic/internal/errors"
|
||||
"github.com/restic/restic/internal/fs"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
restoreui "github.com/restic/restic/internal/ui/restore"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
@@ -41,7 +40,7 @@ var restorerAbortOnAllErrors = func(_ string, err error) error { return err }
|
||||
type Options struct {
|
||||
DryRun bool
|
||||
Sparse bool
|
||||
Progress *restoreui.Progress
|
||||
Progress ProgressReporter
|
||||
Overwrite OverwriteBehavior
|
||||
Delete bool
|
||||
OwnershipByName bool
|
||||
@@ -100,6 +99,7 @@ func (c *OverwriteBehavior) Type() string {
|
||||
|
||||
// NewRestorer creates a restorer preloaded with the content from the snapshot id.
|
||||
func NewRestorer(repo restic.Repository, sn *data.Snapshot, opts Options) *Restorer {
|
||||
opts.Progress = progressOrNoop(opts.Progress)
|
||||
r := &Restorer{
|
||||
repo: repo,
|
||||
opts: opts,
|
||||
@@ -287,7 +287,7 @@ func (res *Restorer) restoreNodeTo(node *data.Node, target, location string) err
|
||||
}
|
||||
}
|
||||
|
||||
res.opts.Progress.AddProgress(location, restoreui.ActionOtherRestored, 0, 0)
|
||||
res.opts.Progress.AddProgress(location, ActionOtherRestored, 0, 0)
|
||||
return res.restoreNodeMetadataTo(node, target, location)
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ func (res *Restorer) restoreHardlinkAt(node *data.Node, target, path, location s
|
||||
}
|
||||
}
|
||||
|
||||
res.opts.Progress.AddProgress(location, restoreui.ActionOtherRestored, 0, 0)
|
||||
res.opts.Progress.AddProgress(location, ActionOtherRestored, 0, 0)
|
||||
// TODO investigate if hardlinks have separate metadata on any supported system
|
||||
return res.restoreNodeMetadataTo(node, path, location)
|
||||
}
|
||||
@@ -408,9 +408,9 @@ func (res *Restorer) RestoreTo(ctx context.Context, dst string) (uint64, error)
|
||||
if !res.opts.DryRun {
|
||||
filerestorer.addFile(location, node.Content, int64(node.Size), matches)
|
||||
} else {
|
||||
action := restoreui.ActionFileUpdated
|
||||
action := ActionFileUpdated
|
||||
if matches == nil {
|
||||
action = restoreui.ActionFileRestored
|
||||
action = ActionFileRestored
|
||||
}
|
||||
// immediately mark as completed
|
||||
res.opts.Progress.AddProgress(location, action, node.Size, node.Size)
|
||||
@@ -475,7 +475,7 @@ func (res *Restorer) RestoreTo(ctx context.Context, dst string) (uint64, error)
|
||||
|
||||
err := res.restoreNodeMetadataTo(node, target, location)
|
||||
if err == nil {
|
||||
res.opts.Progress.AddProgress(location, restoreui.ActionDirRestored, 0, 0)
|
||||
res.opts.Progress.AddProgress(location, ActionDirRestored, 0, 0)
|
||||
}
|
||||
return err
|
||||
},
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
"github.com/restic/restic/internal/restic"
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
"github.com/restic/restic/internal/ui/progress"
|
||||
restoreui "github.com/restic/restic/internal/ui/restore"
|
||||
)
|
||||
|
||||
type Node interface{}
|
||||
@@ -987,22 +986,6 @@ func TestRestorerSparseOverwrite(t *testing.T) {
|
||||
saveSnapshotsAndOverwrite(t, baseSnapshot, sparseSnapshot, opts, opts)
|
||||
}
|
||||
|
||||
type printerMock struct {
|
||||
s restoreui.State
|
||||
restic.Printer
|
||||
}
|
||||
|
||||
func (p *printerMock) Update(_ restoreui.State, _ time.Duration) {
|
||||
}
|
||||
func (p *printerMock) Error(_ string, _ error) error {
|
||||
return nil
|
||||
}
|
||||
func (p *printerMock) CompleteItem(_ restoreui.ItemAction, _ string, _ uint64) {
|
||||
}
|
||||
func (p *printerMock) Finish(s restoreui.State, _ time.Duration) {
|
||||
p.s = s
|
||||
}
|
||||
|
||||
func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||
baseTime := time.Now()
|
||||
baseSnapshot := Snapshot{
|
||||
@@ -1032,7 +1015,7 @@ func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||
var tests = []struct {
|
||||
Overwrite OverwriteBehavior
|
||||
Files map[string]string
|
||||
Progress restoreui.State
|
||||
Progress progressState
|
||||
}{
|
||||
{
|
||||
Overwrite: OverwriteAlways,
|
||||
@@ -1041,7 +1024,7 @@ func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||
"dirtest/file": "content: file2\n",
|
||||
"dirtest/foo": "content: foo",
|
||||
},
|
||||
Progress: restoreui.State{
|
||||
Progress: progressState{
|
||||
FilesFinished: 4,
|
||||
FilesTotal: 4,
|
||||
FilesSkipped: 0,
|
||||
@@ -1057,7 +1040,7 @@ func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||
"dirtest/file": "content: file2\n",
|
||||
"dirtest/foo": "content: foo",
|
||||
},
|
||||
Progress: restoreui.State{
|
||||
Progress: progressState{
|
||||
FilesFinished: 4,
|
||||
FilesTotal: 4,
|
||||
FilesSkipped: 0,
|
||||
@@ -1073,7 +1056,7 @@ func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||
"dirtest/file": "content: file\n",
|
||||
"dirtest/foo": "content: foobar",
|
||||
},
|
||||
Progress: restoreui.State{
|
||||
Progress: progressState{
|
||||
FilesFinished: 2,
|
||||
FilesTotal: 2,
|
||||
FilesSkipped: 2,
|
||||
@@ -1089,7 +1072,7 @@ func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||
"dirtest/file": "content: file\n",
|
||||
"dirtest/foo": "content: foobar",
|
||||
},
|
||||
Progress: restoreui.State{
|
||||
Progress: progressState{
|
||||
FilesFinished: 1,
|
||||
FilesTotal: 1,
|
||||
FilesSkipped: 3,
|
||||
@@ -1102,8 +1085,7 @@ func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run("", func(t *testing.T) {
|
||||
mock := &printerMock{Printer: restic.NewNoopPrinter()}
|
||||
progress := restoreui.NewProgress(mock, true, false, true)
|
||||
progress := newTestProgress()
|
||||
tempdir := saveSnapshotsAndOverwrite(t, baseSnapshot, overwriteSnapshot, Options{}, Options{Overwrite: test.Overwrite, Progress: progress})
|
||||
|
||||
for filename, content := range test.Files {
|
||||
@@ -1118,8 +1100,7 @@ func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
progress.Finish()
|
||||
rtest.Equals(t, test.Progress, mock.s)
|
||||
rtest.Equals(t, test.Progress, progress.state())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1154,18 +1135,16 @@ func TestRestorerOverwritePartial(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
mock := &printerMock{Printer: restic.NewNoopPrinter()}
|
||||
progress := restoreui.NewProgress(mock, true, false, true)
|
||||
progress := newTestProgress()
|
||||
saveSnapshotsAndOverwrite(t, baseSnapshot, overwriteSnapshot, Options{}, Options{Overwrite: OverwriteAlways, Progress: progress})
|
||||
progress.Finish()
|
||||
rtest.Equals(t, restoreui.State{
|
||||
rtest.Equals(t, progressState{
|
||||
FilesFinished: 2,
|
||||
FilesTotal: 2,
|
||||
FilesSkipped: 0,
|
||||
AllBytesWritten: uint64(size),
|
||||
AllBytesTotal: uint64(size),
|
||||
AllBytesSkipped: 0,
|
||||
}, mock.s)
|
||||
}, progress.state())
|
||||
}
|
||||
|
||||
func TestRestorerOverwriteSpecial(t *testing.T) {
|
||||
|
||||
@@ -12,9 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/restic/restic/internal/repository"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
restoreui "github.com/restic/restic/internal/ui/restore"
|
||||
)
|
||||
|
||||
func TestRestorerRestoreEmptyHardlinkedFields(t *testing.T) {
|
||||
@@ -88,8 +86,7 @@ func testRestorerProgressBar(t *testing.T, dryRun bool) {
|
||||
},
|
||||
}, noopGetGenericAttributes)
|
||||
|
||||
mock := &printerMock{Printer: restic.NewNoopPrinter()}
|
||||
progress := restoreui.NewProgress(mock, true, false, true)
|
||||
progress := newTestProgress()
|
||||
res := NewRestorer(repo, sn, Options{Progress: progress, DryRun: dryRun})
|
||||
|
||||
tempdir := rtest.TempDir(t)
|
||||
@@ -98,16 +95,15 @@ func testRestorerProgressBar(t *testing.T, dryRun bool) {
|
||||
|
||||
_, err := res.RestoreTo(ctx, tempdir)
|
||||
rtest.OK(t, err)
|
||||
progress.Finish()
|
||||
|
||||
rtest.Equals(t, restoreui.State{
|
||||
rtest.Equals(t, progressState{
|
||||
FilesFinished: 4,
|
||||
FilesTotal: 4,
|
||||
FilesSkipped: 0,
|
||||
AllBytesWritten: 10,
|
||||
AllBytesTotal: 10,
|
||||
AllBytesSkipped: 0,
|
||||
}, mock.s)
|
||||
}, progress.state())
|
||||
}
|
||||
|
||||
func TestRestorePermissions(t *testing.T) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/restic/restic/internal/restic"
|
||||
"github.com/restic/restic/internal/restorer"
|
||||
"github.com/restic/restic/internal/ui"
|
||||
"github.com/restic/restic/internal/ui/progress"
|
||||
)
|
||||
@@ -61,24 +62,24 @@ func (t *jsonPrinter) Error(item string, err error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *jsonPrinter) CompleteItem(messageType ItemAction, item string, size uint64) {
|
||||
func (t *jsonPrinter) CompleteItem(messageType restorer.ItemAction, item string, size uint64) {
|
||||
if t.verbosity < 3 {
|
||||
return
|
||||
}
|
||||
|
||||
var action string
|
||||
switch messageType {
|
||||
case ActionDirRestored:
|
||||
case restorer.ActionDirRestored:
|
||||
action = "restored"
|
||||
case ActionFileRestored:
|
||||
case restorer.ActionFileRestored:
|
||||
action = "restored"
|
||||
case ActionOtherRestored:
|
||||
case restorer.ActionOtherRestored:
|
||||
action = "restored"
|
||||
case ActionFileUpdated:
|
||||
case restorer.ActionFileUpdated:
|
||||
action = "updated"
|
||||
case ActionFileUnchanged:
|
||||
case restorer.ActionFileUnchanged:
|
||||
action = "unchanged"
|
||||
case ActionDeleted:
|
||||
case restorer.ActionDeleted:
|
||||
action = "deleted"
|
||||
default:
|
||||
panic("unknown message type")
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/restic/restic/internal/errors"
|
||||
"github.com/restic/restic/internal/restorer"
|
||||
"github.com/restic/restic/internal/test"
|
||||
"github.com/restic/restic/internal/ui"
|
||||
)
|
||||
@@ -47,15 +48,15 @@ func TestJSONPrintSummaryOnSuccessWithSkipped(t *testing.T) {
|
||||
|
||||
func TestJSONPrintCompleteItem(t *testing.T) {
|
||||
for _, data := range []struct {
|
||||
action ItemAction
|
||||
action restorer.ItemAction
|
||||
size uint64
|
||||
expected string
|
||||
}{
|
||||
{ActionDirRestored, 0, "{\"message_type\":\"verbose_status\",\"action\":\"restored\",\"item\":\"test\",\"size\":0}\n"},
|
||||
{ActionFileRestored, 123, "{\"message_type\":\"verbose_status\",\"action\":\"restored\",\"item\":\"test\",\"size\":123}\n"},
|
||||
{ActionFileUpdated, 123, "{\"message_type\":\"verbose_status\",\"action\":\"updated\",\"item\":\"test\",\"size\":123}\n"},
|
||||
{ActionFileUnchanged, 123, "{\"message_type\":\"verbose_status\",\"action\":\"unchanged\",\"item\":\"test\",\"size\":123}\n"},
|
||||
{ActionDeleted, 0, "{\"message_type\":\"verbose_status\",\"action\":\"deleted\",\"item\":\"test\",\"size\":0}\n"},
|
||||
{restorer.ActionDirRestored, 0, "{\"message_type\":\"verbose_status\",\"action\":\"restored\",\"item\":\"test\",\"size\":0}\n"},
|
||||
{restorer.ActionFileRestored, 123, "{\"message_type\":\"verbose_status\",\"action\":\"restored\",\"item\":\"test\",\"size\":123}\n"},
|
||||
{restorer.ActionFileUpdated, 123, "{\"message_type\":\"verbose_status\",\"action\":\"updated\",\"item\":\"test\",\"size\":123}\n"},
|
||||
{restorer.ActionFileUnchanged, 123, "{\"message_type\":\"verbose_status\",\"action\":\"unchanged\",\"item\":\"test\",\"size\":123}\n"},
|
||||
{restorer.ActionDeleted, 0, "{\"message_type\":\"verbose_status\",\"action\":\"deleted\",\"item\":\"test\",\"size\":0}\n"},
|
||||
} {
|
||||
term, printer := createJSONProgress()
|
||||
printer.CompleteItem(data.action, "test", data.size)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/restic/restic/internal/restic"
|
||||
"github.com/restic/restic/internal/restorer"
|
||||
"github.com/restic/restic/internal/ui/progress"
|
||||
)
|
||||
|
||||
@@ -29,6 +30,8 @@ type Progress struct {
|
||||
printer ProgressPrinter
|
||||
}
|
||||
|
||||
var _ restorer.ProgressReporter = (*Progress)(nil)
|
||||
|
||||
type progressInfoEntry struct {
|
||||
bytesWritten uint64
|
||||
bytesTotal uint64
|
||||
@@ -37,22 +40,12 @@ type progressInfoEntry struct {
|
||||
type ProgressPrinter interface {
|
||||
Update(progress State, duration time.Duration)
|
||||
Error(item string, err error) error
|
||||
CompleteItem(action ItemAction, item string, size uint64)
|
||||
CompleteItem(action restorer.ItemAction, item string, size uint64)
|
||||
Finish(progress State, duration time.Duration)
|
||||
restic.Printer
|
||||
}
|
||||
|
||||
type ItemAction string
|
||||
|
||||
// Constants for the different CompleteItem actions.
|
||||
const (
|
||||
ActionDirRestored ItemAction = "dir restored"
|
||||
ActionFileRestored ItemAction = "file restored"
|
||||
ActionFileUpdated ItemAction = "file updated"
|
||||
ActionFileUnchanged ItemAction = "file unchanged"
|
||||
ActionOtherRestored ItemAction = "other restored"
|
||||
ActionDeleted ItemAction = "deleted"
|
||||
)
|
||||
var _ restorer.ProgressReporter = (*Progress)(nil)
|
||||
|
||||
func NewProgress(printer ProgressPrinter, quiet, json, canUpdateStatus bool) *Progress {
|
||||
return newProgress(printer, progress.CalculateProgressInterval(!quiet, json, canUpdateStatus))
|
||||
@@ -93,7 +86,7 @@ func (p *Progress) AddFile(size uint64) {
|
||||
}
|
||||
|
||||
// AddProgress accumulates the number of bytes written for a file
|
||||
func (p *Progress) AddProgress(name string, action ItemAction, bytesWrittenPortion uint64, bytesTotal uint64) {
|
||||
func (p *Progress) AddProgress(name string, action restorer.ItemAction, bytesWrittenPortion uint64, bytesTotal uint64) {
|
||||
if p == nil {
|
||||
return
|
||||
}
|
||||
@@ -128,7 +121,7 @@ func (p *Progress) AddSkippedFile(name string, size uint64) {
|
||||
p.s.FilesSkipped++
|
||||
p.s.AllBytesSkipped += size
|
||||
|
||||
p.printer.CompleteItem(ActionFileUnchanged, name, size)
|
||||
p.printer.CompleteItem(restorer.ActionFileUnchanged, name, size)
|
||||
}
|
||||
|
||||
func (p *Progress) ReportDeletion(name string) {
|
||||
@@ -141,7 +134,7 @@ func (p *Progress) ReportDeletion(name string) {
|
||||
|
||||
p.s.FilesDeleted++
|
||||
|
||||
p.printer.CompleteItem(ActionDeleted, name, 0)
|
||||
p.printer.CompleteItem(restorer.ActionDeleted, name, 0)
|
||||
}
|
||||
|
||||
func (p *Progress) Error(item string, err error) error {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/restic/restic/internal/errors"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
"github.com/restic/restic/internal/restorer"
|
||||
"github.com/restic/restic/internal/test"
|
||||
)
|
||||
|
||||
@@ -19,7 +20,7 @@ type printerTraceEntry struct {
|
||||
type printerTrace []printerTraceEntry
|
||||
|
||||
type itemTraceEntry struct {
|
||||
action ItemAction
|
||||
action restorer.ItemAction
|
||||
item string
|
||||
size uint64
|
||||
}
|
||||
@@ -49,7 +50,7 @@ func (p *mockPrinter) Error(item string, err error) error {
|
||||
p.errors = append(p.errors, errorTraceEntry{item, err})
|
||||
return nil
|
||||
}
|
||||
func (p *mockPrinter) CompleteItem(action ItemAction, item string, size uint64) {
|
||||
func (p *mockPrinter) CompleteItem(action restorer.ItemAction, item string, size uint64) {
|
||||
p.items = append(p.items, itemTraceEntry{action, item, size})
|
||||
}
|
||||
func (p *mockPrinter) Finish(progress State, _ time.Duration) {
|
||||
@@ -98,7 +99,7 @@ func TestFirstProgressOnAFile(t *testing.T) {
|
||||
|
||||
result, items, _ := testProgress(func(progress *Progress) bool {
|
||||
progress.AddFile(expectedBytesTotal)
|
||||
progress.AddProgress("test", ActionFileUpdated, expectedBytesWritten, expectedBytesTotal)
|
||||
progress.AddProgress("test", restorer.ActionFileUpdated, expectedBytesWritten, expectedBytesTotal)
|
||||
return false
|
||||
})
|
||||
test.Equals(t, printerTrace{
|
||||
@@ -112,16 +113,16 @@ func TestLastProgressOnAFile(t *testing.T) {
|
||||
|
||||
result, items, _ := testProgress(func(progress *Progress) bool {
|
||||
progress.AddFile(fileSize)
|
||||
progress.AddProgress("test", ActionFileUpdated, 30, fileSize)
|
||||
progress.AddProgress("test", ActionFileUpdated, 35, fileSize)
|
||||
progress.AddProgress("test", ActionFileUpdated, 35, fileSize)
|
||||
progress.AddProgress("test", restorer.ActionFileUpdated, 30, fileSize)
|
||||
progress.AddProgress("test", restorer.ActionFileUpdated, 35, fileSize)
|
||||
progress.AddProgress("test", restorer.ActionFileUpdated, 35, fileSize)
|
||||
return false
|
||||
})
|
||||
test.Equals(t, printerTrace{
|
||||
printerTraceEntry{State{1, 1, 0, 0, fileSize, fileSize, 0}, 0, false},
|
||||
}, result)
|
||||
test.Equals(t, itemTrace{
|
||||
itemTraceEntry{action: ActionFileUpdated, item: "test", size: fileSize},
|
||||
itemTraceEntry{action: restorer.ActionFileUpdated, item: "test", size: fileSize},
|
||||
}, items)
|
||||
}
|
||||
|
||||
@@ -131,17 +132,17 @@ func TestLastProgressOnLastFile(t *testing.T) {
|
||||
result, items, _ := testProgress(func(progress *Progress) bool {
|
||||
progress.AddFile(fileSize)
|
||||
progress.AddFile(50)
|
||||
progress.AddProgress("test1", ActionFileUpdated, 50, 50)
|
||||
progress.AddProgress("test2", ActionFileUpdated, 50, fileSize)
|
||||
progress.AddProgress("test2", ActionFileUpdated, 50, fileSize)
|
||||
progress.AddProgress("test1", restorer.ActionFileUpdated, 50, 50)
|
||||
progress.AddProgress("test2", restorer.ActionFileUpdated, 50, fileSize)
|
||||
progress.AddProgress("test2", restorer.ActionFileUpdated, 50, fileSize)
|
||||
return false
|
||||
})
|
||||
test.Equals(t, printerTrace{
|
||||
printerTraceEntry{State{2, 2, 0, 0, 50 + fileSize, 50 + fileSize, 0}, 0, false},
|
||||
}, result)
|
||||
test.Equals(t, itemTrace{
|
||||
itemTraceEntry{action: ActionFileUpdated, item: "test1", size: 50},
|
||||
itemTraceEntry{action: ActionFileUpdated, item: "test2", size: fileSize},
|
||||
itemTraceEntry{action: restorer.ActionFileUpdated, item: "test1", size: 50},
|
||||
itemTraceEntry{action: restorer.ActionFileUpdated, item: "test2", size: fileSize},
|
||||
}, items)
|
||||
}
|
||||
|
||||
@@ -151,8 +152,8 @@ func TestSummaryOnSuccess(t *testing.T) {
|
||||
result, _, _ := testProgress(func(progress *Progress) bool {
|
||||
progress.AddFile(fileSize)
|
||||
progress.AddFile(50)
|
||||
progress.AddProgress("test1", ActionFileUpdated, 50, 50)
|
||||
progress.AddProgress("test2", ActionFileUpdated, fileSize, fileSize)
|
||||
progress.AddProgress("test1", restorer.ActionFileUpdated, 50, 50)
|
||||
progress.AddProgress("test2", restorer.ActionFileUpdated, fileSize, fileSize)
|
||||
return true
|
||||
})
|
||||
test.Equals(t, printerTrace{
|
||||
@@ -166,8 +167,8 @@ func TestSummaryOnErrors(t *testing.T) {
|
||||
result, _, _ := testProgress(func(progress *Progress) bool {
|
||||
progress.AddFile(fileSize)
|
||||
progress.AddFile(50)
|
||||
progress.AddProgress("test1", ActionFileUpdated, 50, 50)
|
||||
progress.AddProgress("test2", ActionFileUpdated, fileSize/2, fileSize)
|
||||
progress.AddProgress("test1", restorer.ActionFileUpdated, 50, 50)
|
||||
progress.AddProgress("test2", restorer.ActionFileUpdated, fileSize/2, fileSize)
|
||||
return true
|
||||
})
|
||||
test.Equals(t, printerTrace{
|
||||
@@ -186,7 +187,7 @@ func TestSkipFile(t *testing.T) {
|
||||
printerTraceEntry{State{0, 0, 1, 0, 0, 0, fileSize}, mockFinishDuration, true},
|
||||
}, result)
|
||||
test.Equals(t, itemTrace{
|
||||
itemTraceEntry{ActionFileUnchanged, "test", fileSize},
|
||||
itemTraceEntry{restorer.ActionFileUnchanged, "test", fileSize},
|
||||
}, items)
|
||||
}
|
||||
|
||||
@@ -196,15 +197,15 @@ func TestProgressTypes(t *testing.T) {
|
||||
_, items, _ := testProgress(func(progress *Progress) bool {
|
||||
progress.AddFile(fileSize)
|
||||
progress.AddFile(0)
|
||||
progress.AddProgress("dir", ActionDirRestored, fileSize, fileSize)
|
||||
progress.AddProgress("new", ActionFileRestored, 0, 0)
|
||||
progress.AddProgress("dir", restorer.ActionDirRestored, fileSize, fileSize)
|
||||
progress.AddProgress("new", restorer.ActionFileRestored, 0, 0)
|
||||
progress.ReportDeletion("del")
|
||||
return true
|
||||
})
|
||||
test.Equals(t, itemTrace{
|
||||
itemTraceEntry{ActionDirRestored, "dir", fileSize},
|
||||
itemTraceEntry{ActionFileRestored, "new", 0},
|
||||
itemTraceEntry{ActionDeleted, "del", 0},
|
||||
itemTraceEntry{restorer.ActionDirRestored, "dir", fileSize},
|
||||
itemTraceEntry{restorer.ActionFileRestored, "new", 0},
|
||||
itemTraceEntry{restorer.ActionDeleted, "del", 0},
|
||||
}, items)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/restic/restic/internal/restic"
|
||||
"github.com/restic/restic/internal/restorer"
|
||||
"github.com/restic/restic/internal/ui"
|
||||
"github.com/restic/restic/internal/ui/progress"
|
||||
)
|
||||
@@ -44,26 +45,26 @@ func (t *textPrinter) Error(item string, err error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *textPrinter) CompleteItem(messageType ItemAction, item string, size uint64) {
|
||||
func (t *textPrinter) CompleteItem(messageType restorer.ItemAction, item string, size uint64) {
|
||||
var action string
|
||||
switch messageType {
|
||||
case ActionDirRestored:
|
||||
case restorer.ActionDirRestored:
|
||||
action = "restored"
|
||||
case ActionFileRestored:
|
||||
case restorer.ActionFileRestored:
|
||||
action = "restored"
|
||||
case ActionOtherRestored:
|
||||
case restorer.ActionOtherRestored:
|
||||
action = "restored"
|
||||
case ActionFileUpdated:
|
||||
case restorer.ActionFileUpdated:
|
||||
action = "updated"
|
||||
case ActionFileUnchanged:
|
||||
case restorer.ActionFileUnchanged:
|
||||
action = "unchanged"
|
||||
case ActionDeleted:
|
||||
case restorer.ActionDeleted:
|
||||
action = "deleted"
|
||||
default:
|
||||
panic("unknown message type")
|
||||
}
|
||||
|
||||
if messageType == ActionDirRestored || messageType == ActionOtherRestored || messageType == ActionDeleted {
|
||||
if messageType == restorer.ActionDirRestored || messageType == restorer.ActionOtherRestored || messageType == restorer.ActionDeleted {
|
||||
t.VV("%-9v %v", action, item)
|
||||
} else {
|
||||
t.VV("%-9v %v with size %v", action, item, ui.FormatBytes(size))
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/restic/restic/internal/errors"
|
||||
"github.com/restic/restic/internal/restorer"
|
||||
"github.com/restic/restic/internal/test"
|
||||
"github.com/restic/restic/internal/ui"
|
||||
)
|
||||
@@ -47,16 +48,16 @@ func TestPrintSummaryOnSuccessWithSkipped(t *testing.T) {
|
||||
|
||||
func TestPrintCompleteItem(t *testing.T) {
|
||||
for _, data := range []struct {
|
||||
action ItemAction
|
||||
action restorer.ItemAction
|
||||
size uint64
|
||||
expected string
|
||||
}{
|
||||
{ActionDirRestored, 0, "restored test"},
|
||||
{ActionFileRestored, 123, "restored test with size 123 B"},
|
||||
{ActionOtherRestored, 0, "restored test"},
|
||||
{ActionFileUpdated, 123, "updated test with size 123 B"},
|
||||
{ActionFileUnchanged, 123, "unchanged test with size 123 B"},
|
||||
{ActionDeleted, 0, "deleted test"},
|
||||
{restorer.ActionDirRestored, 0, "restored test"},
|
||||
{restorer.ActionFileRestored, 123, "restored test with size 123 B"},
|
||||
{restorer.ActionOtherRestored, 0, "restored test"},
|
||||
{restorer.ActionFileUpdated, 123, "updated test with size 123 B"},
|
||||
{restorer.ActionFileUnchanged, 123, "unchanged test with size 123 B"},
|
||||
{restorer.ActionDeleted, 0, "deleted test"},
|
||||
} {
|
||||
term, printer := createTextProgress()
|
||||
printer.CompleteItem(data.action, "test", data.size)
|
||||
|
||||
Reference in New Issue
Block a user