From 3b71fd8b7b5b8ddf7aeece6a7296f408b7e1fd1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Cant=C3=BA?= Date: Thu, 30 Dec 2021 20:10:51 -0800 Subject: [PATCH] [release/6.0] Don't create multiple large files at the same time (#63032) * Move NoInt32OverflowInTheBufferingLogic to OuterLoop and address pending feedback (#60606) * Don't create multiple large files at the same time (#62519) * move existing large file tests into a separate type (no code changes) * don't run the large file tests in parallel * 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 * Fix DisableParallelization build issue * Apply suggestions from code review Co-authored-by: Adam Sitnik * Update src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs Co-authored-by: Adam Sitnik * Notepad with uppercase (#62487) Co-authored-by: Adam Sitnik Co-authored-by: Dan Moseley --- .../tests/ProcessStartInfoTests.cs | 2 +- .../tests/ProcessTests.cs | 15 +++-- .../tests/File/ReadWriteAllBytes.cs | 15 ----- .../tests/File/ReadWriteAllBytesAsync.cs | 16 ----- .../tests/FileStream/Read.cs | 44 ------------- .../tests/LargeFileTests.cs | 64 +++++++++++++++++++ .../tests/System.IO.FileSystem.Tests.csproj | 1 + .../BufferedStream/BufferedStreamTests.cs | 34 ++++++++++ 8 files changed, 110 insertions(+), 81 deletions(-) create mode 100644 src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs index 38062773cb367..6f304b08989f5 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs @@ -1318,7 +1318,7 @@ private void VerifyNotepadMainWindowTitle(Process process, string filename) string expected = Path.GetFileNameWithoutExtension(filename); process.WaitForInputIdle(); // Give the file a chance to load - Assert.Equal("notepad", process.ProcessName); + Assert.Equal("notepad", process.ProcessName.ToLower()); // Notepad calls CreateWindowEx with pWindowName of empty string, then calls SetWindowTextW // with "Untitled - Notepad" then finally if you're opening a file, calls SetWindowTextW diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs index 880da43a64653..71e27ea0d9cf9 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs @@ -267,11 +267,16 @@ public void ProcessStart_UseShellExecute_OnWindows_DoesNotThrow(bool isFolder) { if (px != null) // sometimes process is null { - Assert.Equal("notepad", px.ProcessName); - - px.Kill(); - Assert.True(px.WaitForExit(WaitInMS)); - px.WaitForExit(); // wait for event handlers to complete + try + { + Assert.Equal("notepad", px.ProcessName.ToLower()); + } + finally + { + px.Kill(); + Assert.True(px.WaitForExit(WaitInMS)); + px.WaitForExit(); // wait for event handlers to complete + } } } } diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs index 5dd2e3f1bda6d..a7815dd40eb12 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs @@ -57,21 +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(() => 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 be562f15ca953..c4f147cbb8009 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,21 +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 Task ReadFileOver2GBAsync() - { - string path = GetTestFilePath(); - using (FileStream fs = File.Create(path)) - { - fs.SetLength(int.MaxValue + 1L); - } - - // File is too large for ReadAllBytes at once - return Assert.ThrowsAsync(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 fec3a7a84e2f1..b6c555920bca3 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/Read.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/Read.cs @@ -14,49 +14,5 @@ public void NegativeReadRootThrows() Assert.Throws(() => new FileStream(Path.GetPathRoot(Directory.GetCurrentDirectory()), FileMode.Open, FileAccess.Read)); } - - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] - [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, 0, data1.Length); - - stream.Seek(position2, SeekOrigin.Begin); - stream.Write(data2, 0, data2.Length); - } - - 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); - } - - using (var stream = new BufferedStream(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize: 0))) - { - 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 0000000000000..c8158f8b97784 --- /dev/null +++ b/src/libraries/System.IO.FileSystem/tests/LargeFileTests.cs @@ -0,0 +1,64 @@ +// 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 +{ + [OuterLoop] + [ActiveIssue("https://github.com/dotnet/runtime/issues/45954", TestPlatforms.Browser)] + [Collection(nameof(NoParallelTests))] // don't create multiple large files at the same time + public class LargeFileTests : FileSystemTest + { + [Fact] + public async Task ReadAllBytesOverLimit() + { + using FileStream fs = new (GetTestFilePath(), FileMode.Create, FileAccess.Write, FileShare.Read, 4096, FileOptions.DeleteOnClose); + + foreach (long lengthOverLimit in new long[] { int.MaxValue + 1L }) + { + fs.SetLength(lengthOverLimit); + + Assert.Throws(() => File.ReadAllBytes(fs.Name)); + await Assert.ThrowsAsync(async () => await File.ReadAllBytesAsync(fs.Name)); + } + } + + [Fact] + 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 (FileStream stream = File.Create(filePath)) + { + stream.Seek(position1, SeekOrigin.Begin); + stream.Write(data1); + + stream.Seek(position2, SeekOrigin.Begin); + stream.Write(data2); + } + + 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)); + Assert.Equal(data1, buffer); + + stream.Seek(position2, SeekOrigin.Begin); + Assert.Equal(buffer.Length, stream.Read(buffer)); + Assert.Equal(data2, buffer); + } + } + } + + [CollectionDefinition(nameof(NoParallelTests), DisableParallelization = true)] + public partial class NoParallelTests { } +} 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 ea17b396daa30..1ffb30f887c24 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 @@ -55,6 +55,7 @@ + diff --git a/src/libraries/System.IO/tests/BufferedStream/BufferedStreamTests.cs b/src/libraries/System.IO/tests/BufferedStream/BufferedStreamTests.cs index 0826875520205..8d11c80336711 100644 --- a/src/libraries/System.IO/tests/BufferedStream/BufferedStreamTests.cs +++ b/src/libraries/System.IO/tests/BufferedStream/BufferedStreamTests.cs @@ -323,6 +323,40 @@ public async Task CopyToTest_ReadBeforeCopy_CopiesAllData(bool copyAsynchronousl Array.Copy(data, 1, expected, 0, expected.Length); Assert.Equal(expected, dst.ToArray()); } + + [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 = Path.GetTempFileName(); + 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 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)); + Assert.Equal(data1, buffer); + + stream.Seek(position2, SeekOrigin.Begin); + Assert.Equal(buffer.Length, stream.Read(buffer)); + Assert.Equal(data2, buffer); + } + } } public class BufferedStream_TestLeaveOpen : TestLeaveOpen