From 6187fdfad1cc8670454a80776f0ee6a43a979fba Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Wed, 9 Mar 2022 15:46:58 +0100 Subject: [PATCH] Reduce the amount of memory allocated by System.IO.Tests (#66387) * use 2.1 GB instead 6.5 GB to verify lack of Int32 overflow: reduce the size use same memory for input and output * use SkipTestException to indicate that the test has been skipped * don't run WriteChars_VeryLargeArray_DoesNotOverflow with other tests in parallel, as it can cause OOM * move the test to Outerloop as suggested by Stephen --- .../BinaryWriter/BinaryWriter.EncodingTests.cs | 32 ++++++++++++---------- .../System.IO/tests/System.IO.Tests.csproj | 3 +- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/libraries/System.IO/tests/BinaryWriter/BinaryWriter.EncodingTests.cs b/src/libraries/System.IO/tests/BinaryWriter/BinaryWriter.EncodingTests.cs index 6a41e67..632aac0 100644 --- a/src/libraries/System.IO/tests/BinaryWriter/BinaryWriter.EncodingTests.cs +++ b/src/libraries/System.IO/tests/BinaryWriter/BinaryWriter.EncodingTests.cs @@ -5,10 +5,14 @@ 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 { [Fact] @@ -187,40 +191,40 @@ namespace System.IO.Tests Assert.Equal(expectedBytes, stream.GetBuffer()[Get7BitEncodedIntByteLength((uint)expectedBytes.Length)..(int)stream.Length]); } + [OuterLoop("Allocates a lot of memory")] [Fact] [SkipOnPlatform(TestPlatforms.Android, "OOM on Android could be uncatchable & kill the test runner")] public unsafe void WriteChars_VeryLargeArray_DoesNotOverflow() { - const nuint INPUT_LEN_IN_CHARS = 1_500_000_000; - const nuint OUTPUT_LEN_IN_BYTES = 3_500_000_000; // overallocate + const nuint INT32_OVERFLOW_SIZE = (nuint)int.MaxValue + 3; - SafeBuffer unmanagedInputBuffer = null; - SafeBuffer unmanagedOutputBufer = null; + SafeBuffer unmanagedBuffer = null; try { try { - unmanagedInputBuffer = SafeBufferUtil.CreateSafeBuffer(INPUT_LEN_IN_CHARS * sizeof(char)); - unmanagedOutputBufer = SafeBufferUtil.CreateSafeBuffer(OUTPUT_LEN_IN_BYTES * sizeof(byte)); + unmanagedBuffer = SafeBufferUtil.CreateSafeBuffer(INT32_OVERFLOW_SIZE * sizeof(byte)); } catch (OutOfMemoryException) { - return; // skip test in low-mem conditions + throw new SkipTestException($"Unable to execute {nameof(WriteChars_VeryLargeArray_DoesNotOverflow)} due to OOM"); // skip test in low-mem conditions } - Span inputSpan = new Span((char*)unmanagedInputBuffer.DangerousGetHandle(), (int)INPUT_LEN_IN_CHARS); - inputSpan.Fill('\u0224'); // LATIN CAPITAL LETTER Z WITH HOOK - Stream outStream = new UnmanagedMemoryStream(unmanagedOutputBufer, 0, (long)unmanagedOutputBufer.ByteLength, FileAccess.ReadWrite); + Assert.True((long)unmanagedBuffer.ByteLength > int.MaxValue); + + // reuse same memory for input and output to avoid allocating more memory and OOMs + Span span = new Span((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(inputSpan); // will write 3 billion bytes to the output + writer.Write(span); // will write slightly more than int.MaxValue bytes to the output - Assert.Equal(3_000_000_000, outStream.Position); + Assert.Equal((long)INT32_OVERFLOW_SIZE, outStream.Position); } finally { - unmanagedInputBuffer?.Dispose(); - unmanagedOutputBufer?.Dispose(); + unmanagedBuffer?.Dispose(); } } diff --git a/src/libraries/System.IO/tests/System.IO.Tests.csproj b/src/libraries/System.IO/tests/System.IO.Tests.csproj index aa8928e..9014ff2 100644 --- a/src/libraries/System.IO/tests/System.IO.Tests.csproj +++ b/src/libraries/System.IO/tests/System.IO.Tests.csproj @@ -1,4 +1,4 @@ - + System.IO true @@ -44,6 +44,7 @@ + -- 2.7.4