diff options
author | Stephen Toub <stoub@microsoft.com> | 2018-03-23 06:11:07 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-23 06:11:07 +0300 |
commit | 77bf4078608a5229afd3132115638b59215f478b (patch) | |
tree | 85767d609c2565b8b319f25d9d48e9130274018b /src/System.IO.FileSystem/tests | |
parent | 53b6cc9aa5b7863744b1e57c8438ec39a6da0855 (diff) |
Fix File.ReadAllBytes{Async} for virtual file system files (#28388)
Some file systems, like procfs, can return 0 for a file's length, even though it actually contains on-demand computed contents. This breaks File.ReadAllBytes{Async}, which currently assumes that a length of 0 means the file is empty. This commit fixes it by changing the assumption to mean that a length of 0 means we can't depend on the Length and instead need to read until EOF.
Diffstat (limited to 'src/System.IO.FileSystem/tests')
-rw-r--r-- | src/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs | 53 | ||||
-rw-r--r-- | src/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs | 52 |
2 files changed, 105 insertions, 0 deletions
diff --git a/src/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs b/src/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs index 7764cdfe5b..b92e5201bd 100644 --- a/src/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs +++ b/src/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs @@ -4,6 +4,7 @@ using System.Runtime.InteropServices; using System.Text; +using System.Threading.Tasks; using Xunit; namespace System.IO.Tests @@ -120,5 +121,57 @@ namespace System.IO.Tests File.SetAttributes(path, FileAttributes.Normal); } } + + [Fact] + public void EmptyFile_ReturnsEmptyArray() + { + string path = GetTestFilePath(); + File.Create(path).Dispose(); + Assert.Equal(0, File.ReadAllBytes(path).Length); + } + + [Theory] + [PlatformSpecific(TestPlatforms.Linux)] + [InlineData("/proc/cmdline")] + [InlineData("/proc/version")] + [InlineData("/proc/filesystems")] + public void ProcFs_EqualsReadAllText(string path) + { + byte[] bytes = null; + string text = null; + + const int NumTries = 3; // some of these could theoretically change between reads, so allow retries just in case + for (int i = 1; i <= NumTries; i++) + { + try + { + bytes = File.ReadAllBytes(path); + text = File.ReadAllText(path); + Assert.Equal(text, Encoding.UTF8.GetString(bytes)); + } + catch when (i < NumTries) { } + } + } + + [Theory] + [PlatformSpecific(TestPlatforms.Linux)] + public void ReadAllBytes_ProcFs_Uptime_ContainsTwoNumbers() + { + string text = Encoding.UTF8.GetString(File.ReadAllBytes("/proc/uptime")); + string[] parts = text.Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + Assert.Equal(2, parts.Length); + Assert.True(double.TryParse(parts[0].Trim(), out _)); + Assert.True(double.TryParse(parts[1].Trim(), out _)); + } + + [Theory] + [PlatformSpecific(TestPlatforms.Linux)] + [InlineData("/proc/meminfo")] + [InlineData("/proc/stat")] + [InlineData("/proc/cpuinfo")] + public void ProcFs_NotEmpty(string path) + { + Assert.InRange(File.ReadAllBytes(path).Length, 1, int.MaxValue); + } } } diff --git a/src/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs b/src/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs index 47b3d71ccc..fa2a8faa7f 100644 --- a/src/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs +++ b/src/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs @@ -134,5 +134,57 @@ namespace System.IO.Tests File.SetAttributes(path, FileAttributes.Normal); } } + + [Fact] + public async Task EmptyFile_ReturnsEmptyArray() + { + string path = GetTestFilePath(); + File.Create(path).Dispose(); + Assert.Equal(0, (await File.ReadAllBytesAsync(path)).Length); + } + + [Theory] + [PlatformSpecific(TestPlatforms.Linux)] + [InlineData("/proc/cmdline")] + [InlineData("/proc/version")] + [InlineData("/proc/filesystems")] + public async Task ProcFs_EqualsReadAllText(string path) + { + byte[] bytes = null; + string text = null; + + const int NumTries = 3; // some of these could theoretically change between reads, so allow retries just in case + for (int i = 1; i <= NumTries; i++) + { + try + { + bytes = await File.ReadAllBytesAsync(path); + text = await File.ReadAllTextAsync(path); + Assert.Equal(text, Encoding.UTF8.GetString(bytes)); + } + catch when (i < NumTries) { } + } + } + + [Theory] + [PlatformSpecific(TestPlatforms.Linux)] + public async Task ReadAllBytes_ProcFs_Uptime_ContainsTwoNumbers() + { + string text = Encoding.UTF8.GetString(await File.ReadAllBytesAsync("/proc/uptime")); + string[] parts = text.Split(' ', StringSplitOptions.RemoveEmptyEntries); + Assert.Equal(2, parts.Length); + Assert.True(double.TryParse(parts[0].Trim(), out _)); + Assert.True(double.TryParse(parts[1].Trim(), out _)); + } + + [Theory] + [PlatformSpecific(TestPlatforms.Linux)] + [InlineData("/proc/meminfo")] + [InlineData("/proc/stat")] + [InlineData("/proc/cpuinfo")] + public async Task ProcFs_NotEmpty(string path) + { + Assert.InRange((await File.ReadAllBytesAsync(path)).Length, 1, int.MaxValue); + } } } |