Imported Upstream version 5.0.0.42

Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-04-10 11:41:01 +00:00
parent 1190d13a04
commit 6bdd276d05
19939 changed files with 3099680 additions and 93811 deletions

View File

@@ -0,0 +1,77 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Threading.Tasks;
using Xunit;
namespace System.IO.Tests
{
public class BufferedStreamFlushTests
{
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task ShouldNotFlushUnderlyingStreamIfReadOnly(bool underlyingCanSeek)
{
var underlying = new DelegateStream(
canReadFunc: () => true,
canWriteFunc: () => false,
canSeekFunc: () => underlyingCanSeek,
readFunc: (_, __, ___) => 123,
writeFunc: (_, __, ___) =>
{
throw new NotSupportedException();
},
seekFunc: (_, __) => 123L
);
var wrapper = new CallTrackingStream(underlying);
var buffered = new BufferedStream(wrapper);
buffered.ReadByte();
buffered.Flush();
Assert.Equal(0, wrapper.TimesCalled(nameof(wrapper.Flush)));
await buffered.FlushAsync();
Assert.Equal(0, wrapper.TimesCalled(nameof(wrapper.FlushAsync)));
}
[Theory]
[InlineData(true, true)]
[InlineData(true, false)]
[InlineData(false, true)]
[InlineData(false, false)]
public async Task ShouldAlwaysFlushUnderlyingStreamIfWritable(bool underlyingCanRead, bool underlyingCanSeek)
{
var underlying = new DelegateStream(
canReadFunc: () => underlyingCanRead,
canWriteFunc: () => true,
canSeekFunc: () => underlyingCanSeek,
readFunc: (_, __, ___) => 123,
writeFunc: (_, __, ___) => { },
seekFunc: (_, __) => 123L
);
var wrapper = new CallTrackingStream(underlying);
var buffered = new BufferedStream(wrapper);
buffered.Flush();
Assert.Equal(1, wrapper.TimesCalled(nameof(wrapper.Flush)));
await buffered.FlushAsync();
Assert.Equal(1, wrapper.TimesCalled(nameof(wrapper.FlushAsync)));
buffered.WriteByte(0);
buffered.Flush();
Assert.Equal(2, wrapper.TimesCalled(nameof(wrapper.Flush)));
await buffered.FlushAsync();
Assert.Equal(2, wrapper.TimesCalled(nameof(wrapper.FlushAsync)));
}
}
}

View File

@@ -0,0 +1,154 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Threading;
using Xunit;
namespace System.IO.Tests
{
public class BufferedStream_InvalidParameters
{
[Fact]
public static void NullConstructor_Throws_ArgumentNullException()
{
Assert.Throws<ArgumentNullException>(() => new BufferedStream(null));
}
[Fact]
public static void NegativeBufferSize_Throws_ArgumentOutOfRangeException()
{
Assert.Throws<ArgumentOutOfRangeException>(() => new BufferedStream(new MemoryStream(), -1));
}
[Fact]
public static void ZeroBufferSize_Throws_ArgumentNullException()
{
Assert.Throws<ArgumentOutOfRangeException>(() => new BufferedStream(new MemoryStream(), 0));
}
[Fact]
public static void UnderlyingStreamDisposed_Throws_ObjectDisposedException()
{
MemoryStream disposedStream = new MemoryStream();
disposedStream.Dispose();
Assert.Throws<ObjectDisposedException>(() => new BufferedStream(disposedStream));
}
[Fact]
public static void SetPositionToNegativeValue_Throws_ArgumentOutOfRangeException()
{
using (BufferedStream stream = new BufferedStream(new MemoryStream()))
{
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Position = -1);
}
}
[Fact]
public static void Read_Arguments()
{
using (BufferedStream stream = new BufferedStream(new MemoryStream()))
{
byte[] array = new byte[10];
Assert.Throws<ArgumentNullException>("array", () => stream.Read(null, 1, 1));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Read(array, -1, 1));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Read(array, 1, -1));
Assert.Throws<ArgumentException>(() => stream.Read(array, 9, 2));
}
}
[Fact]
public static void Write_Arguments()
{
using (BufferedStream stream = new BufferedStream(new MemoryStream()))
{
byte[] array = new byte[10];
Assert.Throws<ArgumentNullException>("array", () => stream.Write(null, 1, 1));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(array, -1, 1));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(array, 1, -1));
Assert.Throws<ArgumentException>(() => stream.Write(array, 9, 2));
}
}
[Fact]
public static void SetLength_NegativeValue()
{
using (MemoryStream underlying = new MemoryStream())
using (BufferedStream stream = new BufferedStream(underlying))
{
Assert.Throws<ArgumentOutOfRangeException>(() => stream.SetLength(-1));
stream.SetLength(1);
Assert.Equal(1, underlying.Length);
Assert.Equal(1, stream.Length);
}
}
[Fact]
public static void ReadOnUnreadableStream_Throws_NotSupportedException()
{
using (WrappedMemoryStream underlying = new WrappedMemoryStream(false, true, true))
using (BufferedStream stream = new BufferedStream(underlying))
{
Assert.Throws<NotSupportedException>(() => stream.Read(new byte[] { 1 }, 0, 1));
}
}
[Fact]
public static void WriteOnUnwritableStream_Throws_NotSupportedException()
{
using (WrappedMemoryStream underlying = new WrappedMemoryStream(true, false, true))
using (BufferedStream stream = new BufferedStream(underlying))
{
Assert.Throws<NotSupportedException>(() => stream.Write(new byte[] { 1 }, 0, 1));
}
}
[Fact]
public static void SeekOnUnseekableStream_Throws_NotSupportedException()
{
using (WrappedMemoryStream underlying = new WrappedMemoryStream(true, true, false))
using (BufferedStream stream = new BufferedStream(underlying))
{
Assert.Throws<NotSupportedException>(() => stream.Seek(0, new SeekOrigin()));
}
}
[Fact]
public void CopyToAsync_InvalidArguments_Throws()
{
using (var s = new BufferedStream(new MemoryStream()))
{
// Null destination
Assert.Throws<ArgumentNullException>("destination", () => { s.CopyToAsync(null); });
// Buffer size out-of-range
Assert.Throws<ArgumentOutOfRangeException>("bufferSize", () => { s.CopyToAsync(new MemoryStream(), 0); });
Assert.Throws<ArgumentOutOfRangeException>("bufferSize", () => { s.CopyToAsync(new MemoryStream(), -1, CancellationToken.None); });
// Copying to non-writable stream
Assert.Throws<NotSupportedException>(() => { s.CopyToAsync(new WrappedMemoryStream(canRead: true, canWrite: false, canSeek: true)); });
// Copying to a non-writable and non-readable stream
Assert.Throws<ObjectDisposedException>(() => { s.CopyToAsync(new WrappedMemoryStream(canRead: false, canWrite: false, canSeek: false)); });
// Copying after disposing the buffer stream
s.Dispose();
Assert.Throws<ObjectDisposedException>(() => { s.CopyToAsync(new MemoryStream()); });
}
// Copying after disposing the underlying stream
using (var ms = new MemoryStream())
using (var s = new BufferedStream(ms))
{
ms.Dispose();
Assert.Throws<ObjectDisposedException>(() => { s.CopyToAsync(new MemoryStream()); });
}
// Copying from a non-readable source
using (var s = new BufferedStream(new WrappedMemoryStream(canRead: false, canWrite: true, canSeek: true)))
{
Assert.Throws<NotSupportedException>(() => { s.CopyToAsync(new MemoryStream()); });
}
}
}
}

View File

@@ -0,0 +1,281 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace System.IO.Tests
{
public class BufferedStream_StreamAsync : StreamAsync
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
[Fact]
public async Task ConcurrentOperationsAreSerialized()
{
byte[] data = Enumerable.Range(0, 1000).Select(i => (byte)i).ToArray();
var mcaos = new ManuallyReleaseAsyncOperationsStream();
var stream = new BufferedStream(mcaos, 1);
var tasks = new Task[4];
for (int i = 0; i < 4; i++)
{
tasks[i] = stream.WriteAsync(data, 250 * i, 250);
}
Assert.False(tasks.All(t => t.IsCompleted));
mcaos.Release();
await Task.WhenAll(tasks);
stream.Position = 0;
for (int i = 0; i < tasks.Length; i++)
{
Assert.Equal(i, stream.ReadByte());
}
}
[Fact]
public void UnderlyingStreamThrowsExceptions()
{
var stream = new BufferedStream(new ThrowsExceptionFromAsyncOperationsStream());
Assert.Equal(TaskStatus.Faulted, stream.ReadAsync(new byte[1], 0, 1).Status);
Assert.Equal(TaskStatus.Faulted, stream.WriteAsync(new byte[10000], 0, 10000).Status);
stream.WriteByte(1);
Assert.Equal(TaskStatus.Faulted, stream.FlushAsync().Status);
}
[Fact]
public async Task CopyToAsyncTest_RequiresAsyncFlushingOfWrites()
{
byte[] data = Enumerable.Range(0, 1000).Select(i => (byte)(i % 256)).ToArray();
var manualReleaseStream = new ManuallyReleaseAsyncOperationsStream();
var src = new BufferedStream(manualReleaseStream);
src.Write(data, 0, data.Length);
src.Position = 0;
var dst = new MemoryStream();
data[0] = 42;
src.WriteByte(42);
dst.WriteByte(42);
Task copyTask = src.CopyToAsync(dst);
manualReleaseStream.Release();
await copyTask;
Assert.Equal(data, dst.ToArray());
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task CopyToAsyncTest_ReadBeforeCopy_CopiesAllData(bool wrappedStreamCanSeek)
{
byte[] data = Enumerable.Range(0, 1000).Select(i => (byte)(i % 256)).ToArray();
var wrapped = new ManuallyReleaseAsyncOperationsStream();
wrapped.Release();
wrapped.Write(data, 0, data.Length);
wrapped.Position = 0;
wrapped.SetCanSeek(wrappedStreamCanSeek);
var src = new BufferedStream(wrapped, 100);
src.ReadByte();
var dst = new MemoryStream();
await src.CopyToAsync(dst);
var expected = new byte[data.Length - 1];
Array.Copy(data, 1, expected, 0, expected.Length);
Assert.Equal(expected, dst.ToArray());
}
}
public class BufferedStream_StreamMethods : StreamMethods
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
protected override Stream CreateStream(int bufferSize)
{
return new BufferedStream(new MemoryStream(), bufferSize);
}
}
public class BufferedStream_TestLeaveOpen : TestLeaveOpen
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
}
public class StreamWriterWithBufferedStream_CloseTests : CloseTests
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
}
public class StreamWriterWithBufferedStream_FlushTests : FlushTests
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
[Fact]
public void WriteAfterRead_NonSeekableStream_Throws()
{
var wrapped = new WrappedMemoryStream(canRead: true, canWrite: true, canSeek: false, data: new byte[] { 1, 2, 3, 4, 5 });
var s = new BufferedStream(wrapped);
s.Read(new byte[3], 0, 3);
Assert.Throws<NotSupportedException>(() => s.Write(new byte[10], 0, 10));
}
}
public class StreamWriterWithBufferedStream_WriteTests : WriteTests
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
}
public class StreamReaderWithBufferedStream_Tests : StreamReaderTests
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
protected override Stream GetSmallStream()
{
byte[] testData = new byte[] { 72, 69, 76, 76, 79 };
return new BufferedStream(new MemoryStream(testData));
}
protected override Stream GetLargeStream()
{
byte[] testData = new byte[] { 72, 69, 76, 76, 79 };
List<byte> data = new List<byte>();
for (int i = 0; i < 1000; i++)
{
data.AddRange(testData);
}
return new BufferedStream(new MemoryStream(data.ToArray()));
}
}
public class BinaryWriterWithBufferedStream_Tests : BinaryWriterTests
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
[Fact]
public override void BinaryWriter_FlushTests()
{
// [] Check that flush updates the underlying stream
using (Stream memstr2 = CreateStream())
using (BinaryWriter bw2 = new BinaryWriter(memstr2))
{
string str = "HelloWorld";
int expectedLength = str.Length + 1; // 1 for 7-bit encoded length
bw2.Write(str);
Assert.Equal(expectedLength, memstr2.Length);
bw2.Flush();
Assert.Equal(expectedLength, memstr2.Length);
}
// [] Flushing a closed writer may throw an exception depending on the underlying stream
using (Stream memstr2 = CreateStream())
{
BinaryWriter bw2 = new BinaryWriter(memstr2);
bw2.Dispose();
Assert.Throws<ObjectDisposedException>(() => bw2.Flush());
}
}
}
public class BinaryWriterWithBufferedStream_WriteByteCharTests : BinaryWriter_WriteByteCharTests
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
}
public class BinaryWriterWithBufferedStream_WriteTests : BinaryWriter_WriteTests
{
protected override Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
}
internal sealed class ManuallyReleaseAsyncOperationsStream : MemoryStream
{
private readonly TaskCompletionSource<bool> _tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
private bool _canSeek = true;
public override bool CanSeek => _canSeek;
public void SetCanSeek(bool canSeek) => _canSeek = canSeek;
public void Release() { _tcs.SetResult(true); }
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
await _tcs.Task;
return await base.ReadAsync(buffer, offset, count, cancellationToken);
}
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
await _tcs.Task;
await base.WriteAsync(buffer, offset, count, cancellationToken);
}
public override async Task FlushAsync(CancellationToken cancellationToken)
{
await _tcs.Task;
await base.FlushAsync(cancellationToken);
}
}
internal sealed class ThrowsExceptionFromAsyncOperationsStream : MemoryStream
{
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
throw new InvalidOperationException("Exception from ReadAsync");
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
throw new InvalidOperationException("Exception from WriteAsync");
}
public override Task FlushAsync(CancellationToken cancellationToken)
{
throw new InvalidOperationException("Exception from FlushAsync");
}
}
}

View File

@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.IO;
using Xunit;
namespace System.IO.Tests
{
public partial class BufferedStreamTests
{
[Fact]
public void UnderlyingStream()
{
var underlyingStream = new MemoryStream();
var bufferedStream = new BufferedStream(underlyingStream);
Assert.Same(underlyingStream, bufferedStream.UnderlyingStream);
}
[Fact]
public void BufferSize()
{
var bufferedStream = new BufferedStream(new MemoryStream(), 1234);
Assert.Equal(1234, bufferedStream.BufferSize);
}
}
}

View File

@@ -0,0 +1,40 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace System.IO.Tests
{
public class BufferedStream_NS17
{
protected Stream CreateStream()
{
return new BufferedStream(new MemoryStream());
}
public void EndCallback(IAsyncResult ar)
{ }
[Fact]
public void BeginEndReadTest()
{
Stream stream = CreateStream();
IAsyncResult result = stream.BeginRead(new byte[1], 0, 1, new AsyncCallback(EndCallback), new object());
stream.EndRead(result);
}
[Fact]
public void BeginEndWriteTest()
{
Stream stream = CreateStream();
IAsyncResult result = stream.BeginWrite(new byte[1], 0, 1, new AsyncCallback(EndCallback), new object());
stream.EndWrite(result);
}
}
}