Avoid wrapping async I/O in synchronous methods in the HTTP tests, as this can lead...
authorEric Eilebrecht <ericeil@hotmail.com>
Wed, 13 Jul 2016 20:09:05 +0000 (13:09 -0700)
committerEric Eilebrecht <ericeil@hotmail.com>
Wed, 13 Jul 2016 22:19:30 +0000 (15:19 -0700)
Commit migrated from https://github.com/dotnet/corefx/commit/af17a7ab4bd0630f71e44bbe566bb712aeb86b5c

src/libraries/Common/tests/System/IO/DelegateStream.cs
src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.cs

index 94c057b..29aa555 100644 (file)
@@ -52,13 +52,17 @@ namespace System.IO
             _positionSetFunc = positionSetFunc ?? (_ => { throw new NotSupportedException(); });
             _positionGetFunc = positionGetFunc ?? (() => { throw new NotSupportedException(); });
 
-            _readFunc = readFunc ?? ((buffer, offset, count) => readAsyncFunc(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult());
+            if (readAsyncFunc != null && readFunc == null)
+                throw new InvalidOperationException("If reads are supported, must provide a synchronous read implementation");
+            _readFunc = readFunc;
             _readAsyncFunc = readAsyncFunc ?? ((buffer, offset, count, token) => base.ReadAsync(buffer, offset, count, token));
 
             _seekFunc = seekFunc ?? ((_, __) => { throw new NotSupportedException(); });
             _setLengthFunc = setLengthFunc ?? (_ => { throw new NotSupportedException(); });
 
-            _writeFunc = writeFunc ?? ((buffer, offset, count) => writeAsyncFunc(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult());
+            if (writeAsyncFunc != null && writeFunc == null)
+                throw new InvalidOperationException("If writes are supported, must provide a synchronous write implementation");
+            _writeFunc = writeFunc;
             _writeAsyncFunc = writeAsyncFunc ?? ((buffer, offset, count, token) => base.WriteAsync(buffer, offset, count, token));
         }
 
index e23ed2f..91c9b3f 100644 (file)
@@ -1022,6 +1022,7 @@ namespace System.Net.Http.Functional.Tests
                             lengthFunc: () => wrappedMemStream.Length,
                             positionGetFunc: () => wrappedMemStream.Position,
                             positionSetFunc: p => wrappedMemStream.Position = p,
+                            readFunc: (buffer, offset, count) => wrappedMemStream.Read(buffer, offset, count),
                             readAsyncFunc: (buffer, offset, count, token) => wrappedMemStream.ReadAsync(buffer, offset, count, token));
                         yield return new object[] { server, new StreamContentWithSyncAsyncCopy(syncKnownLengthStream, syncCopy: syncCopy), data };
                     }
@@ -1029,34 +1030,45 @@ namespace System.Net.Http.Functional.Tests
                     // A stream that provides the data synchronously and has an unknown length
                     {
                         int syncUnknownLengthStreamOffset = 0;
+
+                        Func<byte[], int, int, int> readFunc = (buffer, offset, count) =>
+                        {
+                            int bytesRemaining = data.Length - syncUnknownLengthStreamOffset;
+                            int bytesToCopy = Math.Min(bytesRemaining, count);
+                            Array.Copy(data, syncUnknownLengthStreamOffset, buffer, offset, bytesToCopy);
+                            syncUnknownLengthStreamOffset += bytesToCopy;
+                            return bytesToCopy;
+                        };
+
                         var syncUnknownLengthStream = new DelegateStream(
                             canReadFunc: () => true,
                             canSeekFunc: () => false,
-                            readAsyncFunc: (buffer, offset, count, token) =>
-                            {
-                                int bytesRemaining = data.Length - syncUnknownLengthStreamOffset;
-                                int bytesToCopy = Math.Min(bytesRemaining, count);
-                                Array.Copy(data, syncUnknownLengthStreamOffset, buffer, offset, bytesToCopy);
-                                syncUnknownLengthStreamOffset += bytesToCopy;
-                                return Task.FromResult(bytesToCopy);
-                            });
+                            readFunc: readFunc,
+                            readAsyncFunc: (buffer, offset, count, token) => Task.FromResult(readFunc(buffer, offset, count)));
                         yield return new object[] { server, new StreamContentWithSyncAsyncCopy(syncUnknownLengthStream, syncCopy: syncCopy), data };
                     }
 
                     // A stream that provides the data asynchronously
                     {
                         int asyncStreamOffset = 0, maxDataPerRead = 100;
+
+                        Func<byte[], int, int, int> readFunc = (buffer, offset, count) =>
+                        {
+                            int bytesRemaining = data.Length - asyncStreamOffset;
+                            int bytesToCopy = Math.Min(bytesRemaining, Math.Min(maxDataPerRead, count));
+                            Array.Copy(data, asyncStreamOffset, buffer, offset, bytesToCopy);
+                            asyncStreamOffset += bytesToCopy;
+                            return bytesToCopy;
+                        };
+
                         var asyncStream = new DelegateStream(
                             canReadFunc: () => true,
                             canSeekFunc: () => false,
+                            readFunc: readFunc,
                             readAsyncFunc: async (buffer, offset, count, token) =>
                             {
                                 await Task.Delay(1).ConfigureAwait(false);
-                                int bytesRemaining = data.Length - asyncStreamOffset;
-                                int bytesToCopy = Math.Min(bytesRemaining, Math.Min(maxDataPerRead, count));
-                                Array.Copy(data, asyncStreamOffset, buffer, offset, bytesToCopy);
-                                asyncStreamOffset += bytesToCopy;
-                                return bytesToCopy;
+                                return readFunc(buffer, offset, count);
                             });
                         yield return new object[] { server, new StreamContentWithSyncAsyncCopy(asyncStream, syncCopy: syncCopy), data };
                     }