diff --git a/fs/cache/cache.go b/fs/cache/cache.go index fec9a6fe1..4a5bdc803 100644 --- a/fs/cache/cache.go +++ b/fs/cache/cache.go @@ -56,12 +56,20 @@ func GetFn(fsString string, create func(fsString string) (fs.Fs, error)) (f fs.F if created { canonicalName := fs.ConfigString(f) if canonicalName != fsString { - fs.Debugf(nil, "fs cache: renaming cache item %q to be canonical %q", fsString, canonicalName) - value, found := c.Rename(fsString, canonicalName) - if found { - f = value.(fs.Fs) + // Note that if err == fs.ErrorIsFile at this moment + // then we can't rename the remote as it will have the + // wrong error status, we need to add a new one. + if err == nil { + fs.Debugf(nil, "fs cache: renaming cache item %q to be canonical %q", fsString, canonicalName) + value, found := c.Rename(fsString, canonicalName) + if found { + f = value.(fs.Fs) + } + addMapping(fsString, canonicalName) + } else { + fs.Debugf(nil, "fs cache: adding new entry for parent of %q, %q", fsString, canonicalName) + Put(canonicalName, f) } - addMapping(fsString, canonicalName) } } return f, err diff --git a/fs/cache/cache_test.go b/fs/cache/cache_test.go index e261eda15..56ad4231c 100644 --- a/fs/cache/cache_test.go +++ b/fs/cache/cache_test.go @@ -23,7 +23,7 @@ func mockNewFs(t *testing.T) (func(), func(path string) (fs.Fs, error)) { switch path { case "mock:/": return mockfs.NewFs("mock", "/"), nil - case "mock:/file.txt": + case "mock:/file.txt", "mock:file.txt": return mockfs.NewFs("mock", "/"), fs.ErrorIsFile case "mock:/error": return nil, errSentinel @@ -64,13 +64,46 @@ func TestGetFile(t *testing.T) { require.Equal(t, fs.ErrorIsFile, err) require.NotNil(t, f) - assert.Equal(t, 1, c.Entries()) + assert.Equal(t, 2, c.Entries()) f2, err := GetFn("mock:/file.txt", create) require.Equal(t, fs.ErrorIsFile, err) require.NotNil(t, f2) assert.Equal(t, f, f2) + + // check parent is there too + f2, err = GetFn("mock:/", create) + require.Nil(t, err) + require.NotNil(t, f2) + + assert.Equal(t, f, f2) +} + +func TestGetFile2(t *testing.T) { + cleanup, create := mockNewFs(t) + defer cleanup() + + assert.Equal(t, 0, c.Entries()) + + f, err := GetFn("mock:file.txt", create) + require.Equal(t, fs.ErrorIsFile, err) + require.NotNil(t, f) + + assert.Equal(t, 2, c.Entries()) + + f2, err := GetFn("mock:file.txt", create) + require.Equal(t, fs.ErrorIsFile, err) + require.NotNil(t, f2) + + assert.Equal(t, f, f2) + + // check parent is there too + f2, err = GetFn("mock:/", create) + require.Nil(t, err) + require.NotNil(t, f2) + + assert.Equal(t, f, f2) } func TestGetError(t *testing.T) {