Skip to content

Commit cfe3ac1

Browse files
author
Ian Hays
authored
Merge pull request dotnet#27216 from ianhays/compressionstream_tests
Fix some compression tests
2 parents e45523d + d87258f commit cfe3ac1

File tree

5 files changed

+42
-132
lines changed

5 files changed

+42
-132
lines changed

src/Common/tests/System/IO/Compression/CompressionStreamPerfTestBase.cs

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,63 +10,46 @@ namespace System.IO.Compression
1010
{
1111
public abstract class CompressionStreamPerfTestBase : CompressionStreamTestBase
1212
{
13-
public static IEnumerable<object[]> CanterburyCorpus_WithCompressionLevel()
13+
public static IEnumerable<object[]> UncompressedTestFiles_WithCompressionLevel()
1414
{
1515
foreach (CompressionLevel compressionLevel in Enum.GetValues(typeof(CompressionLevel)))
1616
{
17-
foreach (object[] canterburyWithoutLevel in CanterburyCorpus())
17+
foreach (object[] testFile in UncompressedTestFiles())
1818
{
19-
yield return new object[] { canterburyWithoutLevel[0], canterburyWithoutLevel[1], compressionLevel };
19+
yield return new object[] { testFile[0], compressionLevel };
2020
}
2121
}
2222
}
2323

24-
public static IEnumerable<object[]> CanterburyCorpus()
25-
{
26-
foreach (int innerIterations in new int[] { 1, 10 })
27-
{
28-
foreach (var fileName in UncompressedTestFiles())
29-
{
30-
yield return new object[] { innerIterations, fileName[0] };
31-
}
32-
}
33-
}
34-
35-
3624
/// <summary>
3725
/// Benchmark tests to measure the performance of individually compressing each file in the
3826
/// Canterbury Corpus
3927
/// </summary>
40-
[Benchmark]
41-
[MemberData(nameof(CanterburyCorpus_WithCompressionLevel))]
42-
public void Compress_Canterbury(int innerIterations, string uncompressedFileName, CompressionLevel compressLevel)
28+
[Benchmark(InnerIterationCount=10)] // limits the max iterations to 100
29+
[MemberData(nameof(UncompressedTestFiles_WithCompressionLevel))]
30+
public void Compress_Canterbury(string uncompressedFileName, CompressionLevel compressLevel)
4331
{
4432
byte[] bytes = File.ReadAllBytes(uncompressedFileName);
45-
MemoryStream[] compressedDataStreams = new MemoryStream[innerIterations];
4633
foreach (var iteration in Benchmark.Iterations)
4734
{
4835
// resizing a memory stream during compression will throw off our results, so pre-size it to the
4936
// size of our input
50-
for (int i = 0; i < innerIterations; i++)
51-
compressedDataStreams[i] = new MemoryStream(bytes.Length);
37+
using (MemoryStream compressedDataStream = new MemoryStream(bytes.Length))
5238
using (iteration.StartMeasurement())
53-
for (int i = 0; i < innerIterations; i++)
54-
using (Stream compressor = CreateStream(compressedDataStreams[i], compressLevel))
55-
compressor.Write(bytes, 0, bytes.Length);
56-
57-
for (int i = 0; i < innerIterations; i++)
58-
compressedDataStreams[i].Dispose();
39+
using (Stream compressor = CreateStream(compressedDataStream, compressLevel))
40+
compressor.Write(bytes, 0, bytes.Length);
5941
}
6042
}
6143

6244
/// <summary>
6345
/// Benchmark tests to measure the performance of individually compressing each file in the
6446
/// Canterbury Corpus
6547
/// </summary>
66-
[Benchmark]
67-
[MemberData(nameof(CanterburyCorpus))]
68-
public void Decompress_Canterbury(int innerIterations, string uncompressedFilePath)
48+
[Benchmark(InnerIterationCount=100)]
49+
[MemberData(nameof(UncompressedTestFiles))]
50+
public void Decompress_Canterbury(string uncompressedFilePath)
6951
{
52+
int innerIterations = (int)Benchmark.InnerIterationCount;
7053
string compressedFilePath = CompressedTestFile(uncompressedFilePath);
7154
byte[] outputRead = new byte[new FileInfo(uncompressedFilePath).Length];
7255
MemoryStream[] memories = new MemoryStream[innerIterations];

src/Common/tests/System/IO/Compression/CompressionStreamUnitTestBase.cs

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -177,48 +177,6 @@ public async Task ReadAsync_DuringReadAsync()
177177
}
178178
}
179179

180-
[Fact]
181-
public virtual void Dispose_WithUnfinishedWriteAsync()
182-
{
183-
byte[] buffer = new byte[100000];
184-
Random rand = new Random();
185-
rand.NextBytes(buffer);
186-
187-
using (var writeStream = new ManualSyncMemoryStream(false))
188-
{
189-
var compressor = CreateStream(writeStream, CompressionMode.Compress, leaveOpen: true);
190-
compressor.Write(buffer, 0, buffer.Length);
191-
int writesBeingFlushed = 2;
192-
Task task = null;
193-
try
194-
{
195-
// Write needs to be big enough to trigger a write to the underlying base stream so the WriteAsync call doesn't immediately complete.
196-
task = compressor.WriteAsync(buffer, 0, buffer.Length);
197-
while (task.IsCompleted)
198-
{
199-
rand.NextBytes(buffer);
200-
task = compressor.WriteAsync(buffer, 0, buffer.Length);
201-
writesBeingFlushed++;
202-
}
203-
204-
// WriteAsync will be blocked on writing the output to the underlying stream. Calling Dispose will trigger a Finish call with unwritten output
205-
// still available.
206-
Assert.InRange(writeStream.Length, 0, buffer.Length);
207-
compressor.Dispose();
208-
Assert.InRange(writeStream.Length, 0, buffer.Length * writesBeingFlushed);
209-
Assert.False(task.IsCompleted);
210-
}
211-
finally
212-
{
213-
// Unblock Async operations
214-
writeStream.manualResetEvent.Set();
215-
// WriteAsync call will return to the compression stream's WriteAsync which will attempt to
216-
// access members of the now disposed stream.
217-
Assert.Throws<AggregateException>(() => task.Wait(1000));
218-
}
219-
}
220-
}
221-
222180
[Fact]
223181
public virtual async Task Dispose_WithUnfinishedReadAsync()
224182
{

src/System.IO.Compression.Brotli/tests/CompressionStreamUnitTests.Brotli.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ public void Precancellation()
3333
}
3434
}
3535

36-
[Fact]
37-
[OuterLoop("Test takes ~12 seconds to run")]
38-
public override void Dispose_WithUnfinishedWriteAsync() { base.Dispose_WithUnfinishedWriteAsync(); }
39-
4036
[Fact]
4137
[OuterLoop("Test takes ~6 seconds to run")]
4238
public override void FlushAsync_DuringWriteAsync() { base.FlushAsync_DuringWriteAsync(); }

src/System.IO.Compression.Brotli/tests/Performance/BrotliPerfTests.cs

Lines changed: 29 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -12,67 +12,48 @@ public class BrotliPerfTests : CompressionTestBase
1212
{
1313
protected override string CompressedTestFile(string uncompressedPath) => Path.Combine("BrotliTestData", Path.GetFileName(uncompressedPath) + ".br");
1414

15-
public static IEnumerable<object[]> CanterburyCorpus_WithCompressionLevel()
15+
public static IEnumerable<object[]> UncompressedTestFiles_WithCompressionLevel()
1616
{
1717
foreach (CompressionLevel compressionLevel in Enum.GetValues(typeof(CompressionLevel)))
1818
{
19-
foreach (object[] canterburyWithoutLevel in CanterburyCorpus())
19+
foreach (object[] testFile in UncompressedTestFiles())
2020
{
21-
yield return new object[] { canterburyWithoutLevel[0], canterburyWithoutLevel[1], compressionLevel };
21+
yield return new object[] { testFile[0], compressionLevel };
2222
}
2323
}
2424
}
2525

26-
public static IEnumerable<object[]> CanterburyCorpus()
27-
{
28-
foreach (int innerIterations in new int[] { 1, 10 })
29-
{
30-
foreach (var fileName in UncompressedTestFiles())
31-
{
32-
yield return new object[] { innerIterations, fileName[0] };
33-
}
34-
}
35-
}
36-
37-
[Benchmark]
38-
[MemberData(nameof(CanterburyCorpus_WithCompressionLevel))]
39-
public void Compress_Canterbury_WithState(int innerIterations, string uncompressedFileName, CompressionLevel compressLevel)
26+
[Benchmark(InnerIterationCount=10)] // limits the max iterations to 100
27+
[MemberData(nameof(UncompressedTestFiles_WithCompressionLevel))]
28+
public void Compress_Canterbury_WithState(string uncompressedFileName, CompressionLevel compressLevel)
4029
{
4130
byte[] bytes = File.ReadAllBytes(uncompressedFileName);
4231
ReadOnlySpan<byte> uncompressedData = new ReadOnlySpan<byte>(bytes);
4332
int maxCompressedSize = BrotliEncoder.GetMaxCompressedLength(bytes.Length);
44-
List<byte[]> compressedDataArrays = new List<byte[]>(innerIterations);
33+
byte[] compressedDataArray = new byte[maxCompressedSize];
4534
foreach (var iteration in Benchmark.Iterations)
4635
{
47-
for (int i = 0; i < innerIterations; i++)
48-
{
49-
compressedDataArrays.Add(new byte[maxCompressedSize]);
50-
}
5136
using (iteration.StartMeasurement())
37+
using (BrotliEncoder encoder = new BrotliEncoder())
5238
{
53-
for (int i = 0; i < innerIterations; i++)
39+
Span<byte> output = new Span<byte>(compressedDataArray);
40+
ReadOnlySpan<byte> input = uncompressedData;
41+
while (!input.IsEmpty && !output.IsEmpty)
5442
{
55-
using (BrotliEncoder encoder = new BrotliEncoder())
56-
{
57-
Span<byte> output = new Span<byte>(compressedDataArrays[i]);
58-
ReadOnlySpan<byte> input = uncompressedData;
59-
while (!input.IsEmpty && !output.IsEmpty)
60-
{
61-
encoder.Compress(input, output, out int bytesConsumed, out int written, isFinalBlock:false);
62-
input = input.Slice(bytesConsumed);
63-
output = output.Slice(written);
64-
}
65-
encoder.Compress(input, output, out int bytesConsumed2, out int written2, isFinalBlock: true);
66-
}
43+
encoder.Compress(input, output, out int bytesConsumed, out int written, isFinalBlock:false);
44+
input = input.Slice(bytesConsumed);
45+
output = output.Slice(written);
6746
}
47+
encoder.Compress(input, output, out int bytesConsumed2, out int written2, isFinalBlock: true);
6848
}
6949
}
7050
}
7151

72-
[Benchmark]
73-
[MemberData(nameof(CanterburyCorpus))]
74-
public void Decompress_Canterbury_WithState(int innerIterations, string uncompressedFileName)
52+
[Benchmark(InnerIterationCount=100)]
53+
[MemberData(nameof(UncompressedTestFiles))]
54+
public void Decompress_Canterbury_WithState(string uncompressedFileName)
7555
{
56+
int innerIterations = (int)Benchmark.InnerIterationCount;
7657
byte[] compressedBytes = File.ReadAllBytes(CompressedTestFile(uncompressedFileName));
7758
ReadOnlySpan<byte> compressedData = new ReadOnlySpan<byte>(compressedBytes);
7859
List<byte[]> uncompressedDataArrays = new List<byte[]>(innerIterations);
@@ -102,27 +83,20 @@ public void Decompress_Canterbury_WithState(int innerIterations, string uncompre
10283
}
10384
}
10485

105-
[Benchmark]
106-
[MemberData(nameof(CanterburyCorpus_WithCompressionLevel))]
107-
public void Compress_Canterbury_WithoutState(int innerIterations, string uncompressedFileName, CompressionLevel compressLevel)
86+
[Benchmark(InnerIterationCount=10)] // limits the max iterations to 100
87+
[MemberData(nameof(UncompressedTestFiles_WithCompressionLevel))]
88+
public void Compress_Canterbury_WithoutState(string uncompressedFileName, CompressionLevel compressLevel)
10889
{
10990
byte[] bytes = File.ReadAllBytes(uncompressedFileName);
11091
ReadOnlySpan<byte> uncompressedData = new ReadOnlySpan<byte>(bytes);
11192
int maxCompressedSize = BrotliEncoder.GetMaxCompressedLength(bytes.Length);
112-
List<byte[]> compressedDataArrays = new List<byte[]>(innerIterations);
93+
byte[] compressedDataArray = new byte[maxCompressedSize];
11394
int compressLevelBrotli = compressLevel == CompressionLevel.Optimal ? 11 : compressLevel == CompressionLevel.Fastest ? 1 : 0;
11495
foreach (var iteration in Benchmark.Iterations)
11596
{
116-
for (int i = 0; i < innerIterations; i++)
117-
{
118-
compressedDataArrays.Add(new byte[maxCompressedSize]);
119-
}
12097
using (iteration.StartMeasurement())
12198
{
122-
for (int i = 0; i < innerIterations; i++)
123-
{
124-
Assert.True(BrotliEncoder.TryCompress(uncompressedData, compressedDataArrays[i], out int bytesWritten, compressLevelBrotli, 22));
125-
}
99+
Assert.True(BrotliEncoder.TryCompress(uncompressedData, compressedDataArray, out int bytesWritten, compressLevelBrotli, 22));
126100
}
127101
}
128102
}
@@ -131,10 +105,11 @@ public void Compress_Canterbury_WithoutState(int innerIterations, string uncompr
131105
/// The perf tests for the instant decompression aren't exactly indicative of real-world scenarios since they require you to know
132106
/// either the exact figure or the upper bound of the uncompressed size of your given compressed data.
133107
/// </summary>
134-
[Benchmark]
135-
[MemberData(nameof(CanterburyCorpus))]
136-
public void Decompress_Canterbury_WithoutState(int innerIterations, string uncompressedFileName)
108+
[Benchmark(InnerIterationCount=100)]
109+
[MemberData(nameof(UncompressedTestFiles))]
110+
public void Decompress_Canterbury_WithoutState(string uncompressedFileName)
137111
{
112+
int innerIterations = (int)Benchmark.InnerIterationCount;
138113
byte[] compressedBytes = File.ReadAllBytes(CompressedTestFile(uncompressedFileName));
139114
ReadOnlySpan<byte> compressedData = new ReadOnlySpan<byte>(compressedBytes);
140115
int uncompressedSize = (int)new FileInfo(uncompressedFileName).Length;
@@ -153,6 +128,6 @@ public void Decompress_Canterbury_WithoutState(int innerIterations, string uncom
153128
}
154129
}
155130
}
156-
}
131+
}
157132
}
158133
}

src/System.IO.Compression.Brotli/tests/Performance/System.IO.Compression.Brotli.Performance.Tests.csproj

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Debug|AnyCPU'" />
1212
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Release|AnyCPU'" />
1313
<ItemGroup>
14-
<!-- [ActiveIssue(26566)]
1514
<Compile Include="BrotliPerfTests.cs" />
1615
<Compile Include="CompressionStreamPerfTests.Brotli.cs" />
1716
<Compile Include="$(CommonTestPath)\System\IO\Compression\CompressionStreamTestBase.cs">
@@ -20,7 +19,6 @@
2019
<Compile Include="$(CommonTestPath)\System\IO\Compression\CompressionStreamPerfTestBase.cs">
2120
<Link>Common\System\IO\Compression\CompressionStreamPerfTestBase.cs</Link>
2221
</Compile>
23-
-->
2422
</ItemGroup>
2523
<ItemGroup>
2624
<SupplementalTestData Include="$(PackagesDir)system.io.compression.testdata\1.0.6-prerelease\content\**\*.*">

0 commit comments

Comments
 (0)