github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/fs/accounting/stats_test.go (about) 1 package accounting 2 3 import ( 4 "fmt" 5 "io" 6 "testing" 7 "time" 8 9 "github.com/ncw/rclone/fs/fserrors" 10 "github.com/pkg/errors" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestETA(t *testing.T) { 15 for _, test := range []struct { 16 size, total int64 17 rate float64 18 wantETA time.Duration 19 wantOK bool 20 wantString string 21 }{ 22 // Custom String Cases 23 {size: 0, total: 365 * 86400, rate: 1.0, wantETA: 365 * 86400 * time.Second, wantOK: true, wantString: "1y"}, 24 {size: 0, total: 7 * 86400, rate: 1.0, wantETA: 7 * 86400 * time.Second, wantOK: true, wantString: "1w"}, 25 {size: 0, total: 1 * 86400, rate: 1.0, wantETA: 1 * 86400 * time.Second, wantOK: true, wantString: "1d"}, 26 {size: 0, total: 1110 * 86400, rate: 1.0, wantETA: 1110 * 86400 * time.Second, wantOK: true, wantString: "3y2w1d"}, 27 {size: 0, total: 15 * 86400, rate: 1.0, wantETA: 15 * 86400 * time.Second, wantOK: true, wantString: "2w1d"}, 28 // Composite Custom String Cases 29 {size: 0, total: 1.5 * 86400, rate: 1.0, wantETA: 1.5 * 86400 * time.Second, wantOK: true, wantString: "1d12h"}, 30 {size: 0, total: 95000, rate: 1.0, wantETA: 95000 * time.Second, wantOK: true, wantString: "1d2h23m20s"}, 31 // Standard Duration String Cases 32 {size: 0, total: 100, rate: 1.0, wantETA: 100 * time.Second, wantOK: true, wantString: "1m40s"}, 33 {size: 50, total: 100, rate: 1.0, wantETA: 50 * time.Second, wantOK: true, wantString: "50s"}, 34 {size: 100, total: 100, rate: 1.0, wantETA: 0 * time.Second, wantOK: true, wantString: "0s"}, 35 // No String Cases 36 {size: -1, total: 100, rate: 1.0, wantETA: 0, wantOK: false, wantString: "-"}, 37 {size: 200, total: 100, rate: 1.0, wantETA: 0, wantOK: false, wantString: "-"}, 38 {size: 10, total: -1, rate: 1.0, wantETA: 0, wantOK: false, wantString: "-"}, 39 {size: 10, total: 20, rate: 0.0, wantETA: 0, wantOK: false, wantString: "-"}, 40 {size: 10, total: 20, rate: -1.0, wantETA: 0, wantOK: false, wantString: "-"}, 41 {size: 0, total: 0, rate: 1.0, wantETA: 0, wantOK: false, wantString: "-"}, 42 } { 43 t.Run(fmt.Sprintf("size=%d/total=%d/rate=%f", test.size, test.total, test.rate), func(t *testing.T) { 44 gotETA, gotOK := eta(test.size, test.total, test.rate) 45 assert.Equal(t, test.wantETA, gotETA) 46 assert.Equal(t, test.wantOK, gotOK) 47 gotString := etaString(test.size, test.total, test.rate) 48 assert.Equal(t, test.wantString, gotString) 49 }) 50 } 51 } 52 53 func TestPercentage(t *testing.T) { 54 assert.Equal(t, percent(0, 1000), "0%") 55 assert.Equal(t, percent(1, 1000), "0%") 56 assert.Equal(t, percent(9, 1000), "1%") 57 assert.Equal(t, percent(500, 1000), "50%") 58 assert.Equal(t, percent(1000, 1000), "100%") 59 assert.Equal(t, percent(1E8, 1E9), "10%") 60 assert.Equal(t, percent(1E8, 1E9), "10%") 61 assert.Equal(t, percent(0, 0), "-") 62 assert.Equal(t, percent(100, -100), "-") 63 assert.Equal(t, percent(-100, 100), "-") 64 assert.Equal(t, percent(-100, -100), "-") 65 } 66 67 func TestStatsError(t *testing.T) { 68 s := NewStats() 69 assert.Equal(t, int64(0), s.GetErrors()) 70 assert.False(t, s.HadFatalError()) 71 assert.False(t, s.HadRetryError()) 72 assert.Equal(t, time.Time{}, s.RetryAfter()) 73 assert.Equal(t, nil, s.GetLastError()) 74 assert.False(t, s.Errored()) 75 76 t0 := time.Now() 77 t1 := t0.Add(time.Second) 78 79 s.Error(nil) 80 assert.Equal(t, int64(0), s.GetErrors()) 81 assert.False(t, s.HadFatalError()) 82 assert.False(t, s.HadRetryError()) 83 assert.Equal(t, time.Time{}, s.RetryAfter()) 84 assert.Equal(t, nil, s.GetLastError()) 85 assert.False(t, s.Errored()) 86 87 s.Error(io.EOF) 88 assert.Equal(t, int64(1), s.GetErrors()) 89 assert.False(t, s.HadFatalError()) 90 assert.True(t, s.HadRetryError()) 91 assert.Equal(t, time.Time{}, s.RetryAfter()) 92 assert.Equal(t, io.EOF, s.GetLastError()) 93 assert.True(t, s.Errored()) 94 95 e := fserrors.ErrorRetryAfter(t0) 96 s.Error(e) 97 assert.Equal(t, int64(2), s.GetErrors()) 98 assert.False(t, s.HadFatalError()) 99 assert.True(t, s.HadRetryError()) 100 assert.Equal(t, t0, s.RetryAfter()) 101 assert.Equal(t, e, s.GetLastError()) 102 103 err := errors.Wrap(fserrors.ErrorRetryAfter(t1), "potato") 104 s.Error(err) 105 assert.Equal(t, int64(3), s.GetErrors()) 106 assert.False(t, s.HadFatalError()) 107 assert.True(t, s.HadRetryError()) 108 assert.Equal(t, t1, s.RetryAfter()) 109 assert.Equal(t, t1, fserrors.RetryAfterErrorTime(err)) 110 111 s.Error(fserrors.FatalError(io.EOF)) 112 assert.Equal(t, int64(4), s.GetErrors()) 113 assert.True(t, s.HadFatalError()) 114 assert.True(t, s.HadRetryError()) 115 assert.Equal(t, t1, s.RetryAfter()) 116 117 s.ResetErrors() 118 assert.Equal(t, int64(0), s.GetErrors()) 119 assert.False(t, s.HadFatalError()) 120 assert.False(t, s.HadRetryError()) 121 assert.Equal(t, time.Time{}, s.RetryAfter()) 122 assert.Equal(t, nil, s.GetLastError()) 123 assert.False(t, s.Errored()) 124 125 s.Error(fserrors.NoRetryError(io.EOF)) 126 assert.Equal(t, int64(1), s.GetErrors()) 127 assert.False(t, s.HadFatalError()) 128 assert.False(t, s.HadRetryError()) 129 assert.Equal(t, time.Time{}, s.RetryAfter()) 130 }