/// <summary> /// Synchronized version of an async stream. /// </summary> /// <param name="stream">Stream to synchronize.</param> /// <returns>synchronized version of the given stream.</returns> public static AsyncStream Synchronized(AsyncStream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (stream is AsyncSafeStream) { return(stream); } return(new AsyncSafeStream(stream)); }
public AsyncSafeStream(AsyncStream stream) { this.asyncStream = stream ?? throw new ArgumentNullException(nameof(stream)); }
public void ASSynchronized() { Assert.ThrowsException <ArgumentNullException>(() => AsyncStream.Synchronized(null !)); var sut = new Mock <AsyncStream>() { CallBase = true }; var synchronized = AsyncStream.Synchronized(sut.Object); Assert.IsNotNull(synchronized); Assert.AreSame(synchronized, AsyncStream.Synchronized(synchronized)); // Caps var funcs = new Expression <Func <AsyncStream, bool> >[] { x => x.CanRead, x => x.CanWrite, x => x.CanSeek, x => x.CanTimeout, }; foreach (var func in funcs) { foreach (var expected in new[] { false, true }) { sut.Setup(func).Returns(expected); Assert.AreEqual(expected, func.Compile()(synchronized)); } } // Position var expected2 = 42; sut.Setup(x => x.Position).Returns(expected2); Assert.AreEqual(expected2, synchronized.Position); sut.SetupProperty(x => x.Position); synchronized.Position = expected2; Assert.AreEqual(expected2, sut.Object.Position); // ReadTimeout sut.Setup(x => x.ReadTimeout).Returns(expected2); Assert.AreEqual(expected2, synchronized.ReadTimeout); sut.SetupProperty(x => x.ReadTimeout); synchronized.ReadTimeout = expected2; Assert.AreEqual(expected2, sut.Object.ReadTimeout); // WriteTimeout sut.Setup(x => x.WriteTimeout).Returns(expected2); Assert.AreEqual(expected2, synchronized.WriteTimeout); sut.SetupProperty(x => x.WriteTimeout); synchronized.WriteTimeout = expected2; Assert.AreEqual(expected2, sut.Object.WriteTimeout); // Seek var expected_offset = 42; var expected_origin = SeekOrigin.End; var result_offset = 0L; var result_origin = SeekOrigin.Begin; sut.Setup(x => x.Seek(It.IsAny <long>(), It.IsAny <SeekOrigin>())) .Callback <long, SeekOrigin>((offset, origin) => { result_offset = offset; result_origin = origin; }); synchronized.Seek(expected_offset, expected_origin); Assert.AreEqual(expected_offset, result_offset); Assert.AreEqual(expected_origin, result_origin); // SetLength var expected_length = 42; var result_length = 0L; sut.Setup(x => x.SetLength(It.IsAny <long>())) .Callback <long>(length => result_length = length); synchronized.SetLength(expected_length); Assert.AreEqual(expected_length, result_length); // Read sut.Setup(x => x.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>())) .ReturnsAsync(expected2); var read = synchronized.ReadAsync(null !, 0, 0).Result; Assert.AreEqual(expected2, read); read = synchronized.Read(null !, 0, 0); Assert.AreEqual(expected2, read); read = synchronized.EndRead(synchronized.BeginRead(null !, 0, 0, null !, null !)); Assert.AreEqual(expected2, read); // Write sut.Setup(x => x.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>())) .Verifiable(); synchronized.WriteAsync(null !, 0, 0).Wait(); sut.Verify(x => x.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()), Times.Once); synchronized.Write(null !, 0, 0); sut.Verify(x => x.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); synchronized.EndWrite(synchronized.BeginWrite(null !, 0, 0, null !, null !)); sut.Verify(x => x.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()), Times.Exactly(3)); Assert.ThrowsExceptionAsync <OperationCanceledException>(() => synchronized.WriteAsync(null !, 0, 0, new CancellationToken(true))); // Async sut.Setup(x => x.FlushAsync(It.IsAny <CancellationToken>())).Verifiable(); synchronized.FlushAsync().Wait(); sut.Verify(x => x.FlushAsync(It.IsAny <CancellationToken>()), Times.Once); synchronized.Flush(); sut.Verify(x => x.FlushAsync(It.IsAny <CancellationToken>()), Times.Exactly(2)); Assert.ThrowsExceptionAsync <OperationCanceledException>(() => synchronized.FlushAsync(new CancellationToken(true))); }