From c6c5dea5cd39842b351515ebdb4ac9c5b5840bde Mon Sep 17 00:00:00 2001
From: Adam Sitnik <adam.sitnik@gmail.com>
Date: Wed, 8 Dec 2021 09:28:33 +0100
Subject: [PATCH 1/3] move existing large file tests into a separate type (no
 code changes)

---
 .../tests/File/ReadWriteAllBytes.cs           |  30 -----
 .../tests/File/ReadWriteAllBytesAsync.cs      |  31 -----
 .../tests/FileStream/Read.cs                  |  34 ------
 .../tests/LargeFileTests.cs                   | 106 ++++++++++++++++++
 .../tests/System.IO.FileSystem.Tests.csproj   |   1 +
 5 files changed, 107 insertions(+), 95 deletions(-)
 create mode 100644 src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs

diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs
index 39becd6d0d5145..26dd666d069166 100644
--- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs
+++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs
@@ -57,36 +57,6 @@ public void ValidWrite(int size)
             File.Delete(path);
         }
 
-        [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
-        public void ReadFileOver2GB()
-        {
-            string path = GetTestFilePath();
-            using (FileStream fs = File.Create(path))
-            {
-                fs.SetLength(int.MaxValue + 1L);
-            }
-
-            // File is too large for ReadAllBytes at once
-            Assert.Throws<IOException>(() => File.ReadAllBytes(path));
-        }
-
-        [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
-        public void ReadFileOverMaxArrayLength()
-        {
-            string path = GetTestFilePath();
-            using (FileStream fs = File.Create(path))
-            {
-                fs.SetLength(Array.MaxLength + 1L);
-            }
-
-            // File is too large for ReadAllBytes at once
-            Assert.Throws<IOException>(() => File.ReadAllBytes(path));
-        }
-
         [Fact]
         public void Overwrite()
         {
diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs
index 6414ab2ad873c9..c4f147cbb80092 100644
--- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs
+++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs
@@ -6,7 +6,6 @@
 using System.Threading.Tasks;
 using Xunit;
 using System.IO.Pipes;
-using Microsoft.DotNet.XUnitExtensions;
 
 namespace System.IO.Tests
 {
@@ -70,36 +69,6 @@ public Task AlreadyCanceledAsync()
                 async () => await File.WriteAllBytesAsync(path, new byte[0], token));
         }
 
-        [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
-        public async Task ReadFileOver2GBAsync()
-        {
-            string path = GetTestFilePath();
-            using (FileStream fs = File.Create(path))
-            {
-                fs.SetLength(int.MaxValue + 1L);
-            }
-
-            // File is too large for ReadAllBytesAsync at once
-            await Assert.ThrowsAsync<IOException>(async () => await File.ReadAllBytesAsync(path));
-        }
-
-        [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
-        public async Task ReadFileOverMaxArrayLengthAsync()
-        {
-            string path = GetTestFilePath();
-            using (FileStream fs = File.Create(path))
-            {
-                fs.SetLength(Array.MaxLength + 1L);
-            }
-
-            // File is too large for ReadAllBytesAsync at once
-            await Assert.ThrowsAsync<IOException>(async () => await File.ReadAllBytesAsync(path));
-        }
-
         [Fact]
         public async Task OverwriteAsync()
         {
diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/Read.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/Read.cs
index 0eccf6a2801bba..b6c555920bca3b 100644
--- a/src/libraries/System.IO.FileSystem/tests/FileStream/Read.cs
+++ b/src/libraries/System.IO.FileSystem/tests/FileStream/Read.cs
@@ -14,39 +14,5 @@ public void NegativeReadRootThrows()
             Assert.Throws<UnauthorizedAccessException>(() =>
                 new FileStream(Path.GetPathRoot(Directory.GetCurrentDirectory()), FileMode.Open, FileAccess.Read));
         }
-
-        [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
-        public void NoInt32OverflowInTheBufferingLogic()
-        {
-            const long position1 = 10;
-            const long position2 = (1L << 32) + position1;
-
-            string filePath = GetTestFilePath();
-            byte[] data1 = new byte[] { 1, 2, 3, 4, 5 };
-            byte[] data2 = new byte[] { 6, 7, 8, 9, 10 };
-            byte[] buffer = new byte[5];
-
-            using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
-            {
-                stream.Seek(position1, SeekOrigin.Begin);
-                stream.Write(data1);
-
-                stream.Seek(position2, SeekOrigin.Begin);
-                stream.Write(data2);
-            }
-
-            using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
-            {
-                stream.Seek(position1, SeekOrigin.Begin);
-                Assert.Equal(buffer.Length, stream.Read(buffer));
-                Assert.Equal(data1, buffer);
-
-                stream.Seek(position2, SeekOrigin.Begin);
-                Assert.Equal(buffer.Length, stream.Read(buffer));
-                Assert.Equal(data2, buffer);
-            }
-        }
     }
 }
diff --git a/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs b/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs
new file mode 100644
index 00000000000000..bed5fbfb4e72f8
--- /dev/null
+++ b/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs
@@ -0,0 +1,106 @@
+﻿// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.IO.Tests;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace System.IO.FileSystem.Tests
+{
+    public class LargeFileTests : FileSystemTest
+    {
+        [Fact]
+        [OuterLoop]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
+        public void ReadFileOver2GB()
+        {
+            string path = GetTestFilePath();
+            using (FileStream fs = File.Create(path))
+            {
+                fs.SetLength(int.MaxValue + 1L);
+            }
+
+            // File is too large for ReadAllBytes at once
+            Assert.Throws<IOException>(() => File.ReadAllBytes(path));
+        }
+
+        [Fact]
+        [OuterLoop]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
+        public void ReadFileOverMaxArrayLength()
+        {
+            string path = GetTestFilePath();
+            using (FileStream fs = File.Create(path))
+            {
+                fs.SetLength(Array.MaxLength + 1L);
+            }
+
+            // File is too large for ReadAllBytes at once
+            Assert.Throws<IOException>(() => File.ReadAllBytes(path));
+        }
+
+        [Fact]
+        [OuterLoop]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
+        public async Task ReadFileOver2GBAsync()
+        {
+            string path = GetTestFilePath();
+            using (FileStream fs = File.Create(path))
+            {
+                fs.SetLength(int.MaxValue + 1L);
+            }
+
+            // File is too large for ReadAllBytesAsync at once
+            await Assert.ThrowsAsync<IOException>(async () => await File.ReadAllBytesAsync(path));
+        }
+
+        [Fact]
+        [OuterLoop]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
+        public async Task ReadFileOverMaxArrayLengthAsync()
+        {
+            string path = GetTestFilePath();
+            using (FileStream fs = File.Create(path))
+            {
+                fs.SetLength(Array.MaxLength + 1L);
+            }
+
+            // File is too large for ReadAllBytesAsync at once
+            await Assert.ThrowsAsync<IOException>(async () => await File.ReadAllBytesAsync(path));
+        }
+
+        [Fact]
+        [OuterLoop]
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
+        public void NoInt32OverflowInTheBufferingLogic()
+        {
+            const long position1 = 10;
+            const long position2 = (1L << 32) + position1;
+
+            string filePath = GetTestFilePath();
+            byte[] data1 = new byte[] { 1, 2, 3, 4, 5 };
+            byte[] data2 = new byte[] { 6, 7, 8, 9, 10 };
+            byte[] buffer = new byte[5];
+
+            using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+            {
+                stream.Seek(position1, SeekOrigin.Begin);
+                stream.Write(data1);
+
+                stream.Seek(position2, SeekOrigin.Begin);
+                stream.Write(data2);
+            }
+
+            using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+            {
+                stream.Seek(position1, SeekOrigin.Begin);
+                Assert.Equal(buffer.Length, stream.Read(buffer));
+                Assert.Equal(data1, buffer);
+
+                stream.Seek(position2, SeekOrigin.Begin);
+                Assert.Equal(buffer.Length, stream.Read(buffer));
+                Assert.Equal(data2, buffer);
+            }
+        }
+    }
+}
diff --git a/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj b/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj
index 579196928e45fc..7c219c593107bf 100644
--- a/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj
+++ b/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj
@@ -56,6 +56,7 @@
     <Compile Include="Enumeration\ExampleTests.cs" />
     <Compile Include="Enumeration\RemovedDirectoryTests.cs" />
     <Compile Include="Enumeration\SymbolicLinksTests.cs" />
+    <Compile Include="LargeFileTests.cs" />
     <Compile Include="PathInternalTests.cs" />
     <Compile Include="RandomAccess\Base.cs" />
     <Compile Include="RandomAccess\GetLength.cs" />

From 3c82531eb5e0d773823a0fbe7976f8a508dd1111 Mon Sep 17 00:00:00 2001
From: Adam Sitnik <adam.sitnik@gmail.com>
Date: Wed, 8 Dec 2021 09:45:29 +0100
Subject: [PATCH 2/3] don't run the large file tests in parallel

---
 .../System.IO.FileSystem/tests/LargeFileTests.cs    | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs b/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs
index bed5fbfb4e72f8..0dc3cba322cb2d 100644
--- a/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs
+++ b/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs
@@ -7,11 +7,12 @@
 
 namespace System.IO.FileSystem.Tests
 {
+    [OuterLoop]
+    [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
+    [Collection(nameof(DisableParallelization))] // don't create multiple large files at the same time
     public class LargeFileTests : FileSystemTest
     {
         [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
         public void ReadFileOver2GB()
         {
             string path = GetTestFilePath();
@@ -25,8 +26,6 @@ public void ReadFileOver2GB()
         }
 
         [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
         public void ReadFileOverMaxArrayLength()
         {
             string path = GetTestFilePath();
@@ -40,8 +39,6 @@ public void ReadFileOverMaxArrayLength()
         }
 
         [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
         public async Task ReadFileOver2GBAsync()
         {
             string path = GetTestFilePath();
@@ -55,8 +52,6 @@ public async Task ReadFileOver2GBAsync()
         }
 
         [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
         public async Task ReadFileOverMaxArrayLengthAsync()
         {
             string path = GetTestFilePath();
@@ -70,8 +65,6 @@ public async Task ReadFileOverMaxArrayLengthAsync()
         }
 
         [Fact]
-        [OuterLoop]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)]
         public void NoInt32OverflowInTheBufferingLogic()
         {
             const long position1 = 10;

From 1fb35d55cd1701c2621abbb622225e65627f71d1 Mon Sep 17 00:00:00 2001
From: Adam Sitnik <adam.sitnik@gmail.com>
Date: Thu, 9 Dec 2021 08:29:34 +0100
Subject: [PATCH 3/3] use FileOptions.DeleteOnClose to ensure that each test
 removes it's own file

use single large file to test File.ReadAllBytes and ile.ReadAllBytesAsync for both limits
---
 .../tests/LargeFileTests.cs                   | 54 +++----------------
 .../BufferedStream/BufferedStreamTests.cs     |  2 +-
 2 files changed, 9 insertions(+), 47 deletions(-)

diff --git a/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs b/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs
index 0dc3cba322cb2d..a93d663f4ff881 100644
--- a/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs
+++ b/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs
@@ -13,55 +13,17 @@ namespace System.IO.FileSystem.Tests
     public class LargeFileTests : FileSystemTest
     {
         [Fact]
-        public void ReadFileOver2GB()
+        public async Task ReadAllBytesOverLimit()
         {
-            string path = GetTestFilePath();
-            using (FileStream fs = File.Create(path))
-            {
-                fs.SetLength(int.MaxValue + 1L);
-            }
-
-            // File is too large for ReadAllBytes at once
-            Assert.Throws<IOException>(() => File.ReadAllBytes(path));
-        }
-
-        [Fact]
-        public void ReadFileOverMaxArrayLength()
-        {
-            string path = GetTestFilePath();
-            using (FileStream fs = File.Create(path))
-            {
-                fs.SetLength(Array.MaxLength + 1L);
-            }
-
-            // File is too large for ReadAllBytes at once
-            Assert.Throws<IOException>(() => File.ReadAllBytes(path));
-        }
+            using FileStream fs = new (GetTestFilePath(), FileMode.Create, FileAccess.Write, FileShare.Read, 4096, FileOptions.DeleteOnClose);
 
-        [Fact]
-        public async Task ReadFileOver2GBAsync()
-        {
-            string path = GetTestFilePath();
-            using (FileStream fs = File.Create(path))
+            foreach (long lengthOverLimit in new long[] { Array.MaxLength + 1L, int.MaxValue + 1L })
             {
-                fs.SetLength(int.MaxValue + 1L);
-            }
-
-            // File is too large for ReadAllBytesAsync at once
-            await Assert.ThrowsAsync<IOException>(async () => await File.ReadAllBytesAsync(path));
-        }
+                fs.SetLength(lengthOverLimit);
 
-        [Fact]
-        public async Task ReadFileOverMaxArrayLengthAsync()
-        {
-            string path = GetTestFilePath();
-            using (FileStream fs = File.Create(path))
-            {
-                fs.SetLength(Array.MaxLength + 1L);
+                Assert.Throws<IOException>(() => File.ReadAllBytes(fs.Name));
+                await Assert.ThrowsAsync<IOException>(async () => await File.ReadAllBytesAsync(fs.Name));
             }
-
-            // File is too large for ReadAllBytesAsync at once
-            await Assert.ThrowsAsync<IOException>(async () => await File.ReadAllBytesAsync(path));
         }
 
         [Fact]
@@ -75,7 +37,7 @@ public void NoInt32OverflowInTheBufferingLogic()
             byte[] data2 = new byte[] { 6, 7, 8, 9, 10 };
             byte[] buffer = new byte[5];
 
-            using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+            using (FileStream stream = File.Create(filePath))
             {
                 stream.Seek(position1, SeekOrigin.Begin);
                 stream.Write(data1);
@@ -84,7 +46,7 @@ public void NoInt32OverflowInTheBufferingLogic()
                 stream.Write(data2);
             }
 
-            using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+            using (FileStream stream = new (filePath, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose))
             {
                 stream.Seek(position1, SeekOrigin.Begin);
                 Assert.Equal(buffer.Length, stream.Read(buffer));
diff --git a/src/libraries/System.IO/tests/BufferedStream/BufferedStreamTests.cs b/src/libraries/System.IO/tests/BufferedStream/BufferedStreamTests.cs
index 6294c2f2553d0c..8d11c80336711a 100644
--- a/src/libraries/System.IO/tests/BufferedStream/BufferedStreamTests.cs
+++ b/src/libraries/System.IO/tests/BufferedStream/BufferedStreamTests.cs
@@ -346,7 +346,7 @@ public void NoInt32OverflowInTheBufferingLogic()
                 stream.Write(data2);
             }
 
-            using (var stream = new BufferedStream(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize: 0)))
+            using (var stream = new BufferedStream(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize: 0, FileOptions.DeleteOnClose)))
             {
                 stream.Seek(position1, SeekOrigin.Begin);
                 Assert.Equal(buffer.Length, stream.Read(buffer));
