github.com/Files-com/files-sdk-go/v2@v2.1.2/file/retrytransfers_test.go (about) 1 package file 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "log" 8 "os" 9 "sync" 10 "testing" 11 "time" 12 13 files_sdk "github.com/Files-com/files-sdk-go/v2" 14 "github.com/Files-com/files-sdk-go/v2/file/manager" 15 "github.com/Files-com/files-sdk-go/v2/file/status" 16 "github.com/Files-com/files-sdk-go/v2/ignore" 17 "github.com/Files-com/files-sdk-go/v2/lib" 18 "github.com/Files-com/files-sdk-go/v2/lib/direction" 19 "github.com/Files-com/files-sdk-go/v2/lib/timer" 20 "github.com/stretchr/testify/assert" 21 ) 22 23 func TestRetryTransfers(t *testing.T) { 24 assert := assert.New(t) 25 t.Run("downloads", func(t *testing.T) { 26 t.Run("RetryAll RetryCount 1", func(t *testing.T) { 27 buildDownloadTest(func(job *status.Job) { 28 events := status.EventsReporter{} 29 eventsMutex := sync.Mutex{} 30 var retryingEvents []status.Status 31 job.RegisterFileEvent(func(file status.File) { 32 eventsMutex.Lock() 33 defer eventsMutex.Unlock() 34 retryingEvents = append(retryingEvents, file.Status) 35 }, status.Retrying) 36 job.SetEventsReporter(events) 37 RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryAll, RetryCount: 1}, false) 38 assert.Equal(true, job.All(status.Complete)) 39 assert.Equal(3, len(retryingEvents), "sets a retrying status before starting") 40 }) 41 }) 42 43 t.Run("RetryUnfinished RetryCount 1", func(t *testing.T) { 44 buildDownloadTest(func(job *status.Job) { 45 job.Start(false) 46 RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryUnfinished, RetryCount: 1}, false) 47 assert.Equal(false, job.All(status.Complete)) 48 assert.Equal(2, job.Count(status.Complete)) 49 assert.Equal(1, job.Count(status.Queued)) 50 assert.Equal(true, job.Started.Called()) 51 assert.Equal(false, job.Scanning.Called()) 52 assert.Equal(false, job.EndScanning.Called()) 53 assert.Equal(false, job.Finished.Called()) 54 job.Finish() 55 }) 56 }) 57 58 t.Run("RetryUnfinished RetryCount 1 signalEvents true", func(t *testing.T) { 59 buildDownloadTest(func(job *status.Job) { 60 job.Start() 61 job.Finish() // Finish already called, this happens in the desktop app 62 RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryUnfinished, RetryCount: 1}, true) 63 assert.Equal(false, job.All(status.Complete)) 64 assert.Equal(2, job.Count(status.Complete)) 65 assert.Equal(1, job.Count(status.Queued)) 66 67 assert.Equal(true, job.Started.Called()) 68 assert.Equal(true, job.Scanning.Called()) 69 assert.Equal(true, job.EndScanning.Called()) 70 assert.Equal(true, job.Finished.Called()) 71 }) 72 }) 73 74 t.Run("RetryErroredIfSomeCompleted RetryCount 1", func(t *testing.T) { 75 buildDownloadTest(func(job *status.Job) { 76 RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryErroredIfSomeCompleted, RetryCount: 1}, false) 77 assert.Equal(false, job.All(status.Complete)) 78 assert.Equal(2, job.Count(status.Complete)) 79 assert.Equal(1, job.Count(status.Queued)) 80 }) 81 }) 82 83 t.Run("RetryErroredIfSomeCompleted RetryCount 1", func(t *testing.T) { 84 buildDownloadTest(func(job *status.Job) { 85 job.Statuses[0].(*DownloadStatus).lastByte = time.Time{} 86 job.Statuses[1].(*DownloadStatus).lastByte = time.Time{} 87 job.Statuses[2].(*DownloadStatus).lastByte = time.Time{} 88 RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryErroredIfSomeCompleted, RetryCount: 1}, false) 89 assert.Equal(1, job.Count(status.Complete)) 90 assert.Equal(1, job.Count(status.Queued)) 91 assert.Equal(1, job.Count(status.Errored), "is not retried because completed happened before this error not after") 92 }) 93 }) 94 }) 95 t.Run("uploads", func(t *testing.T) { 96 t.Run("RetryAll RetryCount 1", func(t *testing.T) { 97 buildUploadTest(func(job *status.Job, _ *MockUploader) { 98 RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryAll, RetryCount: 1}, false) 99 assert.Equal(true, job.All(status.Complete)) 100 }) 101 }) 102 103 t.Run("RetryUnfinished RetryCount 1", func(t *testing.T) { 104 buildUploadTest(func(job *status.Job, _ *MockUploader) { 105 RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryUnfinished, RetryCount: 1}, false) 106 assert.Equal(false, job.All(status.Complete)) 107 assert.Equal(2, job.Count(status.Complete)) 108 assert.Equal(1, job.Count(status.Queued)) 109 assert.Equal(false, job.Running(), "does change the original time") 110 }) 111 }) 112 113 t.Run("RetryUnfinished RetryCount 2", func(t *testing.T) { 114 buildUploadTest(func(job *status.Job, uploader *MockUploader) { 115 uploader.uploadError = fmt.Errorf("bad things") 116 RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryUnfinished, RetryCount: 2, Backoff: -1}, false) 117 assert.Equal(false, job.All(status.Complete)) 118 assert.Equal(1, job.Count(status.Complete)) 119 assert.Equal(2, job.Count(status.Errored)) 120 assert.Equal(false, job.Running(), "does change the original time") 121 }, status.Errored, status.Errored, status.Complete) 122 }) 123 124 t.Run("RetryUnfinished RetryCount 1", func(t *testing.T) { 125 buildUploadTest(func(job *status.Job, _ *MockUploader) { 126 startTime := time.Now().AddDate(0, -1, 0) 127 endTime := time.Now().AddDate(0, -1, 0) 128 job.Timer.Runs = timer.Runs{timer.Run{ 129 Start: startTime, 130 Finish: endTime, 131 }} 132 uploadStatusErrored := job.Statuses[0].(*UploadStatus) 133 uploadStatusErrored.status = status.Complete 134 RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryUnfinished, RetryCount: 1}, false) 135 assert.Equal(false, job.All(status.Complete)) 136 assert.Equal(2, job.Count(status.Complete)) 137 assert.Equal(1, job.Count(status.Queued)) 138 assert.Equal(startTime, job.StartTime(), "does not change the original time") 139 assert.Equal(endTime, job.FinishTime(), "does not change the original time") 140 }) 141 }) 142 }) 143 } 144 145 func buildDownloadTest(test func(*status.Job)) { 146 job := (&status.Job{Direction: direction.DownloadType, Manager: manager.Default(), Config: files_sdk.Config{}, Logger: (&files_sdk.Config{}).Logger()}).Init() 147 temps := make([]string, 3) 148 statuses := []status.Status{status.Errored, status.Complete, status.Queued} 149 tmpDir, err := ioutil.TempDir(os.TempDir(), "client_test") 150 if err != nil { 151 log.Fatal(err) 152 } 153 for i, s := range statuses { 154 tempFile, err := ioutil.TempFile(tmpDir, fmt.Sprintf("%v.txt", i)) 155 if err != nil { 156 panic(err) 157 } 158 _, err = tempFile.Write([]byte("taco")) 159 if err != nil { 160 panic(err) 161 } 162 temps = append(temps, tempFile.Name()) 163 localFile, err := os.Open(tempFile.Name()) 164 if err != nil { 165 panic(err) 166 } 167 tempFile.Close() 168 job.Add(&DownloadStatus{Mutex: &sync.RWMutex{}, lastByte: time.Now(), localPath: tempFile.Name(), fsFile: localFile, status: s, job: job, file: files_sdk.File{DisplayName: fmt.Sprintf("%v.txt", i)}}) 169 } 170 171 test(job) 172 173 for _, tmp := range temps { 174 os.Remove(tmp) 175 } 176 os.RemoveAll(tmpDir) 177 } 178 179 func buildUploadTest(test func(*status.Job, *MockUploader), statuses ...status.Status) { 180 job := (&status.Job{Direction: direction.UploadType, Manager: manager.Default(), Params: UploaderParams{}, Config: files_sdk.Config{}, Logger: (&files_sdk.Config{}).Logger()}).Init() 181 job.Ignore, _ = ignore.New() 182 var temps []string 183 if len(statuses) == 0 { 184 statuses = []status.Status{status.Errored, status.Complete, status.Queued} 185 } 186 uploader := &MockUploader{} 187 tmpDir, err := ioutil.TempDir(os.TempDir(), "retrytransfers") 188 if err != nil { 189 log.Fatal(err) 190 } 191 for i, s := range statuses { 192 tempFile, err := ioutil.TempFile(tmpDir, fmt.Sprintf("%v.txt", i)) 193 if err != nil { 194 panic(err) 195 } 196 _, err = tempFile.Write([]byte("taco")) 197 if err != nil { 198 panic(err) 199 } 200 temps = append(temps, tempFile.Name()) 201 tempFile.Close() 202 job.Add(&UploadStatus{Mutex: &sync.RWMutex{}, Uploader: uploader, lastByte: time.Now(), localPath: tempFile.Name(), status: s, job: job, file: files_sdk.File{DisplayName: fmt.Sprintf("%v.txt", i), Mtime: lib.Time(time.Now())}}) 203 } 204 205 test(job, uploader) 206 207 for _, tmp := range temps { 208 os.Remove(tmp) 209 } 210 if err := os.RemoveAll(tmpDir); err != nil { 211 panic(err) 212 } 213 }