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 }