Run large file test on its own (#67857)
authorDan Moseley <danmose@microsoft.com>
Tue, 12 Apr 2022 06:45:45 +0000 (00:45 -0600)
committerGitHub <noreply@github.com>
Tue, 12 Apr 2022 06:45:45 +0000 (08:45 +0200)
* Segregate large file StreamReader test

* Extract just problematic test from BinaryWriter.Encoding tests

src/libraries/System.IO/tests/BinaryWriter/BinaryWriter.EncodingTests.cs
src/libraries/System.IO/tests/BinaryWriter/BinaryWriter.EncodingTests_Serial.cs [new file with mode: 0644]
src/libraries/System.IO/tests/StreamReader/StreamReaderTests.cs
src/libraries/System.IO/tests/StreamReader/StreamReaderTests_Serial.cs [new file with mode: 0644]
src/libraries/System.IO/tests/System.IO.Tests.csproj

index 88a6b62..43e5441 100644 (file)
@@ -10,9 +10,6 @@ using Xunit;
 
 namespace System.IO.Tests
 {
-    // WriteChars_VeryLargeArray_DoesNotOverflow allocates a lot of memory and can cause OOM,
-    // it should not be executed in parallel with other tests
-    [Collection(nameof(DisableParallelization))]
     public class BinaryWriter_EncodingTests
     {
         [Fact]
@@ -191,43 +188,6 @@ namespace System.IO.Tests
             Assert.Equal(expectedBytes, stream.GetBuffer()[Get7BitEncodedIntByteLength((uint)expectedBytes.Length)..(int)stream.Length]);
         }
 
-        [OuterLoop("Allocates a lot of memory")]
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))]
-        [SkipOnPlatform(TestPlatforms.Android, "OOM on Android could be uncatchable & kill the test runner")]
-        public unsafe void WriteChars_VeryLargeArray_DoesNotOverflow()
-        {
-            const nuint INT32_OVERFLOW_SIZE = (nuint)int.MaxValue + 3;
-
-            SafeBuffer unmanagedBuffer = null;
-            try
-            {
-                try
-                {
-                    unmanagedBuffer = SafeBufferUtil.CreateSafeBuffer(INT32_OVERFLOW_SIZE * sizeof(byte));
-                }
-                catch (OutOfMemoryException)
-                {
-                    throw new SkipTestException($"Unable to execute {nameof(WriteChars_VeryLargeArray_DoesNotOverflow)} due to OOM"); // skip test in low-mem conditions
-                }
-
-                Assert.True((long)unmanagedBuffer.ByteLength > int.MaxValue);
-
-                // reuse same memory for input and output to avoid allocating more memory and OOMs
-                Span<char> span = new Span<char>((char*)unmanagedBuffer.DangerousGetHandle(), (int)(INT32_OVERFLOW_SIZE / sizeof(char)));
-                span.Fill('\u0224'); // LATIN CAPITAL LETTER Z WITH HOOK
-                Stream outStream = new UnmanagedMemoryStream(unmanagedBuffer, 0, (long)unmanagedBuffer.ByteLength, FileAccess.ReadWrite);
-                BinaryWriter writer = new BinaryWriter(outStream);
-
-                writer.Write(span); // will write slightly more than int.MaxValue bytes to the output
-
-                Assert.Equal((long)INT32_OVERFLOW_SIZE, outStream.Position);
-            }
-            finally
-            {
-                unmanagedBuffer?.Dispose();
-            }
-        }
-
         private static bool IsUsingFastUtf8(BinaryWriter writer)
         {
             return (bool)writer.GetType().GetField("_useFastUtf8", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(writer);
diff --git a/src/libraries/System.IO/tests/BinaryWriter/BinaryWriter.EncodingTests_Serial.cs b/src/libraries/System.IO/tests/BinaryWriter/BinaryWriter.EncodingTests_Serial.cs
new file mode 100644 (file)
index 0000000..90ad549
--- /dev/null
@@ -0,0 +1,55 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Numerics;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using Microsoft.DotNet.XUnitExtensions;
+using Xunit;
+
+namespace System.IO.Tests
+{
+    // WriteChars_VeryLargeArray_DoesNotOverflow allocates a lot of memory and can cause OOM,
+    // it should not be executed in parallel with other tests
+    [Collection(nameof(DisableParallelization))]
+    public class BinaryWriter_EncodingTests_Serial
+    {
+        [OuterLoop("Allocates a lot of memory")]
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))]
+        [SkipOnPlatform(TestPlatforms.Android, "OOM on Android could be uncatchable & kill the test runner")]
+        public unsafe void WriteChars_VeryLargeArray_DoesNotOverflow()
+        {
+            const nuint INT32_OVERFLOW_SIZE = (nuint)int.MaxValue + 3;
+
+            SafeBuffer unmanagedBuffer = null;
+            try
+            {
+                try
+                {
+                    unmanagedBuffer = SafeBufferUtil.CreateSafeBuffer(INT32_OVERFLOW_SIZE * sizeof(byte));
+                }
+                catch (OutOfMemoryException)
+                {
+                    throw new SkipTestException($"Unable to execute {nameof(WriteChars_VeryLargeArray_DoesNotOverflow)} due to OOM"); // skip test in low-mem conditions
+                }
+
+                Assert.True((long)unmanagedBuffer.ByteLength > int.MaxValue);
+
+                // reuse same memory for input and output to avoid allocating more memory and OOMs
+                Span<char> span = new Span<char>((char*)unmanagedBuffer.DangerousGetHandle(), (int)(INT32_OVERFLOW_SIZE / sizeof(char)));
+                span.Fill('\u0224'); // LATIN CAPITAL LETTER Z WITH HOOK
+                Stream outStream = new UnmanagedMemoryStream(unmanagedBuffer, 0, (long)unmanagedBuffer.ByteLength, FileAccess.ReadWrite);
+                BinaryWriter writer = new BinaryWriter(outStream);
+
+                writer.Write(span); // will write slightly more than int.MaxValue bytes to the output
+
+                Assert.Equal((long)INT32_OVERFLOW_SIZE, outStream.Position);
+            }
+            finally
+            {
+                unmanagedBuffer?.Dispose();
+            }
+        }
+    }
+}
index 89ee53b..810cbe5 100644 (file)
@@ -132,61 +132,6 @@ namespace System.IO.Tests
             Assert.Equal(token, ex.CancellationToken);
         }
 
-        [OuterLoop("It creates 1GB file")]
-        [Fact]
-        [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser.")]
-        public async Task ReadToEndAsync_WithCancellation()
-        {
-            string path = GetTestFilePath();
-            CreateLargeFile(path);
-
-            using StreamReader reader = File.OpenText(path);
-            using CancellationTokenSource cts = new();
-            var token = cts.Token;
-
-            var ex = await Assert.ThrowsAnyAsync<OperationCanceledException>(async () =>
-            {
-                Task<string> readToEndTask = reader.ReadToEndAsync(token);
-
-                // This is a time-sensitive test where the cancellation needs to happen before the async read completes.
-                // A sleep may be too long a delay, so spin-wait for a very short duration before canceling.
-                SpinWait spinner = default;
-                while (!spinner.NextSpinWillYield)
-                {
-                    spinner.SpinOnce(sleep1Threshold: -1);
-                }
-
-                cts.Cancel();
-                await readToEndTask;
-            });
-            Assert.Equal(token, ex.CancellationToken);
-        }
-
-        private void CreateLargeFile(string path)
-        {
-            const string sentence = "A very large file used for testing StreamReader cancellation. 0123456789012345678901234567890123456789.";
-            const int repeatCount = 10_000_000;
-            Encoding encoding = Encoding.UTF8;
-
-            using FileStream fs = File.OpenWrite(path);
-            long fileSize = encoding.GetByteCount(sentence) * repeatCount;
-
-            try
-            {
-                fs.SetLength(fileSize);
-            }
-            catch (IOException)
-            {
-                throw new SkipTestException($"Unable to run {ReadToEndAsync_WithCancellation} due to lack of available disk space");
-            }
-
-            using StreamWriter streamWriter = new StreamWriter(fs, encoding);
-            for (int i = 0; i < repeatCount; i++)
-            {
-                streamWriter.WriteLine(sentence);
-            }
-        }
-
         [Fact]
         public void GetBaseStream()
         {
diff --git a/src/libraries/System.IO/tests/StreamReader/StreamReaderTests_Serial.cs b/src/libraries/System.IO/tests/StreamReader/StreamReaderTests_Serial.cs
new file mode 100644 (file)
index 0000000..990bbbc
--- /dev/null
@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.IO.Pipes;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.DotNet.XUnitExtensions;
+using Xunit;
+
+namespace System.IO.Tests
+{
+    // Run these tests on their own as they use a lot of disk space
+    [Collection(nameof(DisableParallelization))]
+    public partial class StreamReaderTests_Serial : FileCleanupTestBase
+    {
+        [OuterLoop("It creates 1GB file")]
+        [Fact]
+        [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser.")]
+        public async Task ReadToEndAsync_WithCancellation()
+        {
+            string path = GetTestFilePath();
+            CreateLargeFile(path);
+
+            using StreamReader reader = File.OpenText(path);
+            using CancellationTokenSource cts = new();
+            var token = cts.Token;
+
+            var ex = await Assert.ThrowsAnyAsync<OperationCanceledException>(async () =>
+            {
+                Task<string> readToEndTask = reader.ReadToEndAsync(token);
+
+                // This is a time-sensitive test where the cancellation needs to happen before the async read completes.
+                // A sleep may be too long a delay, so spin-wait for a very short duration before canceling.
+                SpinWait spinner = default;
+                while (!spinner.NextSpinWillYield)
+                {
+                    spinner.SpinOnce(sleep1Threshold: -1);
+                }
+
+                cts.Cancel();
+                await readToEndTask;
+            });
+            Assert.Equal(token, ex.CancellationToken);
+        }
+
+        private void CreateLargeFile(string path)
+        {
+            const string sentence = "A very large file used for testing StreamReader cancellation. 0123456789012345678901234567890123456789.";
+            const int repeatCount = 10_000_000;
+            Encoding encoding = Encoding.UTF8;
+
+            using FileStream fs = File.OpenWrite(path);
+            long fileSize = encoding.GetByteCount(sentence) * repeatCount;
+
+            try
+            {
+                fs.SetLength(fileSize);
+            }
+            catch (IOException)
+            {
+                throw new SkipTestException($"Unable to run {ReadToEndAsync_WithCancellation} due to lack of available disk space");
+            }
+
+            using StreamWriter streamWriter = new StreamWriter(fs, encoding);
+            for (int i = 0; i < repeatCount; i++)
+            {
+                streamWriter.WriteLine(sentence);
+            }
+        }
+    }
+}
index 9014ff2..35bba18 100644 (file)
@@ -17,6 +17,7 @@
     <Compile Include="StreamWriter\StreamWriter.StringCtorTests.cs" />
     <Compile Include="BinaryWriter\BinaryWriter.DisposeAsync.cs" />
     <Compile Include="BinaryWriter\BinaryWriter.EncodingTests.cs" />
+    <Compile Include="BinaryWriter\BinaryWriter.EncodingTests_Serial.cs" />
     <Compile Include="BinaryWriter\BinaryWriter.WriteByteCharTests.cs" />
     <Compile Include="BinaryWriter\BinaryWriter.WriteTests.cs" />
     <Compile Include="BinaryWriter\BinaryWriterTests.cs" />
@@ -28,6 +29,7 @@
     <Compile Include="MemoryStream\MemoryStreamTests.cs" />
     <Compile Include="StreamReader\StreamReader.CtorTests.cs" />
     <Compile Include="StreamReader\StreamReaderTests.cs" />
+    <Compile Include="StreamReader\StreamReaderTests_Serial.cs" />
     <Compile Include="StreamWriter\StreamWriter.BaseStream.cs" />
     <Compile Include="StreamWriter\StreamWriter.CloseTests.cs" />
     <Compile Include="StreamWriter\StreamWriter.CtorTests.cs" />