Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 344b712

Browse files
committed
Merge pull request #1924 from stephentoub/compression_managed_zlib
Test both managed/zlib System.IO.Compression implementations
2 parents 863339a + 6c120e2 commit 344b712

File tree

6 files changed

+155
-69
lines changed

6 files changed

+155
-69
lines changed

src/System.IO.Compression/src/System/IO/Compression/DeflateStream.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,13 @@ public partial class DeflateStream : Stream
2525
private bool _wroteHeader;
2626
private bool _wroteBytes;
2727

28-
private enum WorkerType : byte { Managed, ZLib, Unknown };
28+
private enum WorkerType : byte { Unknown = 0, Managed = 1, ZLib = 2 };
2929
private static readonly WorkerType s_deflaterType = GetDeflaterType();
30+
#if DEBUG
31+
// This field is used for testing purposes and is accessed via reflection.
32+
// NOTE: If the name of this field changes, the test must also be updated.
33+
private static WorkerType s_forcedTestingDeflaterType = WorkerType.Unknown;
34+
#endif
3035

3136
public DeflateStream(Stream stream, CompressionMode mode)
3237
: this(stream, mode, false)
@@ -105,7 +110,17 @@ public DeflateStream(Stream stream, CompressionLevel compressionLevel, bool leav
105110

106111
private static IDeflater CreateDeflater(CompressionLevel? compressionLevel)
107112
{
108-
switch (s_deflaterType)
113+
// The deflator type (zlib or managed) is normally determined by s_deflatorType,
114+
// which is initialized by the provider based on what's available on the system.
115+
// But for testing purposes, we sometimes want to override this, forcing
116+
// compression/decompression to use a particular type.
117+
WorkerType deflatorType = s_deflaterType;
118+
#if DEBUG
119+
if (s_forcedTestingDeflaterType != WorkerType.Unknown)
120+
deflatorType = s_forcedTestingDeflaterType;
121+
#endif
122+
123+
switch (deflatorType)
109124
{
110125
case WorkerType.Managed:
111126
return new DeflaterManaged();
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.Reflection;
5+
6+
namespace System.IO.Compression.Tests
7+
{
8+
internal static class Common
9+
{
10+
internal static void SetDeflaterMode(string mode)
11+
{
12+
const string fieldName = "s_forcedTestingDeflaterType";
13+
FieldInfo forceType = typeof(DeflateStream).GetTypeInfo().GetDeclaredField(fieldName);
14+
if (forceType != null)
15+
{
16+
forceType.SetValue(null, mode == "zlib" ? (byte)2 : mode == "managed" ? (byte)1 : (byte)0);
17+
}
18+
else if (mode == "zlib" || mode == "managed")
19+
{
20+
Console.Error.WriteLine("Could not change deflater type to " + mode + ": missing " + fieldName);
21+
}
22+
}
23+
}
24+
}

src/System.IO.Compression/tests/DeflateStreamTests.cs

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4-
using System;
5-
using System.Collections.Generic;
4+
using System.Reflection;
65
using System.Text;
76
using System.Threading.Tasks;
8-
using System.IO;
9-
using System.Reflection;
10-
using System.IO.Compression;
117
using Xunit;
128

139
namespace System.IO.Compression.Tests
1410
{
15-
public partial class DeflateStreamTests
11+
public class ZLibDeflateStreamTests : DeflateStreamTests, IDisposable
12+
{
13+
public ZLibDeflateStreamTests() { Common.SetDeflaterMode("zlib"); }
14+
public void Dispose() { Common.SetDeflaterMode("unknown"); }
15+
}
16+
17+
public class ManagedDeflateStreamTests : DeflateStreamTests, IDisposable
18+
{
19+
public ManagedDeflateStreamTests() { Common.SetDeflaterMode("managed"); }
20+
public void Dispose() { Common.SetDeflaterMode("unknown"); }
21+
}
22+
23+
public abstract class DeflateStreamTests
1624
{
1725
static string gzTestFile(String fileName) { return Path.Combine("GZTestData", fileName); }
1826

1927
[Fact]
20-
public static void BaseStream1()
28+
public void BaseStream1()
2129
{
2230
var writeStream = new MemoryStream();
2331
var zip = new DeflateStream(writeStream, CompressionMode.Compress);
@@ -27,7 +35,7 @@ public static void BaseStream1()
2735
}
2836

2937
[Fact]
30-
public static void BaseStream2()
38+
public void BaseStream2()
3139
{
3240
var ms = new MemoryStream();
3341
var zip = new DeflateStream(ms, CompressionMode.Decompress);
@@ -37,7 +45,7 @@ public static void BaseStream2()
3745
}
3846

3947
[Fact]
40-
public static async Task ModifyBaseStream()
48+
public async Task ModifyBaseStream()
4149
{
4250
var ms = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.txt.gz"));
4351
var newMs = StripHeaderAndFooter.Strip(ms);
@@ -52,7 +60,7 @@ public static async Task ModifyBaseStream()
5260
}
5361

5462
[Fact]
55-
public static void DecompressCanRead()
63+
public void DecompressCanRead()
5664
{
5765
var ms = new MemoryStream();
5866
var zip = new DeflateStream(ms, CompressionMode.Decompress);
@@ -64,7 +72,7 @@ public static void DecompressCanRead()
6472
}
6573

6674
[Fact]
67-
public static void CompressCanWrite()
75+
public void CompressCanWrite()
6876
{
6977
var ms = new MemoryStream();
7078
var zip = new DeflateStream(ms, CompressionMode.Compress);
@@ -75,15 +83,15 @@ public static void CompressCanWrite()
7583
}
7684

7785
[Fact]
78-
public static void CanDisposeBaseStream()
86+
public void CanDisposeBaseStream()
7987
{
8088
var ms = new MemoryStream();
8189
var zip = new DeflateStream(ms, CompressionMode.Compress);
8290
ms.Dispose(); // This would throw if this was invalid
8391
}
8492

8593
[Fact]
86-
public static void CanDisposeDeflateStream()
94+
public void CanDisposeDeflateStream()
8795
{
8896
var ms = new MemoryStream();
8997
var zip = new DeflateStream(ms, CompressionMode.Compress);
@@ -96,7 +104,7 @@ public static void CanDisposeDeflateStream()
96104
}
97105

98106
[Fact]
99-
public static async Task CanReadBaseStreamAfterDispose()
107+
public async Task CanReadBaseStreamAfterDispose()
100108
{
101109
var ms = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.txt.gz"));
102110
var newMs = StripHeaderAndFooter.Strip(ms);
@@ -114,7 +122,7 @@ public static async Task CanReadBaseStreamAfterDispose()
114122
}
115123

116124
[Fact]
117-
public static async Task DecompressWorks()
125+
public async Task DecompressWorks()
118126
{
119127
var compareStream = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.txt"));
120128
var gzStream = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.txt.gz"));
@@ -123,7 +131,7 @@ public static async Task DecompressWorks()
123131
}
124132

125133
[Fact]
126-
public static async Task DecompressWorksWithBinaryFile()
134+
public async Task DecompressWorksWithBinaryFile()
127135
{
128136
var compareStream = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.doc"));
129137
var gzStream = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.doc.gz"));
@@ -132,7 +140,7 @@ public static async Task DecompressWorksWithBinaryFile()
132140
}
133141

134142
// Making this async since regular read/write are tested below
135-
private static async Task DecompressAsync(MemoryStream compareStream, MemoryStream gzStream)
143+
private async Task DecompressAsync(MemoryStream compareStream, MemoryStream gzStream)
136144
{
137145
var strippedMs = StripHeaderAndFooter.Strip(gzStream);
138146

@@ -167,8 +175,9 @@ private static async Task DecompressAsync(MemoryStream compareStream, MemoryStre
167175
Assert.Equal(compareArray[i], writtenArray[i]);
168176
}
169177
}
178+
170179
[Fact]
171-
public static async Task DecompressFailsWithRealGzStream()
180+
public async Task DecompressFailsWithRealGzStream()
172181
{
173182
String[] files = { gzTestFile("GZTestDocument.doc.gz"), gzTestFile("GZTestDocument.txt.gz") };
174183
foreach (String fileName in files)
@@ -181,8 +190,9 @@ public static async Task DecompressFailsWithRealGzStream()
181190
zip.Dispose();
182191
}
183192
}
193+
184194
[Fact]
185-
public static void NullBaseStreamThrows()
195+
public void NullBaseStreamThrows()
186196
{
187197
Assert.Throws<ArgumentNullException>(() =>
188198
{
@@ -194,8 +204,9 @@ public static void NullBaseStreamThrows()
194204
var deflate = new DeflateStream(null, CompressionMode.Compress);
195205
});
196206
}
207+
197208
[Fact]
198-
public static void DisposedBaseStreamThrows()
209+
public void DisposedBaseStreamThrows()
199210
{
200211
var ms = new MemoryStream();
201212
ms.Dispose();
@@ -209,8 +220,9 @@ public static void DisposedBaseStreamThrows()
209220
var deflate = new DeflateStream(ms, CompressionMode.Compress);
210221
});
211222
}
223+
212224
[Fact]
213-
public static void ReadOnlyStreamThrowsOnCompress()
225+
public void ReadOnlyStreamThrowsOnCompress()
214226
{
215227
var ms = new LocalMemoryStream();
216228
ms.SetCanWrite(false);
@@ -220,8 +232,9 @@ public static void ReadOnlyStreamThrowsOnCompress()
220232
var gzip = new DeflateStream(ms, CompressionMode.Compress);
221233
});
222234
}
235+
223236
[Fact]
224-
public static void WriteOnlyStreamThrowsOnDecompress()
237+
public void WriteOnlyStreamThrowsOnDecompress()
225238
{
226239
var ms = new LocalMemoryStream();
227240
ms.SetCanRead(false);
@@ -231,8 +244,9 @@ public static void WriteOnlyStreamThrowsOnDecompress()
231244
var gzip = new DeflateStream(ms, CompressionMode.Decompress);
232245
});
233246
}
247+
234248
[Fact]
235-
public static void TestCtors()
249+
public void TestCtors()
236250
{
237251
CompressionLevel[] legalValues = new CompressionLevel[] { CompressionLevel.Optimal, CompressionLevel.Fastest, CompressionLevel.NoCompression };
238252

@@ -246,23 +260,26 @@ public static void TestCtors()
246260
}
247261
}
248262
}
263+
249264
[Fact]
250-
public static void TestLevelOptimial()
265+
public void TestLevelOptimial()
251266
{
252267
TestCtor(CompressionLevel.Optimal);
253268
}
269+
254270
[Fact]
255-
public static void TestLevelNoCompression()
271+
public void TestLevelNoCompression()
256272
{
257273
TestCtor(CompressionLevel.NoCompression);
258274
}
275+
259276
[Fact]
260-
public static void TestLevelFastest()
277+
public void TestLevelFastest()
261278
{
262279
TestCtor(CompressionLevel.Fastest);
263280
}
264281

265-
public static void TestCtor(CompressionLevel level, bool? leaveOpen = null)
282+
private static void TestCtor(CompressionLevel level, bool? leaveOpen = null)
266283
{
267284
//Create the DeflateStream
268285
int _bufferSize = 1024;
@@ -314,7 +331,7 @@ public static void TestCtor(CompressionLevel level, bool? leaveOpen = null)
314331
}
315332

316333
[Fact]
317-
public static async Task Flush()
334+
public async Task Flush()
318335
{
319336
var ms = new MemoryStream();
320337
var ds = new DeflateStream(ms, CompressionMode.Compress);
@@ -323,16 +340,18 @@ public static async Task Flush()
323340

324341
// Just ensuring Flush doesn't throw
325342
}
343+
326344
[Fact]
327-
public static void FlushFailsAfterDispose()
345+
public void FlushFailsAfterDispose()
328346
{
329347
var ms = new MemoryStream();
330348
var ds = new DeflateStream(ms, CompressionMode.Compress);
331349
ds.Dispose();
332350
Assert.Throws<ObjectDisposedException>(() => { ds.Flush(); });
333351
}
352+
334353
[Fact]
335-
public static async Task FlushAsyncFailsAfterDispose()
354+
public async Task FlushAsyncFailsAfterDispose()
336355
{
337356

338357
var ms = new MemoryStream();
@@ -346,7 +365,7 @@ await Assert.ThrowsAsync<ObjectDisposedException>(async () =>
346365
}
347366

348367
[Fact]
349-
public static void TestSeekMethodsDecompress()
368+
public void TestSeekMethodsDecompress()
350369
{
351370
var ms = new MemoryStream();
352371
var zip = new DeflateStream(ms, CompressionMode.Decompress);
@@ -360,8 +379,9 @@ public static void TestSeekMethodsDecompress()
360379
//Should we try all the enums? doesn't seem necessary
361380
Assert.Throws<NotSupportedException>(delegate { zip.Seek(100L, SeekOrigin.Begin); });
362381
}
382+
363383
[Fact]
364-
public static void TestSeekMethodsCompress()
384+
public void TestSeekMethodsCompress()
365385
{
366386
var ms = new MemoryStream();
367387
var zip = new DeflateStream(ms, CompressionMode.Compress);

0 commit comments

Comments
 (0)