diff --git a/backend/cache/cache.go b/backend/cache/cache.go index 7d53185c3..7fd132b4d 100644 --- a/backend/cache/cache.go +++ b/backend/cache/cache.go @@ -859,19 +859,30 @@ func (f *Fs) DirMove(src fs.Fs, srcRemote, dstRemote string) error { f.backgroundRunner.pause() defer f.backgroundRunner.play() + _, errInWrap := srcFs.UnWrap().List(srcRemote) + _, errInTemp := f.tempFs.List(srcRemote) + // not found in either fs + if errInWrap != nil && errInTemp != nil { + return fs.ErrorDirNotFound + } + // we check if the source exists on the remote and make the same move on it too if it does // otherwise, we skip this step - _, err := srcFs.UnWrap().List(srcRemote) - if err == nil { + if errInWrap == nil { err := do(srcFs.UnWrap(), srcRemote, dstRemote) if err != nil { return err } fs.Debugf(srcRemote, "movedir: dir moved in the source fs") } + // we need to check if the directory exists in the temp fs + // and skip the move if it doesn't + if errInTemp != nil { + goto cleanup + } var queuedEntries []*Object - err = walk.Walk(f.tempFs, srcRemote, true, -1, func(path string, entries fs.DirEntries, err error) error { + err := walk.Walk(f.tempFs, srcRemote, true, -1, func(path string, entries fs.DirEntries, err error) error { for _, o := range entries { if oo, ok := o.(fs.Object); ok { co := ObjectFromOriginal(f, oo) @@ -910,6 +921,7 @@ func (f *Fs) DirMove(src fs.Fs, srcRemote, dstRemote string) error { } fs.Debugf(srcRemote, "movedir: dir moved in the source fs") } +cleanup: // delete src dir from cache along with all chunks srcDir := NewDirectory(srcFs, srcRemote) diff --git a/backend/cache/cache_internal_test.go b/backend/cache/cache_internal_test.go index d76689d75..06e63c031 100644 --- a/backend/cache/cache_internal_test.go +++ b/backend/cache/cache_internal_test.go @@ -54,30 +54,33 @@ var ( runInstance *run errNotSupported = errors.New("not supported") decryptedToEncryptedRemotes = map[string]string{ - "one": "lm4u7jjt3c85bf56vjqgeenuno", - "second": "qvt1ochrkcfbptp5mu9ugb2l14", - "test": "jn4tegjtpqro30t3o11thb4b5s", - "test2": "qakvqnh8ttei89e0gc76crpql4", - "data.bin": "0q2847tfko6mhj3dag3r809qbc", - "ticw/data.bin": "5mv97b0ule6pht33srae5pice8/0q2847tfko6mhj3dag3r809qbc", - "tiuufo/test/one": "vi6u1olqhirqv14cd8qlej1mgo/jn4tegjtpqro30t3o11thb4b5s/lm4u7jjt3c85bf56vjqgeenuno", - "tiuufo/test/second": "vi6u1olqhirqv14cd8qlej1mgo/jn4tegjtpqro30t3o11thb4b5s/qvt1ochrkcfbptp5mu9ugb2l14", - "tiutfo/test/one": "legd371aa8ol36tjfklt347qnc/jn4tegjtpqro30t3o11thb4b5s/lm4u7jjt3c85bf56vjqgeenuno", - "tiutfo/second/one": "legd371aa8ol36tjfklt347qnc/qvt1ochrkcfbptp5mu9ugb2l14/lm4u7jjt3c85bf56vjqgeenuno", - "second/one": "qvt1ochrkcfbptp5mu9ugb2l14/lm4u7jjt3c85bf56vjqgeenuno", - "test/one": "jn4tegjtpqro30t3o11thb4b5s/lm4u7jjt3c85bf56vjqgeenuno", - "test/second": "jn4tegjtpqro30t3o11thb4b5s/qvt1ochrkcfbptp5mu9ugb2l14", - "test/third": "jn4tegjtpqro30t3o11thb4b5s/2nd7fjiop5h3ihfj1vl953aa5g", - "test/0.bin": "jn4tegjtpqro30t3o11thb4b5s/e6frddt058b6kvbpmlstlndmtk", - "test/1.bin": "jn4tegjtpqro30t3o11thb4b5s/kck472nt1k7qbmob0mt1p1crgc", - "test/2.bin": "jn4tegjtpqro30t3o11thb4b5s/744oe9ven2rmak4u27if51qk24", - "test/3.bin": "jn4tegjtpqro30t3o11thb4b5s/2bjd8kef0u5lmsu6qhqll34bcs", - "test/4.bin": "jn4tegjtpqro30t3o11thb4b5s/cvjs73iv0a82v0c7r67avllh7s", - "test/5.bin": "jn4tegjtpqro30t3o11thb4b5s/0plkdo790b6bnmt33qsdqmhv9c", - "test/6.bin": "jn4tegjtpqro30t3o11thb4b5s/s5r633srnjtbh83893jovjt5d0", - "test/7.bin": "jn4tegjtpqro30t3o11thb4b5s/6rq45tr9bjsammku622flmqsu4", - "test/8.bin": "jn4tegjtpqro30t3o11thb4b5s/37bc6tcl3e31qb8cadvjb749vk", - "test/9.bin": "jn4tegjtpqro30t3o11thb4b5s/t4pr35hnls32789o8fk0chk1ec", + "one": "lm4u7jjt3c85bf56vjqgeenuno", + "second": "qvt1ochrkcfbptp5mu9ugb2l14", + "test": "jn4tegjtpqro30t3o11thb4b5s", + "test2": "qakvqnh8ttei89e0gc76crpql4", + "data.bin": "0q2847tfko6mhj3dag3r809qbc", + "ticw/data.bin": "5mv97b0ule6pht33srae5pice8/0q2847tfko6mhj3dag3r809qbc", + "tiuufo/test/one": "vi6u1olqhirqv14cd8qlej1mgo/jn4tegjtpqro30t3o11thb4b5s/lm4u7jjt3c85bf56vjqgeenuno", + "tiuufo/test/second": "vi6u1olqhirqv14cd8qlej1mgo/jn4tegjtpqro30t3o11thb4b5s/qvt1ochrkcfbptp5mu9ugb2l14", + "tiutfo/test/one": "legd371aa8ol36tjfklt347qnc/jn4tegjtpqro30t3o11thb4b5s/lm4u7jjt3c85bf56vjqgeenuno", + "tiutfo/second/one": "legd371aa8ol36tjfklt347qnc/qvt1ochrkcfbptp5mu9ugb2l14/lm4u7jjt3c85bf56vjqgeenuno", + "second/one": "qvt1ochrkcfbptp5mu9ugb2l14/lm4u7jjt3c85bf56vjqgeenuno", + "test/one": "jn4tegjtpqro30t3o11thb4b5s/lm4u7jjt3c85bf56vjqgeenuno", + "test/second": "jn4tegjtpqro30t3o11thb4b5s/qvt1ochrkcfbptp5mu9ugb2l14", + "one/test": "lm4u7jjt3c85bf56vjqgeenuno/jn4tegjtpqro30t3o11thb4b5s", + "one/test/data.bin": "lm4u7jjt3c85bf56vjqgeenuno/jn4tegjtpqro30t3o11thb4b5s/0q2847tfko6mhj3dag3r809qbc", + "second/test/data.bin": "qvt1ochrkcfbptp5mu9ugb2l14/jn4tegjtpqro30t3o11thb4b5s/0q2847tfko6mhj3dag3r809qbc", + "test/third": "jn4tegjtpqro30t3o11thb4b5s/2nd7fjiop5h3ihfj1vl953aa5g", + "test/0.bin": "jn4tegjtpqro30t3o11thb4b5s/e6frddt058b6kvbpmlstlndmtk", + "test/1.bin": "jn4tegjtpqro30t3o11thb4b5s/kck472nt1k7qbmob0mt1p1crgc", + "test/2.bin": "jn4tegjtpqro30t3o11thb4b5s/744oe9ven2rmak4u27if51qk24", + "test/3.bin": "jn4tegjtpqro30t3o11thb4b5s/2bjd8kef0u5lmsu6qhqll34bcs", + "test/4.bin": "jn4tegjtpqro30t3o11thb4b5s/cvjs73iv0a82v0c7r67avllh7s", + "test/5.bin": "jn4tegjtpqro30t3o11thb4b5s/0plkdo790b6bnmt33qsdqmhv9c", + "test/6.bin": "jn4tegjtpqro30t3o11thb4b5s/s5r633srnjtbh83893jovjt5d0", + "test/7.bin": "jn4tegjtpqro30t3o11thb4b5s/6rq45tr9bjsammku622flmqsu4", + "test/8.bin": "jn4tegjtpqro30t3o11thb4b5s/37bc6tcl3e31qb8cadvjb749vk", + "test/9.bin": "jn4tegjtpqro30t3o11thb4b5s/t4pr35hnls32789o8fk0chk1ec", } ) @@ -652,6 +655,43 @@ func TestInternalUploadQueueOneFileWithRest(t *testing.T) { testInternalUploadQueueOneFile(t, id, rootFs, boltDb) } +func TestInternalUploadMoveExistingFile(t *testing.T) { + id := fmt.Sprintf("tiumef%v", time.Now().Unix()) + rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true, + nil, + map[string]string{"cache-tmp-upload-path": path.Join(runInstance.tmpUploadDir, id), "cache-tmp-wait-time": "3s"}) + defer runInstance.cleanupFs(t, rootFs, boltDb) + + err := rootFs.Mkdir("one") + require.NoError(t, err) + err = rootFs.Mkdir("one/test") + require.NoError(t, err) + err = rootFs.Mkdir("second") + require.NoError(t, err) + + // create some rand test data + testSize := int64(10485760) + testReader := runInstance.randomReader(t, testSize) + runInstance.writeObjectReader(t, rootFs, "one/test/data.bin", testReader) + runInstance.completeAllBackgroundUploads(t, rootFs, "one/test/data.bin") + + de1, err := runInstance.list(t, rootFs, "one/test") + require.NoError(t, err) + require.Len(t, de1, 1) + + time.Sleep(time.Second * 5) + _ = os.Remove(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "one/test"))) + require.NoError(t, err) + + err = runInstance.dirMove(t, rootFs, "one/test", "second/test") + require.NoError(t, err) + + // check if it can be read + de1, err = runInstance.list(t, rootFs, "second/test") + require.NoError(t, err) + require.Len(t, de1, 1) +} + func TestInternalUploadQueueMoreFiles(t *testing.T) { id := fmt.Sprintf("tiuqmf%v", time.Now().Unix()) rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true,