Merge pull request #5634 from cvium/directoryservice-case-sensitive
make directoryservice cache case sensitive
This commit is contained in:
commit
1de031a7c3
|
@ -12,11 +12,11 @@ namespace MediaBrowser.Controller.Providers
|
|||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
private readonly ConcurrentDictionary<string, FileSystemMetadata[]> _cache = new ConcurrentDictionary<string, FileSystemMetadata[]>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly ConcurrentDictionary<string, FileSystemMetadata[]> _cache = new (StringComparer.Ordinal);
|
||||
|
||||
private readonly ConcurrentDictionary<string, FileSystemMetadata> _fileCache = new ConcurrentDictionary<string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly ConcurrentDictionary<string, FileSystemMetadata> _fileCache = new (StringComparer.Ordinal);
|
||||
|
||||
private readonly ConcurrentDictionary<string, List<string>> _filePathCache = new ConcurrentDictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly ConcurrentDictionary<string, List<string>> _filePathCache = new (StringComparer.Ordinal);
|
||||
|
||||
public DirectoryService(IFileSystem fileSystem)
|
||||
{
|
||||
|
|
200
tests/Jellyfin.Controller.Tests/DirectoryServiceTests.cs
Normal file
200
tests/Jellyfin.Controller.Tests/DirectoryServiceTests.cs
Normal file
|
@ -0,0 +1,200 @@
|
|||
using System.Linq;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Controller.Tests
|
||||
{
|
||||
public class DirectoryServiceTests
|
||||
{
|
||||
private const string LowerCasePath = "/music/someartist";
|
||||
private const string UpperCasePath = "/music/SOMEARTIST";
|
||||
|
||||
private static readonly FileSystemMetadata[] _lowerCaseFileSystemMetadata =
|
||||
{
|
||||
new ()
|
||||
{
|
||||
FullName = LowerCasePath + "/Artwork",
|
||||
IsDirectory = true
|
||||
},
|
||||
new ()
|
||||
{
|
||||
FullName = LowerCasePath + "/Some Other Folder",
|
||||
IsDirectory = true
|
||||
},
|
||||
new ()
|
||||
{
|
||||
FullName = LowerCasePath + "/Song 2.mp3",
|
||||
IsDirectory = false
|
||||
},
|
||||
new ()
|
||||
{
|
||||
FullName = LowerCasePath + "/Song 3.mp3",
|
||||
IsDirectory = false
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly FileSystemMetadata[] _upperCaseFileSystemMetadata =
|
||||
{
|
||||
new ()
|
||||
{
|
||||
FullName = UpperCasePath + "/Lyrics",
|
||||
IsDirectory = true
|
||||
},
|
||||
new ()
|
||||
{
|
||||
FullName = UpperCasePath + "/Song 1.mp3",
|
||||
IsDirectory = false
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void GetFileSystemEntries_GivenPathsWithDifferentCasing_CachesAll()
|
||||
{
|
||||
var fileSystemMock = new Mock<IFileSystem>();
|
||||
fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is<string>(x => x == UpperCasePath), false)).Returns(_upperCaseFileSystemMetadata);
|
||||
fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is<string>(x => x == LowerCasePath), false)).Returns(_lowerCaseFileSystemMetadata);
|
||||
var directoryService = new DirectoryService(fileSystemMock.Object);
|
||||
|
||||
var upperCaseResult = directoryService.GetFileSystemEntries(UpperCasePath);
|
||||
var lowerCaseResult = directoryService.GetFileSystemEntries(LowerCasePath);
|
||||
|
||||
Assert.Equal(_upperCaseFileSystemMetadata, upperCaseResult);
|
||||
Assert.Equal(_lowerCaseFileSystemMetadata, lowerCaseResult);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFiles_GivenPathsWithDifferentCasing_ReturnsCorrectFiles()
|
||||
{
|
||||
var fileSystemMock = new Mock<IFileSystem>();
|
||||
fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is<string>(x => x == UpperCasePath), false)).Returns(_upperCaseFileSystemMetadata);
|
||||
fileSystemMock.Setup(f => f.GetFileSystemEntries(It.Is<string>(x => x == LowerCasePath), false)).Returns(_lowerCaseFileSystemMetadata);
|
||||
var directoryService = new DirectoryService(fileSystemMock.Object);
|
||||
|
||||
var upperCaseResult = directoryService.GetFiles(UpperCasePath);
|
||||
var lowerCaseResult = directoryService.GetFiles(LowerCasePath);
|
||||
|
||||
Assert.Equal(_upperCaseFileSystemMetadata.Where(f => !f.IsDirectory), upperCaseResult);
|
||||
Assert.Equal(_lowerCaseFileSystemMetadata.Where(f => !f.IsDirectory), lowerCaseResult);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFile_GivenFilePathsWithDifferentCasing_ReturnsCorrectFile()
|
||||
{
|
||||
const string lowerCasePath = "/music/someartist/song 1.mp3";
|
||||
var lowerCaseFileSystemMetadata = new FileSystemMetadata
|
||||
{
|
||||
FullName = lowerCasePath,
|
||||
Exists = true
|
||||
};
|
||||
const string upperCasePath = "/music/SOMEARTIST/SONG 1.mp3";
|
||||
var upperCaseFileSystemMetadata = new FileSystemMetadata
|
||||
{
|
||||
FullName = upperCasePath,
|
||||
Exists = false
|
||||
};
|
||||
var fileSystemMock = new Mock<IFileSystem>();
|
||||
fileSystemMock.Setup(f => f.GetFileInfo(It.Is<string>(x => x == upperCasePath))).Returns(upperCaseFileSystemMetadata);
|
||||
fileSystemMock.Setup(f => f.GetFileInfo(It.Is<string>(x => x == lowerCasePath))).Returns(lowerCaseFileSystemMetadata);
|
||||
var directoryService = new DirectoryService(fileSystemMock.Object);
|
||||
|
||||
var lowerCaseResult = directoryService.GetFile(lowerCasePath);
|
||||
var upperCaseResult = directoryService.GetFile(upperCasePath);
|
||||
|
||||
Assert.Equal(lowerCaseFileSystemMetadata, lowerCaseResult);
|
||||
Assert.Null(upperCaseResult);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFile_GivenCachedPath_ReturnsCachedFile()
|
||||
{
|
||||
const string path = "/music/someartist/song 1.mp3";
|
||||
var cachedFileSystemMetadata = new FileSystemMetadata
|
||||
{
|
||||
FullName = path,
|
||||
Exists = true
|
||||
};
|
||||
var newFileSystemMetadata = new FileSystemMetadata
|
||||
{
|
||||
FullName = "/music/SOMEARTIST/song 1.mp3",
|
||||
Exists = true
|
||||
};
|
||||
|
||||
var fileSystemMock = new Mock<IFileSystem>();
|
||||
fileSystemMock.Setup(f => f.GetFileInfo(It.Is<string>(x => x == path))).Returns(cachedFileSystemMetadata);
|
||||
var directoryService = new DirectoryService(fileSystemMock.Object);
|
||||
|
||||
var result = directoryService.GetFile(path);
|
||||
fileSystemMock.Setup(f => f.GetFileInfo(It.Is<string>(x => x == path))).Returns(newFileSystemMetadata);
|
||||
var secondResult = directoryService.GetFile(path);
|
||||
|
||||
Assert.Equal(cachedFileSystemMetadata, result);
|
||||
Assert.Equal(cachedFileSystemMetadata, secondResult);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFilePaths_GivenCachedFilePathWithoutClear_ReturnsOnlyCachedPaths()
|
||||
{
|
||||
const string path = "/music/someartist";
|
||||
|
||||
var cachedPaths = new[]
|
||||
{
|
||||
"/music/someartist/song 1.mp3",
|
||||
"/music/someartist/song 2.mp3",
|
||||
"/music/someartist/song 3.mp3",
|
||||
"/music/someartist/song 4.mp3",
|
||||
};
|
||||
var newPaths = new[]
|
||||
{
|
||||
"/music/someartist/song 5.mp3",
|
||||
"/music/someartist/song 6.mp3",
|
||||
"/music/someartist/song 7.mp3",
|
||||
"/music/someartist/song 8.mp3",
|
||||
};
|
||||
|
||||
var fileSystemMock = new Mock<IFileSystem>();
|
||||
fileSystemMock.Setup(f => f.GetFilePaths(It.Is<string>(x => x == path), false)).Returns(cachedPaths);
|
||||
var directoryService = new DirectoryService(fileSystemMock.Object);
|
||||
|
||||
var result = directoryService.GetFilePaths(path);
|
||||
fileSystemMock.Setup(f => f.GetFilePaths(It.Is<string>(x => x == path), false)).Returns(newPaths);
|
||||
var secondResult = directoryService.GetFilePaths(path);
|
||||
|
||||
Assert.Equal(cachedPaths, result);
|
||||
Assert.Equal(cachedPaths, secondResult);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFilePaths_GivenCachedFilePathWithClear_ReturnsNewPaths()
|
||||
{
|
||||
const string path = "/music/someartist";
|
||||
|
||||
var cachedPaths = new[]
|
||||
{
|
||||
"/music/someartist/song 1.mp3",
|
||||
"/music/someartist/song 2.mp3",
|
||||
"/music/someartist/song 3.mp3",
|
||||
"/music/someartist/song 4.mp3",
|
||||
};
|
||||
var newPaths = new[]
|
||||
{
|
||||
"/music/someartist/song 5.mp3",
|
||||
"/music/someartist/song 6.mp3",
|
||||
"/music/someartist/song 7.mp3",
|
||||
"/music/someartist/song 8.mp3",
|
||||
};
|
||||
|
||||
var fileSystemMock = new Mock<IFileSystem>();
|
||||
fileSystemMock.Setup(f => f.GetFilePaths(It.Is<string>(x => x == path), false)).Returns(cachedPaths);
|
||||
var directoryService = new DirectoryService(fileSystemMock.Object);
|
||||
|
||||
var result = directoryService.GetFilePaths(path);
|
||||
fileSystemMock.Setup(f => f.GetFilePaths(It.Is<string>(x => x == path), false)).Returns(newPaths);
|
||||
var secondResult = directoryService.GetFilePaths(path, true);
|
||||
|
||||
Assert.Equal(cachedPaths, result);
|
||||
Assert.Equal(newPaths, secondResult);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
|
||||
<PackageReference Include="coverlet.collector" Version="3.0.3" />
|
||||
|
|
Loading…
Reference in New Issue
Block a user