diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendFile.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendFile.cs index cda5d75b48c303..aa0d967e9f783d 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendFile.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendFile.cs @@ -235,45 +235,6 @@ public async Task SliceBuffers_Success() } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/42534", TestPlatforms.Windows)] - [OuterLoop("Creates and sends a file several gigabytes long")] - [Fact] - public async Task GreaterThan2GBFile_SendsAllBytes() - { - const long FileLength = 100L + int.MaxValue; - - using var tmpFile = TempFile.Create(); - using (FileStream fs = File.Create(tmpFile.Path)) - { - fs.SetLength(FileLength); - } - - using var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - using var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - listener.BindToAnonymousPort(IPAddress.Loopback); - listener.Listen(1); - - client.Connect(listener.LocalEndPoint); - using Socket server = listener.Accept(); - - await new Task[] - { - SendFileAsync(server, tmpFile.Path), - Task.Run(() => - { - byte[] buffer = new byte[100_000]; - long count = 0; - while (count < FileLength) - { - int received = client.Receive(buffer); - Assert.NotEqual(0, received); - count += received; - } - Assert.Equal(0, client.Available); - }) - }.WhenAllOrAnyFailed(); - } - [Fact] public async Task SendFileGetsCanceledByDispose() { @@ -503,4 +464,78 @@ public void EndSendFile_NullAsyncResult_Throws() Assert.Throws(() => s.EndSendFile(null)); } } + + // Running all cases of GreaterThan2GBFile_SendsAllBytes in parallel may attempt to allocate Min(ProcessorCount, Subclass_Count) * 2GB of disk space + // in extreme cases. Some CI machines may run out of disk space if this happens. + [Collection(nameof(NoParallelTests))] + public abstract class SendFile_NonParallel : SocketTestHelperBase where T : SocketHelperBase, new() + { + protected SendFile_NonParallel(ITestOutputHelper output) : base(output) + { + } + + [ActiveIssue("https://github.com/dotnet/runtime/issues/42534", TestPlatforms.Windows)] + [OuterLoop("Creates and sends a file several gigabytes long")] + [Fact] + public async Task GreaterThan2GBFile_SendsAllBytes() + { + const long FileLength = 100L + int.MaxValue; + + using var tmpFile = TempFile.Create(); + using (FileStream fs = File.Create(tmpFile.Path)) + { + fs.SetLength(FileLength); + } + + using var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + using var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + listener.BindToAnonymousPort(IPAddress.Loopback); + listener.Listen(1); + + client.Connect(listener.LocalEndPoint); + using Socket server = listener.Accept(); + + await new Task[] + { + SendFileAsync(server, tmpFile.Path), + Task.Run(() => + { + byte[] buffer = new byte[100_000]; + long count = 0; + while (count < FileLength) + { + int received = client.Receive(buffer); + Assert.NotEqual(0, received); + count += received; + } + Assert.Equal(0, client.Available); + }) + }.WhenAllOrAnyFailed(); + } + } + + public sealed class SendFile_NonParallel_SyncSpan : SendFile_NonParallel + { + public SendFile_NonParallel_SyncSpan(ITestOutputHelper output) : base(output) { } + } + + public sealed class SendFile_NonParallel_SyncSpanForceNonBlocking : SendFile_NonParallel + { + public SendFile_NonParallel_SyncSpanForceNonBlocking(ITestOutputHelper output) : base(output) { } + } + + public sealed class SendFile_NonParallel_ArraySync : SendFile_NonParallel + { + public SendFile_NonParallel_ArraySync(ITestOutputHelper output) : base(output) { } + } + + public sealed class SendFile_NonParallel_Task : SendFile_NonParallel + { + public SendFile_NonParallel_Task(ITestOutputHelper output) : base(output) { } + } + + public sealed class SendFile_NonParallel_Apm : SendFile_NonParallel + { + public SendFile_NonParallel_Apm(ITestOutputHelper output) : base(output) { } + } }