Add tests for reads and writes beyond EOF (#56395)
authorAdam Sitnik <adam.sitnik@gmail.com>
Tue, 27 Jul 2021 18:07:49 +0000 (20:07 +0200)
committerGitHub <noreply@github.com>
Tue, 27 Jul 2021 18:07:49 +0000 (20:07 +0200)
* ensure that reads beyond EOF return 0

* ensure that writes beyond EOF extend the file and the content is zeroed

src/libraries/System.IO.FileSystem/tests/RandomAccess/Read.cs
src/libraries/System.IO.FileSystem/tests/RandomAccess/ReadAsync.cs
src/libraries/System.IO.FileSystem/tests/RandomAccess/ReadScatter.cs
src/libraries/System.IO.FileSystem/tests/RandomAccess/ReadScatterAsync.cs
src/libraries/System.IO.FileSystem/tests/RandomAccess/Write.cs
src/libraries/System.IO.FileSystem/tests/RandomAccess/WriteAsync.cs
src/libraries/System.IO.FileSystem/tests/RandomAccess/WriteGather.cs
src/libraries/System.IO.FileSystem/tests/RandomAccess/WriteGatherAsync.cs

index 9559e7cebc12f51c3bc96396beeac5ad1ae394d3..509914ecd4b0d0d699f03474665a91fa39422244 100644 (file)
@@ -51,6 +51,20 @@ namespace System.IO.Tests
             }
         }
 
+        [Theory]
+        [MemberData(nameof(GetSyncAsyncOptions))]
+        public void ReadFromBeyondEndOfFileReturnsZero(FileOptions options)
+        {
+            string filePath = GetTestFilePath();
+            File.WriteAllBytes(filePath, new byte[100]);
+
+            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.Open, options: options))
+            {
+                long eof = RandomAccess.GetLength(handle);
+                Assert.Equal(0, RandomAccess.Read(handle, new byte[1], fileOffset: eof + 1));
+            }
+        }
+
         [Theory]
         [MemberData(nameof(GetSyncAsyncOptions))]
         public void ReadsBytesFromGivenFileAtGivenOffset(FileOptions options)
index f23cd8f92f6ac957f88aac91f96e28161a4f907d..fe8f8b1111f2db55d0951944417e57288fc2e25f 100644 (file)
@@ -56,6 +56,20 @@ namespace System.IO.Tests
             }
         }
 
+        [Theory]
+        [MemberData(nameof(GetSyncAsyncOptions))]
+        public async Task ReadFromBeyondEndOfFileReturnsZeroAsync(FileOptions options)
+        {
+            string filePath = GetTestFilePath();
+            File.WriteAllBytes(filePath, new byte[100]);
+
+            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.Open, options: options))
+            {
+                long eof = RandomAccess.GetLength(handle);
+                Assert.Equal(0, await RandomAccess.ReadAsync(handle, new byte[1], fileOffset: eof + 1));
+            }
+        }
+
         [Theory]
         [MemberData(nameof(GetSyncAsyncOptions))]
         public async Task HappyPath(FileOptions options)
index 7f51ea6e8478e2523eee9e7c3e7037d9e6e974ac..0aa60632696188879b90c8cb8843f246ceb4c172 100644 (file)
@@ -46,6 +46,20 @@ namespace System.IO.Tests
             }
         }
 
+        [Theory]
+        [MemberData(nameof(GetSyncAsyncOptions))]
+        public void ReadFromBeyondEndOfFileReturnsZero(FileOptions options)
+        {
+            string filePath = GetTestFilePath();
+            File.WriteAllBytes(filePath, new byte[100]);
+
+            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.Open, options: options))
+            {
+                long eof = RandomAccess.GetLength(handle);
+                Assert.Equal(0, RandomAccess.Read(handle, new Memory<byte>[] { new byte[1] }, fileOffset: eof + 1));
+            }
+        }
+
         [Theory]
         [MemberData(nameof(GetSyncAsyncOptions))]
         public void ReadsBytesFromGivenFileAtGivenOffset(FileOptions options)
index 250d9c316777dacd0edf3b6ac8e6a2ef2813f315..0a9be6c433678e421ceb81d6807cbc5ecf789b3b 100644 (file)
@@ -66,6 +66,20 @@ namespace System.IO.Tests
             }
         }
 
+        [Theory]
+        [MemberData(nameof(GetSyncAsyncOptions))]
+        public async Task ReadFromBeyondEndOfFileReturnsZeroAsync(FileOptions options)
+        {
+            string filePath = GetTestFilePath();
+            File.WriteAllBytes(filePath, new byte[100]);
+
+            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.Open, options: options))
+            {
+                long eof = RandomAccess.GetLength(handle);
+                Assert.Equal(0, await RandomAccess.ReadAsync(handle, new Memory<byte>[] { new byte[1] }, fileOffset: eof + 1));
+            }
+        }
+
         [Theory]
         [MemberData(nameof(GetSyncAsyncOptions))]
         public async Task ReadsBytesFromGivenFileAtGivenOffsetAsync(FileOptions options)
index 8a687dc6012dec5f04f4702f7e6a15f39a7e3efb..d78bd0c686d1d6e2e545d01317f8f900d3c58899 100644 (file)
@@ -50,6 +50,22 @@ namespace System.IO.Tests
             Assert.Equal(stackAllocated.ToArray(), File.ReadAllBytes(filePath));
         }
 
+        [Theory]
+        [MemberData(nameof(GetSyncAsyncOptions))]
+        public void WriteBeyondEndOfFileExtendsTheFile(FileOptions options)
+        {
+            string filePath = GetTestFilePath();
+
+            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.CreateNew, FileAccess.Write, options: options))
+            {
+                Assert.Equal(0, RandomAccess.GetLength(handle));
+                RandomAccess.Write(handle, new byte[1] { 1 }, fileOffset: 1);
+                Assert.Equal(2, RandomAccess.GetLength(handle));
+            }
+
+            Assert.Equal(new byte[] { 0, 1 }, File.ReadAllBytes(filePath));
+        }
+
         [Theory]
         [MemberData(nameof(GetSyncAsyncOptions))]
         public void WritesBytesFromGivenBufferToGivenFileAtGivenOffset(FileOptions options)
index 370032839820603aab0768a43078e691fe7fba58..b816bc8541592ea7343132bc8250a15e5bf90730 100644 (file)
@@ -52,6 +52,22 @@ namespace System.IO.Tests
             }
         }
 
+        [Theory]
+        [MemberData(nameof(GetSyncAsyncOptions))]
+        public async Task WriteBeyondEndOfFileExtendsTheFileAsync(FileOptions options)
+        {
+            string filePath = GetTestFilePath();
+
+            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.CreateNew, FileAccess.Write, options: options))
+            {
+                Assert.Equal(0, RandomAccess.GetLength(handle));
+                await RandomAccess.WriteAsync(handle, new byte[1] { 1 }, fileOffset: 1);
+                Assert.Equal(2, RandomAccess.GetLength(handle));
+            }
+
+            Assert.Equal(new byte[] { 0, 1 }, await File.ReadAllBytesAsync(filePath));
+        }
+
         [Theory]
         [MemberData(nameof(GetSyncAsyncOptions))]
         public async Task WritesBytesFromGivenBufferToGivenFileAtGivenOffsetAsync(FileOptions options)
index 0f28b7c9c68b65f2ac1ceb313f777de776754b5a..2edc72eb867c52add599661446e20d4313b70825 100644 (file)
@@ -47,6 +47,22 @@ namespace System.IO.Tests
             }
         }
 
+        [Theory]
+        [MemberData(nameof(GetSyncAsyncOptions))]
+        public void WriteBeyondEndOfFileExtendsTheFile(FileOptions options)
+        {
+            string filePath = GetTestFilePath();
+
+            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.CreateNew, FileAccess.Write, options: options))
+            {
+                Assert.Equal(0, RandomAccess.GetLength(handle));
+                RandomAccess.Write(handle, new ReadOnlyMemory<byte>[] { new byte[1] { 1 } }, fileOffset: 1);
+                Assert.Equal(2, RandomAccess.GetLength(handle));
+            }
+
+            Assert.Equal(new byte[] { 0, 1 }, File.ReadAllBytes(filePath));
+        }
+
         [Theory]
         [MemberData(nameof(GetSyncAsyncOptions))]
         public void WritesBytesFromGivenBuffersToGivenFileAtGivenOffset(FileOptions options)
index f89cfd3b4fc62308c307a14dc471f128a50f6386..bf995a318fd9a479fb3be0f0934ba4a6e58606cc 100644 (file)
@@ -64,6 +64,22 @@ namespace System.IO.Tests
             }
         }
 
+        [Theory]
+        [MemberData(nameof(GetSyncAsyncOptions))]
+        public async Task WriteBeyondEndOfFileExtendsTheFileAsync(FileOptions options)
+        {
+            string filePath = GetTestFilePath();
+
+            using (SafeFileHandle handle = File.OpenHandle(filePath, FileMode.CreateNew, FileAccess.Write, options: options))
+            {
+                Assert.Equal(0, RandomAccess.GetLength(handle));
+                await RandomAccess.WriteAsync(handle, new ReadOnlyMemory<byte>[] { new byte[1] { 1 } }, fileOffset: 1);
+                Assert.Equal(2, RandomAccess.GetLength(handle));
+            }
+
+            Assert.Equal(new byte[] { 0, 1 }, await File.ReadAllBytesAsync(filePath));
+        }
+
         [Theory]
         [MemberData(nameof(GetSyncAsyncOptions))]
         public async Task WritesBytesFromGivenBufferToGivenFileAtGivenOffsetAsync(FileOptions options)