github.com/jstaf/onedriver@v0.14.2-0.20240420231225-f07678f9e6ef/fs/upload_manager_test.go (about)

     1  package fs
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/jstaf/onedriver/fs/graph"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  	bolt "go.etcd.io/bbolt"
    18  )
    19  
    20  // Test that new uploads are written to disk to support resuming them later if
    21  // the user shuts down their computer.
    22  func TestUploadDiskSerialization(t *testing.T) {
    23  	t.Parallel()
    24  	// write a file and get its id - we do this as a goroutine because uploads are
    25  	// blocking now
    26  	go exec.Command("cp", "dmel.fa", filepath.Join(TestDir, "upload_to_disk.fa")).Run()
    27  	time.Sleep(time.Second)
    28  	inode, err := fs.GetPath("/onedriver_tests/upload_to_disk.fa", nil)
    29  	require.NoError(t, err)
    30  
    31  	// we can find the in-progress upload because there is a several second
    32  	// delay on new uploads
    33  	session := UploadSession{}
    34  	err = fs.db.Batch(func(tx *bolt.Tx) error {
    35  		b, _ := tx.CreateBucketIfNotExists(bucketUploads)
    36  		diskSession := b.Get([]byte(inode.ID()))
    37  		if diskSession == nil {
    38  			return errors.New("item to upload not found on disk")
    39  		}
    40  		return json.Unmarshal(diskSession, &session)
    41  	})
    42  	if err != nil {
    43  		t.Log(err)
    44  		t.Log("This test sucks and should be rewritten to be less race-y!")
    45  		t.SkipNow()
    46  	}
    47  
    48  	// kill the session before it gets uploaded
    49  	fs.uploads.CancelUpload(session.ID)
    50  
    51  	// confirm that the file didn't get uploaded yet (just in case!)
    52  	driveItem, err := graph.GetItemPath("/onedriver_tests/upload_to_disk.fa", auth)
    53  	if err == nil || driveItem != nil {
    54  		if driveItem.Size > 0 {
    55  			t.Fatal("This test should be rewritten, the file was uploaded before " +
    56  				"the upload could be canceled.")
    57  		}
    58  	}
    59  
    60  	// now we create a new UploadManager from scratch, with the file injected
    61  	// into its db and confirm that the file gets uploaded
    62  	db, err := bolt.Open(filepath.Join(testDBLoc, "test_upload_disk_serialization.db"), 0644, nil)
    63  	require.NoError(t, err)
    64  	db.Update(func(tx *bolt.Tx) error {
    65  		b, _ := tx.CreateBucket(bucketUploads)
    66  		payload, _ := json.Marshal(&session)
    67  		return b.Put([]byte(session.ID), payload)
    68  	})
    69  
    70  	NewUploadManager(time.Second, db, fs, auth)
    71  	assert.Eventually(t, func() bool {
    72  		driveItem, err = graph.GetItemPath("/onedriver_tests/upload_to_disk.fa", auth)
    73  		if driveItem != nil && err == nil {
    74  			return true
    75  		}
    76  		return false
    77  	}, 100*time.Second, 5*time.Second,
    78  		"Could not find uploaded file after unserializing from disk and resuming upload.",
    79  	)
    80  }
    81  
    82  // Make sure that uploading the same file multiple times works exactly as it should.
    83  func TestRepeatedUploads(t *testing.T) {
    84  	t.Parallel()
    85  
    86  	// test setup
    87  	fname := filepath.Join(TestDir, "repeated_upload.txt")
    88  	require.NoError(t, ioutil.WriteFile(fname, []byte("initial content"), 0644))
    89  	var inode *Inode
    90  	require.Eventually(t, func() bool {
    91  		inode, _ = fs.GetPath("/onedriver_tests/repeated_upload.txt", auth)
    92  		return !isLocalID(inode.ID())
    93  	}, retrySeconds, 2*time.Second, "ID was local after upload.")
    94  
    95  	for i := 0; i < 5; i++ {
    96  		uploadme := []byte(fmt.Sprintf("iteration: %d", i))
    97  		require.NoError(t, ioutil.WriteFile(fname, uploadme, 0644))
    98  
    99  		time.Sleep(5 * time.Second)
   100  
   101  		item, err := graph.GetItemPath("/onedriver_tests/repeated_upload.txt", auth)
   102  		require.NoError(t, err)
   103  
   104  		content, _, err := graph.GetItemContent(item.ID, auth)
   105  		require.NoError(t, err)
   106  
   107  		if !bytes.Equal(content, uploadme) {
   108  			// wait and retry once
   109  			time.Sleep(5 * time.Second)
   110  			content, _, err := graph.GetItemContent(item.ID, auth)
   111  			require.NoError(t, err)
   112  			if !bytes.Equal(content, uploadme) {
   113  				t.Fatalf("Upload failed - got \"%s\", wanted \"%s\"", content, uploadme)
   114  			}
   115  		}
   116  	}
   117  }