github.com/Files-com/files-sdk-go/v3@v3.1.81/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/v3"
    14  	"github.com/Files-com/files-sdk-go/v3/file/manager"
    15  	"github.com/Files-com/files-sdk-go/v3/file/status"
    16  	"github.com/Files-com/files-sdk-go/v3/ignore"
    17  	"github.com/Files-com/files-sdk-go/v3/lib"
    18  	"github.com/Files-com/files-sdk-go/v3/lib/direction"
    19  	"github.com/Files-com/files-sdk-go/v3/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 *Job) {
    28  				events := EventsReporter{}
    29  				eventsMutex := sync.Mutex{}
    30  				var retryingEvents []status.Status
    31  				job.RegisterFileEvent(func(file JobFile) {
    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 *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 *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("uploads", func(t *testing.T) {
    75  		t.Run("RetryAll RetryCount 1", func(t *testing.T) {
    76  			buildUploadTest(func(job *Job, _ *MockUploader) {
    77  				RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryAll, RetryCount: 1}, false)
    78  				assert.Equal(true, job.All(status.Complete))
    79  			})
    80  		})
    81  
    82  		t.Run("RetryUnfinished RetryCount 1", func(t *testing.T) {
    83  			buildUploadTest(func(job *Job, _ *MockUploader) {
    84  				RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryUnfinished, RetryCount: 1}, false)
    85  				assert.Equal(false, job.All(status.Complete))
    86  				assert.Equal(2, job.Count(status.Complete))
    87  				assert.Equal(1, job.Count(status.Queued))
    88  				assert.Equal(false, job.Running(), "does change the original time")
    89  			})
    90  		})
    91  
    92  		t.Run("RetryUnfinished RetryCount 2", func(t *testing.T) {
    93  			buildUploadTest(func(job *Job, uploader *MockUploader) {
    94  				uploader.uploadError = fmt.Errorf("bad things")
    95  				RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryUnfinished, RetryCount: 2, Backoff: -1}, false)
    96  				assert.Equal(false, job.All(status.Complete))
    97  				assert.Equal(1, job.Count(status.Complete))
    98  				assert.Equal(2, job.Count(status.Errored))
    99  				assert.Equal(false, job.Running(), "does change the original time")
   100  			}, status.Errored, status.Errored, status.Complete)
   101  		})
   102  
   103  		t.Run("RetryUnfinished RetryCount 1", func(t *testing.T) {
   104  			buildUploadTest(func(job *Job, _ *MockUploader) {
   105  				startTime := time.Now().AddDate(0, -1, 0)
   106  				endTime := time.Now().AddDate(0, -1, 0)
   107  				job.Timer.Runs = timer.Runs{timer.Run{
   108  					Start:  startTime,
   109  					Finish: endTime,
   110  				}}
   111  				uploadStatusErrored := job.Statuses[0].(*UploadStatus)
   112  				uploadStatusErrored.status = status.Complete
   113  				RetryByPolicy(context.Background(), job, RetryPolicy{Type: RetryUnfinished, RetryCount: 1}, false)
   114  				assert.Equal(false, job.All(status.Complete))
   115  				assert.Equal(2, job.Count(status.Complete))
   116  				assert.Equal(1, job.Count(status.Queued))
   117  				assert.Equal(startTime, job.StartTime(), "does not change the original time")
   118  				assert.Equal(endTime, job.FinishTime(), "does not change the original time")
   119  			})
   120  		})
   121  	})
   122  }
   123  
   124  func buildDownloadTest(test func(*Job)) {
   125  	job := (&Job{Direction: direction.DownloadType, Manager: manager.Default(), Config: files_sdk.Config{}.Init(), Logger: lib.NullLogger{}}).Init()
   126  	temps := make([]string, 3)
   127  	statuses := []status.Status{status.Errored, status.Complete, status.Queued}
   128  	tmpDir, err := ioutil.TempDir(os.TempDir(), "client_test")
   129  	if err != nil {
   130  		log.Fatal(err)
   131  	}
   132  	for i, s := range statuses {
   133  		tempFile, err := ioutil.TempFile(tmpDir, fmt.Sprintf("%v.txt", i))
   134  		if err != nil {
   135  			panic(err)
   136  		}
   137  		_, err = tempFile.Write([]byte("taco"))
   138  		if err != nil {
   139  			panic(err)
   140  		}
   141  		temps = append(temps, tempFile.Name())
   142  		localFile, err := os.Open(tempFile.Name())
   143  		if err != nil {
   144  			panic(err)
   145  		}
   146  		tempFile.Close()
   147  		job.Add(&DownloadStatus{Mutex: &sync.RWMutex{}, localPath: tempFile.Name(), fsFile: localFile, status: s, job: job, file: files_sdk.File{DisplayName: fmt.Sprintf("%v.txt", i)}})
   148  	}
   149  
   150  	test(job)
   151  
   152  	for _, tmp := range temps {
   153  		os.Remove(tmp)
   154  	}
   155  	os.RemoveAll(tmpDir)
   156  }
   157  
   158  func buildUploadTest(test func(*Job, *MockUploader), statuses ...status.Status) {
   159  	job := (&Job{Direction: direction.UploadType, Manager: manager.Default(), Params: UploaderParams{}, Config: files_sdk.Config{}.Init(), Logger: lib.NullLogger{}}).Init()
   160  	job.Ignore, _ = ignore.New()
   161  	var temps []string
   162  	if len(statuses) == 0 {
   163  		statuses = []status.Status{status.Errored, status.Complete, status.Queued}
   164  	}
   165  	uploader := &MockUploader{}
   166  	tmpDir, err := ioutil.TempDir(os.TempDir(), "retrytransfers")
   167  	if err != nil {
   168  		log.Fatal(err)
   169  	}
   170  	for i, s := range statuses {
   171  		tempFile, err := ioutil.TempFile(tmpDir, fmt.Sprintf("%v.txt", i))
   172  		if err != nil {
   173  			panic(err)
   174  		}
   175  		_, err = tempFile.Write([]byte("taco"))
   176  		if err != nil {
   177  			panic(err)
   178  		}
   179  		temps = append(temps, tempFile.Name())
   180  		tempFile.Close()
   181  		job.Add(&UploadStatus{Mutex: &sync.RWMutex{}, Uploader: uploader, localPath: tempFile.Name(), status: s, job: job, file: files_sdk.File{DisplayName: fmt.Sprintf("%v.txt", i), Mtime: lib.Time(time.Now())}})
   182  	}
   183  
   184  	test(job, uploader)
   185  
   186  	for _, tmp := range temps {
   187  		os.Remove(tmp)
   188  	}
   189  	if err := os.RemoveAll(tmpDir); err != nil {
   190  		panic(err)
   191  	}
   192  }