drive: fix DirMove leaving a hardlinked directory behind #2245
This bug was introduced by the v3 API conversion in 07f20dd1fd
.
The problem was that dircache.FindPath doesn't work for the root directory.
This adds an internal error for dircache.FindPath being called with
the root directory. This makes a failing test, which the fix to the
drive backend fixes.
This also improves the DirCache integration test.
This commit is contained in:
parent
29ce1c2747
commit
3d5106e52b
3 changed files with 37 additions and 5 deletions
|
@ -1195,10 +1195,16 @@ func (f *Fs) DirMove(src fs.Fs, srcRemote, dstRemote string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find ID of src parent
|
// Find ID of src parent
|
||||||
_, srcDirectoryID, err := srcFs.dirCache.FindPath(srcRemote, false)
|
var srcDirectoryID string
|
||||||
|
if srcRemote == "" {
|
||||||
|
srcDirectoryID, err = srcFs.dirCache.RootParentID()
|
||||||
|
} else {
|
||||||
|
_, srcDirectoryID, err = srcFs.dirCache.FindPath(srcRemote, false)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find ID of src
|
// Find ID of src
|
||||||
srcID, err := srcFs.dirCache.FindDir(srcRemote, false)
|
srcID, err := srcFs.dirCache.FindDir(srcRemote, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -626,6 +626,9 @@ func Run(t *testing.T, opt *Opt) {
|
||||||
fstest.CheckListing(t, remote, []fstest.Item{file1, file2})
|
fstest.CheckListing(t, remote, []fstest.Item{file1, file2})
|
||||||
// 1: file name.txt
|
// 1: file name.txt
|
||||||
// 2: hello sausage?/../z.txt
|
// 2: hello sausage?/../z.txt
|
||||||
|
|
||||||
|
// Tidy up moveTest directory
|
||||||
|
require.NoError(t, remote.Rmdir("moveTest"))
|
||||||
})
|
})
|
||||||
|
|
||||||
// Move src to this remote using server side move operations.
|
// Move src to this remote using server side move operations.
|
||||||
|
@ -664,21 +667,38 @@ func Run(t *testing.T, opt *Opt) {
|
||||||
|
|
||||||
// check remotes
|
// check remotes
|
||||||
// FIXME: Prints errors.
|
// FIXME: Prints errors.
|
||||||
fstest.CheckListing(t, remote, []fstest.Item{})
|
// remote should not exist here
|
||||||
|
_, err = remote.List("")
|
||||||
|
require.Equal(t, fs.ErrorDirNotFound, errors.Cause(err))
|
||||||
|
//fstest.CheckListingWithPrecision(t, remote, []fstest.Item{}, []string{}, remote.Precision())
|
||||||
file1Copy := file1
|
file1Copy := file1
|
||||||
file1Copy.Path = path.Join(newName, file1.Path)
|
file1Copy.Path = path.Join(newName, file1.Path)
|
||||||
file2Copy := file2
|
file2Copy := file2
|
||||||
file2Copy.Path = path.Join(newName, file2.Path)
|
file2Copy.Path = path.Join(newName, file2.Path)
|
||||||
file2Copy.WinPath = path.Join(newName, file2.WinPath)
|
file2Copy.WinPath = path.Join(newName, file2.WinPath)
|
||||||
fstest.CheckListing(t, newRemote, []fstest.Item{file2Copy, file1Copy})
|
fstest.CheckListingWithPrecision(t, newRemote, []fstest.Item{file2Copy, file1Copy}, []string{
|
||||||
|
"new_name",
|
||||||
|
"new_name/sub_new_name",
|
||||||
|
"new_name/sub_new_name/hello? sausage",
|
||||||
|
"new_name/sub_new_name/hello? sausage/êé",
|
||||||
|
"new_name/sub_new_name/hello? sausage/êé/Hello, 世界",
|
||||||
|
"new_name/sub_new_name/hello? sausage/êé/Hello, 世界/ \" ' @ < > & ? + ≠",
|
||||||
|
}, newRemote.Precision())
|
||||||
|
|
||||||
// move it back
|
// move it back
|
||||||
err = doDirMove(newRemote, newName, "")
|
err = doDirMove(newRemote, newName, "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// check remotes
|
// check remotes
|
||||||
fstest.CheckListing(t, remote, []fstest.Item{file2, file1})
|
fstest.CheckListingWithPrecision(t, remote, []fstest.Item{file2, file1}, []string{
|
||||||
fstest.CheckListing(t, newRemote, []fstest.Item{})
|
"hello? sausage",
|
||||||
|
"hello? sausage/êé",
|
||||||
|
"hello? sausage/êé/Hello, 世界",
|
||||||
|
"hello? sausage/êé/Hello, 世界/ \" ' @ < > & ? + ≠",
|
||||||
|
}, remote.Precision())
|
||||||
|
fstest.CheckListingWithPrecision(t, newRemote, []fstest.Item{}, []string{
|
||||||
|
"new_name",
|
||||||
|
}, newRemote.Precision())
|
||||||
})
|
})
|
||||||
|
|
||||||
// TestFsRmdirFull tests removing a non empty directory
|
// TestFsRmdirFull tests removing a non empty directory
|
||||||
|
|
|
@ -204,8 +204,14 @@ func (dc *DirCache) _findDir(path string, create bool) (pathID string, err error
|
||||||
|
|
||||||
// FindPath finds the leaf and directoryID from a path
|
// FindPath finds the leaf and directoryID from a path
|
||||||
//
|
//
|
||||||
|
// Do not call FindPath with the root directory - it will return an error
|
||||||
|
//
|
||||||
// If create is set parent directories will be created if they don't exist
|
// If create is set parent directories will be created if they don't exist
|
||||||
func (dc *DirCache) FindPath(path string, create bool) (leaf, directoryID string, err error) {
|
func (dc *DirCache) FindPath(path string, create bool) (leaf, directoryID string, err error) {
|
||||||
|
if path == "" {
|
||||||
|
err = errors.New("internal error: can't call FindPath with root directory")
|
||||||
|
return
|
||||||
|
}
|
||||||
dc.mu.Lock()
|
dc.mu.Lock()
|
||||||
defer dc.mu.Unlock()
|
defer dc.mu.Unlock()
|
||||||
directory, leaf := SplitPath(path)
|
directory, leaf := SplitPath(path)
|
||||||
|
|
Loading…
Reference in a new issue