From 3564b7bac9a26958cef938cefc1b9548a042ea04 Mon Sep 17 00:00:00 2001 From: Geoffrey Kizer Date: Wed, 13 Jan 2021 22:00:56 -0800 Subject: [PATCH 1/7] add Memory support in SendPacketElements and SendPacketsAsync --- .../ref/System.Net.Sockets.cs | 3 + .../System/Net/Sockets/SendPacketsElement.cs | 20 ++- .../Sockets/SocketAsyncEventArgs.Windows.cs | 57 +++----- .../src/System/Net/Sockets/SocketPal.Unix.cs | 4 +- .../tests/FunctionalTests/SendPacketsAsync.cs | 109 ++++++++++++++- .../FunctionalTests/SendPacketsElementTest.cs | 126 +++++++++++++++++- 6 files changed, 268 insertions(+), 51 deletions(-) diff --git a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs index 9f1e8403036358..5a5ccf63eb6525 100644 --- a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs +++ b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs @@ -234,6 +234,8 @@ public partial class SendPacketsElement public SendPacketsElement(byte[] buffer) { } public SendPacketsElement(byte[] buffer, int offset, int count) { } public SendPacketsElement(byte[] buffer, int offset, int count, bool endOfPacket) { } + public SendPacketsElement(ReadOnlyMemory buffer) { } + public SendPacketsElement(ReadOnlyMemory buffer, bool endOfPacket) { } public SendPacketsElement(System.IO.FileStream fileStream) { } public SendPacketsElement(System.IO.FileStream fileStream, long offset, int count) { } public SendPacketsElement(System.IO.FileStream fileStream, long offset, int count, bool endOfPacket) { } @@ -247,6 +249,7 @@ public SendPacketsElement(string filepath, long offset, int count, bool endOfPac public bool EndOfPacket { get { throw null; } } public string? FilePath { get { throw null; } } public System.IO.FileStream? FileStream { get { throw null; } } + public ReadOnlyMemory? MemoryBuffer { get { throw null; } } public int Offset { get { throw null; } } public long OffsetLong { get { throw null; } } } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SendPacketsElement.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SendPacketsElement.cs index f800906120ce28..2ba1a4a919a6cb 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SendPacketsElement.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SendPacketsElement.cs @@ -42,7 +42,7 @@ public SendPacketsElement(string filepath, long offset, int count, bool endOfPac throw new ArgumentOutOfRangeException(nameof(count)); } - Initialize(filepath, null, null, offset, count, endOfPacket); + Initialize(filepath, null, null, null, offset, count, endOfPacket); } // Constructors for fileStream elements. @@ -75,7 +75,7 @@ public SendPacketsElement(FileStream fileStream, long offset, int count, bool en throw new ArgumentOutOfRangeException(nameof(count)); } - Initialize(null, fileStream, null, offset, count, endOfPacket); + Initialize(null, fileStream, null, null, offset, count, endOfPacket); } // Constructors for buffer elements. @@ -102,14 +102,24 @@ public SendPacketsElement(byte[] buffer, int offset, int count, bool endOfPacket throw new ArgumentOutOfRangeException(nameof(count)); } - Initialize(null, null, buffer, offset, count, endOfPacket); + Initialize(null, null, buffer, new ReadOnlyMemory(buffer, offset, count), offset, count, endOfPacket); } - private void Initialize(string? filePath, FileStream? fileStream, byte[]? buffer, long offset, int count, bool endOfPacket) + public SendPacketsElement(ReadOnlyMemory buffer) : + this(buffer, false) + { } + + public SendPacketsElement(ReadOnlyMemory buffer, bool endOfPacket) + { + Initialize(null, null, null, buffer, 0, buffer.Length, endOfPacket); + } + + private void Initialize(string? filePath, FileStream? fileStream, byte[]? buffer, ReadOnlyMemory? memoryBuffer, long offset, int count, bool endOfPacket) { FilePath = filePath; FileStream = fileStream; Buffer = buffer; + MemoryBuffer = memoryBuffer; OffsetLong = offset; Count = count; EndOfPacket = endOfPacket; @@ -123,6 +133,8 @@ private void Initialize(string? filePath, FileStream? fileStream, byte[]? buffer public int Count { get; private set; } + public ReadOnlyMemory? MemoryBuffer { get; private set; } + public int Offset => checked((int)OffsetLong); public long OffsetLong { get; private set; } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs index a1a725d8a5041a..4033e4fe055f28 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs @@ -55,7 +55,7 @@ private enum SingleBufferHandleState : byte // Note that these arrays are allocated and then grown as necessary, but never shrunk. // Thus the actual in-use length is defined by _bufferListInternal.Count, not the length of these arrays. private WSABuffer[]? _wsaBufferArrayPinned; - private GCHandle[]? _multipleBufferGCHandles; + private MemoryHandle[]? _multipleBufferMemoryHandles; // Internal buffers for WSARecvMsg private byte[]? _wsaMessageBufferPinned; @@ -703,7 +703,7 @@ internal unsafe SocketError DoOperationSendPackets(Socket socket, SafeSocketHand { sendPacketsElementsFileStreamCount++; } - else if (spe.Buffer != null && spe.Count > 0) + else if (spe.MemoryBuffer != null && spe.Count > 0) { sendPacketsElementsBufferCount++; } @@ -865,28 +865,17 @@ private void SetupMultipleBuffers() { int bufferCount = _bufferListInternal.Count; -#if DEBUG - if (_multipleBufferGCHandles != null) - { - foreach (GCHandle gcHandle in _multipleBufferGCHandles) - { - Debug.Assert(!gcHandle.IsAllocated); - } - } -#endif - // Number of things to pin is number of buffers. // Ensure we have properly sized object array. - if (_multipleBufferGCHandles == null || (_multipleBufferGCHandles.Length < bufferCount)) + if (_multipleBufferMemoryHandles == null || (_multipleBufferMemoryHandles.Length < bufferCount)) { - _multipleBufferGCHandles = new GCHandle[bufferCount]; + _multipleBufferMemoryHandles = new MemoryHandle[bufferCount]; } // Pin the buffers. for (int i = 0; i < bufferCount; i++) { - Debug.Assert(!_multipleBufferGCHandles[i].IsAllocated); - _multipleBufferGCHandles[i] = GCHandle.Alloc(_bufferListInternal[i].Array, GCHandleType.Pinned); + _multipleBufferMemoryHandles[i] = _bufferListInternal[i].Array.AsMemory().Pin(); } if (_wsaBufferArrayPinned == null || _wsaBufferArrayPinned.Length < bufferCount) @@ -973,14 +962,12 @@ private void FreePinHandles() _singleBufferHandle.Dispose(); } - if (_multipleBufferGCHandles != null) + if (_multipleBufferMemoryHandles != null) { - for (int i = 0; i < _multipleBufferGCHandles.Length; i++) + for (int i = 0; i < _multipleBufferMemoryHandles.Length; i++) { - if (_multipleBufferGCHandles[i].IsAllocated) - { - _multipleBufferGCHandles[i].Free(); - } + _multipleBufferMemoryHandles[i].Dispose(); + _multipleBufferMemoryHandles[i] = default; } } @@ -1007,50 +994,40 @@ private unsafe Interop.Winsock.TransmitPacketsElement[] SetupPinHandlesSendPacke // Number of things to pin is number of buffers + 1 (native descriptor). // Ensure we have properly sized object array. -#if DEBUG - if (_multipleBufferGCHandles != null) + if (_multipleBufferMemoryHandles == null || (_multipleBufferMemoryHandles.Length < sendPacketsElementsBufferCount)) { - foreach (GCHandle gcHandle in _multipleBufferGCHandles) - { - Debug.Assert(!gcHandle.IsAllocated); - } - } -#endif - - if (_multipleBufferGCHandles == null || (_multipleBufferGCHandles.Length < sendPacketsElementsBufferCount)) - { - _multipleBufferGCHandles = new GCHandle[sendPacketsElementsBufferCount]; + _multipleBufferMemoryHandles = new MemoryHandle[sendPacketsElementsBufferCount]; } // Pin user specified buffers. int index = 0; foreach (SendPacketsElement spe in sendPacketsElementsCopy) { - if (spe?.Buffer != null && spe.Count > 0) + if (spe?.MemoryBuffer != null && spe.Count > 0) { - Debug.Assert(!_multipleBufferGCHandles[index].IsAllocated); - _multipleBufferGCHandles[index] = GCHandle.Alloc(spe.Buffer, GCHandleType.Pinned); - + _multipleBufferMemoryHandles[index] = spe.MemoryBuffer.Value.Pin(); index++; } } // Fill in native descriptor. + int bufferIndex = 0; int descriptorIndex = 0; int fileIndex = 0; foreach (SendPacketsElement spe in sendPacketsElementsCopy) { if (spe != null) { - if (spe.Buffer != null && spe.Count > 0) + if (spe.MemoryBuffer != null && spe.Count > 0) { // This element is a buffer. - sendPacketsDescriptorPinned[descriptorIndex].buffer = Marshal.UnsafeAddrOfPinnedArrayElement(spe.Buffer, spe.Offset); + sendPacketsDescriptorPinned[descriptorIndex].buffer = (IntPtr)_multipleBufferMemoryHandles[bufferIndex].Pointer; sendPacketsDescriptorPinned[descriptorIndex].length = (uint)spe.Count; sendPacketsDescriptorPinned[descriptorIndex].flags = Interop.Winsock.TransmitPacketsElementFlags.Memory | (spe.EndOfPacket ? Interop.Winsock.TransmitPacketsElementFlags.EndOfPacket : 0); + bufferIndex++; descriptorIndex++; } else if (spe.FilePath != null) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs index 653164730d760c..019bd5f165db77 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs @@ -1797,9 +1797,9 @@ public static async void SendPacketsAsync( SendPacketsElement e = elements[i]; if (e != null) { - if (e.Buffer != null) + if (e.MemoryBuffer != null) { - bytesTransferred += await socket.SendAsync(new ArraySegment(e.Buffer, e.Offset, e.Count), SocketFlags.None).ConfigureAwait(false); + bytesTransferred += await socket.SendAsync(e.MemoryBuffer.Value, SocketFlags.None).ConfigureAwait(false); } else { diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs index 37b63f1c525d1f..13662db2364ca5 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs @@ -242,6 +242,107 @@ public void BufferZeroCountThenNormal_ZeroCountIgnored(SocketImplementationType #endregion Buffers + #region Memory + + [Theory] + [InlineData(SocketImplementationType.APM)] + [InlineData(SocketImplementationType.Async)] + public void NormalMemory_Success(SocketImplementationType type) + { + SendPackets(type, new SendPacketsElement(new ReadOnlyMemory(new byte[10])), 10); + } + + [Theory] + [InlineData(SocketImplementationType.APM)] + [InlineData(SocketImplementationType.Async)] + public void NormalMemoryRange_Success(SocketImplementationType type) + { + SendPackets(type, new SendPacketsElement(new ReadOnlyMemory(new byte[10], 5, 5)), 5); + } + + [Theory] + [InlineData(SocketImplementationType.APM)] + [InlineData(SocketImplementationType.Async)] + public void EmptyMemory_Ignored(SocketImplementationType type) + { + SendPackets(type, new SendPacketsElement(new ReadOnlyMemory(new byte[0])), 0); + } + + [Theory] + [InlineData(SocketImplementationType.APM)] + [InlineData(SocketImplementationType.Async)] + public void MemoryZeroCount_Ignored(SocketImplementationType type) + { + SendPackets(type, new SendPacketsElement(new ReadOnlyMemory(new byte[10], 4, 0)), 0); + } + + [Theory] + [InlineData(SocketImplementationType.APM)] + [InlineData(SocketImplementationType.Async)] + public void MemoryMixedBuffers_ZeroCountMemoryIgnored(SocketImplementationType type) + { + SendPacketsElement[] elements = new SendPacketsElement[] + { + new SendPacketsElement(new ReadOnlyMemory(new byte[10], 4, 0)), // Ignored + new SendPacketsElement(new ReadOnlyMemory(new byte[10], 4, 4)), + new SendPacketsElement(new ReadOnlyMemory(new byte[10], 0, 4)) + }; + SendPackets(type, elements, SocketError.Success, 8); + } + + [Theory] + [InlineData(SocketImplementationType.APM)] + [InlineData(SocketImplementationType.Async)] + public void MemoryZeroCountThenNormal_ZeroCountIgnored(SocketImplementationType type) + { + Assert.True(Capability.IPv6Support()); + + EventWaitHandle completed = new ManualResetEvent(false); + + int port; + using (SocketTestServer.SocketTestServerFactory(type, _serverAddress, out port)) + { + using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) + { + sock.Connect(new IPEndPoint(_serverAddress, port)); + using (SocketAsyncEventArgs args = new SocketAsyncEventArgs()) + { + args.Completed += OnCompleted; + args.UserToken = completed; + + // First do an empty send, ignored + args.SendPacketsElements = new SendPacketsElement[] + { + new SendPacketsElement(new ReadOnlyMemory(new byte[5], 3, 0)) + }; + + if (sock.SendPacketsAsync(args)) + { + Assert.True(completed.WaitOne(TestSettings.PassingTestTimeout), "Timed out"); + } + Assert.Equal(SocketError.Success, args.SocketError); + Assert.Equal(0, args.BytesTransferred); + + completed.Reset(); + // Now do a real send + args.SendPacketsElements = new SendPacketsElement[] + { + new SendPacketsElement(new ReadOnlyMemory(new byte[5], 1, 4)) + }; + + if (sock.SendPacketsAsync(args)) + { + Assert.True(completed.WaitOne(TestSettings.PassingTestTimeout), "Timed out"); + } + Assert.Equal(SocketError.Success, args.SocketError); + Assert.Equal(4, args.BytesTransferred); + } + } + } + } + + #endregion Memory + #region TransmitFileOptions [Theory] [InlineData(SocketImplementationType.APM)] @@ -632,7 +733,9 @@ public void SendPacketsElement_FileStreamMultiPartMixed_Success(SocketImplementa new SendPacketsElement(new byte[] { 5, 6, 7 }, 0, 3), new SendPacketsElement(stream, s_testFileSize - 10, 10), new SendPacketsElement(TestFileName, 0L, 10), + new SendPacketsElement(new ReadOnlyMemory(new byte[] { 11, 12, 13 }, 0, 3)), new SendPacketsElement(stream, 10L, 20), + new SendPacketsElement(new ReadOnlyMemory(new byte[] { 14, 15, 16 })), new SendPacketsElement(TestFileName, 30, 10), new SendPacketsElement(new byte[] { 8, 9, 10 }, 0, 3), }; @@ -649,9 +752,11 @@ public void SendPacketsElement_FileStreamMultiPartMixed_MultipleFileStreams_Succ using (var stream2 = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) { var elements = new[] { + new SendPacketsElement(new ReadOnlyMemory(new byte[] { 11, 12, 13 }, 0, 3)), new SendPacketsElement(new byte[] { 5, 6, 7 }, 0, 0), new SendPacketsElement(stream, s_testFileSize - 10, 10), new SendPacketsElement(stream2, s_testFileSize - 100, 10), + new SendPacketsElement(new ReadOnlyMemory(new byte[] { 14, 15, 16 })), new SendPacketsElement(TestFileName, 0L, 10), new SendPacketsElement(new byte[] { 8, 9, 10 }, 0, 1), new SendPacketsElement(TestFileName, 30, 10), @@ -827,8 +932,8 @@ int FileCount(SendPacketsElement element) { else if (spe.FileStream != null) { ReadFromFile(spe.FileStream.Name, spe.OffsetLong, spe.Count, result, ref resultOffset); } - else if (spe.Buffer != null && spe.Count > 0) { - Array.Copy(spe.Buffer, spe.OffsetLong, result, resultOffset, spe.Count); + else if (spe.MemoryBuffer != null && spe.Count > 0) { + spe.MemoryBuffer.Value.CopyTo(result.AsMemory((int)resultOffset)); resultOffset += spe.Count; } } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsElementTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsElementTest.cs index 216cfd5d7d11a1..d0e1b33cf517b8 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsElementTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsElementTest.cs @@ -47,6 +47,8 @@ public void EmptyBufferCtor_Success() Assert.Equal(0, element.Buffer.Length); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(0, element.MemoryBuffer.Value.Length); Assert.False(element.EndOfPacket); Assert.Null(element.FilePath); } @@ -59,6 +61,8 @@ public void BufferCtorNormal_Success() Assert.Equal(10, element.Buffer.Length); Assert.Equal(0, element.Offset); Assert.Equal(10, element.Count); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(element.Count, element.MemoryBuffer.Value.Length); Assert.False(element.EndOfPacket); Assert.Null(element.FilePath); } @@ -107,6 +111,8 @@ public void BufferCtorEndOfBufferTrue_Success() Assert.Equal(10, element.Buffer.Length); Assert.Equal(2, element.Offset); Assert.Equal(8, element.Count); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(element.Count, element.MemoryBuffer.Value.Length); Assert.True(element.EndOfPacket); Assert.Null(element.FilePath); } @@ -119,6 +125,8 @@ public void BufferCtorEndOfBufferFalse_Success() Assert.Equal(10, element.Buffer.Length); Assert.Equal(6, element.Offset); Assert.Equal(4, element.Count); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(element.Count, element.MemoryBuffer.Value.Length); Assert.False(element.EndOfPacket); Assert.Null(element.FilePath); } @@ -132,6 +140,8 @@ public void BufferCtorZeroCount_Success() Assert.Equal(0, element.Buffer.Length); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(element.Count, element.MemoryBuffer.Value.Length); Assert.False(element.EndOfPacket); Assert.Null(element.FilePath); } @@ -146,6 +156,8 @@ public void EmptyBufferCtor_OffsetLong_FileStream_Success() Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.Equal(0, element.OffsetLong); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(element.Count, element.MemoryBuffer.Value.Length); Assert.False(element.EndOfPacket); Assert.Null(element.FilePath); Assert.Null(element.FileStream); @@ -160,6 +172,8 @@ public void BufferCtorNormal_OffsetLong_FileStream_Success() Assert.Equal(0, element.Offset); Assert.Equal(10, element.Count); Assert.Equal(0, element.OffsetLong); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(element.Count, element.MemoryBuffer.Value.Length); Assert.False(element.EndOfPacket); Assert.Null(element.FilePath); Assert.Null(element.FileStream); @@ -174,6 +188,8 @@ public void BufferCtorEndOfBufferTrue_OffsetLong_FileStream_Success() Assert.Equal(2, element.Offset); Assert.Equal(8, element.Count); Assert.Equal(2, element.OffsetLong); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(element.Count, element.MemoryBuffer.Value.Length); Assert.True(element.EndOfPacket); Assert.Null(element.FilePath); Assert.Null(element.FileStream); @@ -188,6 +204,8 @@ public void BufferCtorEndOfBufferFalse_OffsetLong_FileStream_Success() Assert.Equal(6, element.Offset); Assert.Equal(4, element.Count); Assert.Equal(6, element.OffsetLong); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(element.Count, element.MemoryBuffer.Value.Length); Assert.False(element.EndOfPacket); Assert.Null(element.FilePath); Assert.Null(element.FileStream); @@ -203,6 +221,8 @@ public void BufferCtorZeroCount_OffsetLong_FileStream_Success() Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.Equal(0, element.OffsetLong); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(element.Count, element.MemoryBuffer.Value.Length); Assert.False(element.EndOfPacket); Assert.Null(element.FilePath); Assert.Null(element.FileStream); @@ -210,6 +230,81 @@ public void BufferCtorZeroCount_OffsetLong_FileStream_Success() #endregion Buffer + #region Memory + + [Fact] + public void EmptyMemoryCtor_Success() + { + SendPacketsElement element = new SendPacketsElement(default(ReadOnlyMemory)); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(0, element.MemoryBuffer.Value.Length); + Assert.Null(element.Buffer); + Assert.Equal(0, element.Offset); + Assert.Equal(element.MemoryBuffer.Value.Length, element.Count); + Assert.False(element.EndOfPacket); + Assert.Null(element.FilePath); + Assert.Null(element.FileStream); + } + + [Fact] + public void MemoryCtorNormal_Success() + { + SendPacketsElement element = new SendPacketsElement(new byte[10].AsMemory()); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(10, element.MemoryBuffer.Value.Length); + Assert.Null(element.Buffer); + Assert.Equal(0, element.Offset); + Assert.Equal(element.MemoryBuffer.Value.Length, element.Count); + Assert.False(element.EndOfPacket); + Assert.Null(element.FilePath); + Assert.Null(element.FileStream); + } + + [Fact] + public void MemoryCtorEndOfPacketTrue_Success() + { + SendPacketsElement element = new SendPacketsElement(new ReadOnlyMemory(new byte[10], 2, 8), true); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(8, element.MemoryBuffer.Value.Length); + Assert.Null(element.Buffer); + Assert.Equal(0, element.Offset); + Assert.Equal(element.MemoryBuffer.Value.Length, element.Count); + Assert.True(element.EndOfPacket); + Assert.Null(element.FilePath); + Assert.Null(element.FileStream); + } + + [Fact] + public void memoryCtorEndOfPacketFalse_Success() + { + SendPacketsElement element = new SendPacketsElement(new ReadOnlyMemory(new byte[10], 6, 4), false); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(4, element.MemoryBuffer.Value.Length); + Assert.Null(element.Buffer); + Assert.Equal(0, element.Offset); + Assert.Equal(element.MemoryBuffer.Value.Length, element.Count); + Assert.False(element.EndOfPacket); + Assert.Null(element.FilePath); + Assert.Null(element.FileStream); + } + + [Fact] + public void MemoryCtorZeroCount_Success() + { + // Elements with empty Buffers are ignored on Send + SendPacketsElement element = new SendPacketsElement(new ReadOnlyMemory(new byte[0], 0, 0)); + Assert.NotNull(element.MemoryBuffer); + Assert.Equal(0, element.MemoryBuffer.Value.Length); + Assert.Null(element.Buffer); + Assert.Equal(0, element.Offset); + Assert.Equal(element.MemoryBuffer.Value.Length, element.Count); + Assert.False(element.EndOfPacket); + Assert.Null(element.FilePath); + Assert.Null(element.FileStream); + } + + #endregion Memory + #region File [Fact] @@ -235,6 +330,7 @@ public void FileCtorEmpty_Success() // An exception will happen on send if this file doesn't exist SendPacketsElement element = new SendPacketsElement(string.Empty); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.False(element.EndOfPacket); @@ -247,6 +343,7 @@ public void FileCtorWhiteSpace_Success() // An exception will happen on send if this file doesn't exist SendPacketsElement element = new SendPacketsElement(" \t "); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.False(element.EndOfPacket); @@ -259,6 +356,7 @@ public void FileCtorNormal_Success() // An exception will happen on send if this file doesn't exist SendPacketsElement element = new SendPacketsElement("SomeFileName"); // Send whole file Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.False(element.EndOfPacket); @@ -271,6 +369,7 @@ public void FileCtorZeroCountLength_Success() // An exception will happen on send if this file doesn't exist SendPacketsElement element = new SendPacketsElement("SomeFileName", 0, 0); // Send whole file Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.False(element.EndOfPacket); @@ -310,6 +409,7 @@ public void FileCtorEndOfBufferTrue_Success() { SendPacketsElement element = new SendPacketsElement("SomeFileName", 2, 8, true); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(2, element.Offset); Assert.Equal(8, element.Count); Assert.True(element.EndOfPacket); @@ -321,6 +421,7 @@ public void FileCtorEndOfBufferFalse_Success() { SendPacketsElement element = new SendPacketsElement("SomeFileName", 6, 4, false); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(6, element.Offset); Assert.Equal(4, element.Count); Assert.False(element.EndOfPacket); @@ -346,6 +447,7 @@ public void FileCtorEmpty_OffsetLong_Success() // An exception will happen on send if this file doesn't exist SendPacketsElement element = new SendPacketsElement(string.Empty); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.Equal(0, element.OffsetLong); @@ -360,6 +462,7 @@ public void FileCtorNormal_OffsetLong_FileStream_Success() SendPacketsElement element = new SendPacketsElement("SomeFileName"); // Send whole file Assert.Null(element.FileStream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.Equal(0, element.OffsetLong); @@ -374,6 +477,7 @@ public void FileCtorZeroCountLength_OffsetLong_FileStream_Success() SendPacketsElement element = new SendPacketsElement("SomeFileName", 0, 0); // Send whole file Assert.Null(element.FileStream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.Equal(0, element.OffsetLong); @@ -384,6 +488,7 @@ public void FileCtorZeroCountLength_OffsetLong_FileStream_Success() element = new SendPacketsElement("SomeFileName", 0L, 0); // Send whole file Assert.Null(element.FileStream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.Equal(0, element.OffsetLong); @@ -423,6 +528,7 @@ public void FileCtorEndOfBufferTrue_OffsetLong_FileStream_Success() SendPacketsElement element = new SendPacketsElement("SomeFileName", 2, 8, true); Assert.Null(element.FileStream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(2, element.Offset); Assert.Equal(8, element.Count); Assert.Equal(2, element.OffsetLong); @@ -432,6 +538,7 @@ public void FileCtorEndOfBufferTrue_OffsetLong_FileStream_Success() element = new SendPacketsElement("SomeFileName", 2L, 8, true); Assert.Null(element.FileStream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(2, element.Offset); Assert.Equal(8, element.Count); Assert.Equal(2, element.OffsetLong); @@ -441,6 +548,7 @@ public void FileCtorEndOfBufferTrue_OffsetLong_FileStream_Success() element = new SendPacketsElement("SomeFileName", (long)int.MaxValue + 2, 8, true); Assert.Null(element.FileStream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Throws(() => { var ofset = element.Offset; @@ -457,6 +565,7 @@ public void FileCtorEndOfBufferFalse_OffsetLong_FileStream_Success() SendPacketsElement element = new SendPacketsElement("SomeFileName", 6, 4, false); Assert.Null(element.FileStream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(6, element.Offset); Assert.Equal(4, element.Count); Assert.Equal(6, element.OffsetLong); @@ -466,6 +575,7 @@ public void FileCtorEndOfBufferFalse_OffsetLong_FileStream_Success() element = new SendPacketsElement("SomeFileName", 6L, 4, false); Assert.Null(element.FileStream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(6, element.Offset); Assert.Equal(4, element.Count); Assert.Equal(6, element.OffsetLong); @@ -475,6 +585,7 @@ public void FileCtorEndOfBufferFalse_OffsetLong_FileStream_Success() element = new SendPacketsElement("SomeFileName", (long)int.MaxValue + 6, 4, false); Assert.Null(element.FileStream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Throws(() => { var ofset = element.Offset; @@ -485,9 +596,9 @@ public void FileCtorEndOfBufferFalse_OffsetLong_FileStream_Success() Assert.Equal("SomeFileName", element.FilePath); } - #endregion File +#endregion File - #region FileStream +#region FileStream [Fact] public void FileStreamCtorNull_Throws() @@ -515,6 +626,7 @@ public void FileStreamCtorNormal_Success() Assert.Null(element.FilePath); Assert.Equal(element.FileStream, stream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.Equal(0, element.OffsetLong); @@ -531,6 +643,7 @@ public void FileStreamCtorZeroCountLength_Success() Assert.Null(element.FilePath); Assert.Equal(element.FileStream, stream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.Equal(0, element.OffsetLong); @@ -540,6 +653,7 @@ public void FileStreamCtorZeroCountLength_Success() Assert.Null(element.FilePath); Assert.Equal(element.FileStream, stream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(0, element.Offset); Assert.Equal(0, element.Count); Assert.Equal(0, element.OffsetLong); @@ -618,6 +732,7 @@ public void FileStreamCtorEndOfBufferTrue_Success() Assert.Null(element.FilePath); Assert.Equal(element.FileStream, stream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(2, element.Offset); Assert.Equal(8, element.Count); Assert.Equal(2, element.OffsetLong); @@ -627,6 +742,7 @@ public void FileStreamCtorEndOfBufferTrue_Success() Assert.Null(element.FilePath); Assert.Equal(element.FileStream, stream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(2, element.Offset); Assert.Equal(8, element.Count); Assert.Equal(2, element.OffsetLong); @@ -636,6 +752,7 @@ public void FileStreamCtorEndOfBufferTrue_Success() Assert.Null(element.FilePath); Assert.Equal(element.FileStream, stream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Throws(() => { var ofset = element.Offset; @@ -655,6 +772,7 @@ public void FileStreamCtorEndOfBufferFalse_Success() Assert.Null(element.FilePath); Assert.Equal(element.FileStream, stream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(6, element.Offset); Assert.Equal(4, element.Count); Assert.Equal(6, element.OffsetLong); @@ -664,6 +782,7 @@ public void FileStreamCtorEndOfBufferFalse_Success() Assert.Null(element.FilePath); Assert.Equal(element.FileStream, stream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Equal(6, element.Offset); Assert.Equal(4, element.Count); Assert.Equal(6, element.OffsetLong); @@ -673,6 +792,7 @@ public void FileStreamCtorEndOfBufferFalse_Success() Assert.Null(element.FilePath); Assert.Equal(element.FileStream, stream); Assert.Null(element.Buffer); + Assert.Null(element.MemoryBuffer); Assert.Throws(() => { var ofset = element.Offset; @@ -683,6 +803,6 @@ public void FileStreamCtorEndOfBufferFalse_Success() } } - #endregion FileStream +#endregion FileStream } } From 51512378ac0bd3fbcc979344e70573dfe282af56 Mon Sep 17 00:00:00 2001 From: Geoff Kizer Date: Thu, 14 Jan 2021 10:14:51 -0800 Subject: [PATCH 2/7] Update src/libraries/System.Net.Sockets/src/System/Net/Sockets/SendPacketsElement.cs Co-authored-by: Stephen Toub --- .../src/System/Net/Sockets/SendPacketsElement.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SendPacketsElement.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SendPacketsElement.cs index 2ba1a4a919a6cb..028b1b4623b374 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SendPacketsElement.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SendPacketsElement.cs @@ -106,7 +106,7 @@ public SendPacketsElement(byte[] buffer, int offset, int count, bool endOfPacket } public SendPacketsElement(ReadOnlyMemory buffer) : - this(buffer, false) + this(buffer, endOfPacket: false) { } public SendPacketsElement(ReadOnlyMemory buffer, bool endOfPacket) From 0daac85f6490cfd630be101c19c8b12e08e63818 Mon Sep 17 00:00:00 2001 From: Geoffrey Kizer Date: Thu, 14 Jan 2021 20:39:36 -0800 Subject: [PATCH 3/7] remove unneeded OuterLoop --- .../tests/FunctionalTests/SendPacketsAsync.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs index 13662db2364ca5..9b6a3e60458a5e 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs @@ -52,7 +52,6 @@ public SendPacketsAsync(ITestOutputHelper output) #region Basic Arguments - [OuterLoop] [Theory] [InlineData(SocketImplementationType.APM)] [InlineData(SocketImplementationType.Async)] @@ -74,7 +73,6 @@ public void Disposed_Throw(SocketImplementationType type) } } - [OuterLoop] [Theory] [InlineData(SocketImplementationType.APM)] [InlineData(SocketImplementationType.Async)] @@ -104,7 +102,6 @@ public void NotConnected_Throw() }); } - [OuterLoop] [Theory] [InlineData(SocketImplementationType.APM)] [InlineData(SocketImplementationType.Async)] @@ -113,7 +110,6 @@ public void NullList_Throws(SocketImplementationType type) AssertExtensions.Throws("e", () => SendPackets(type, (SendPacketsElement[])null, SocketError.Success, 0)); } - [OuterLoop] [Theory] [InlineData(SocketImplementationType.APM)] [InlineData(SocketImplementationType.Async)] @@ -122,7 +118,6 @@ public void NullElement_Ignored(SocketImplementationType type) SendPackets(type, (SendPacketsElement)null, 0); } - [OuterLoop] [Theory] [InlineData(SocketImplementationType.APM)] [InlineData(SocketImplementationType.Async)] @@ -131,7 +126,6 @@ public void EmptyList_Ignored(SocketImplementationType type) SendPackets(type, new SendPacketsElement[0], SocketError.Success, 0); } - [OuterLoop] [Fact] public void SocketAsyncEventArgs_DefaultSendSize_0() { From 823ce39b45680a682eacde8fe8a266447360b5a2 Mon Sep 17 00:00:00 2001 From: Geoffrey Kizer Date: Thu, 14 Jan 2021 20:55:11 -0800 Subject: [PATCH 4/7] just use one SocketImplementationType for server --- .../tests/FunctionalTests/SendPacketsAsync.cs | 408 +++++++----------- 1 file changed, 158 insertions(+), 250 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs index 9b6a3e60458a5e..8c663fe78b0c47 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs @@ -52,13 +52,11 @@ public SendPacketsAsync(ITestOutputHelper output) #region Basic Arguments - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void Disposed_Throw(SocketImplementationType type) + [Fact] + public void Disposed_Throw() { int port; - using (SocketTestServer.SocketTestServerFactory(type, _serverAddress, out port)) + using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, _serverAddress, out port)) { using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) { @@ -73,13 +71,11 @@ public void Disposed_Throw(SocketImplementationType type) } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void NullArgs_Throw(SocketImplementationType type) + [Fact] + public void NullArgs_Throw() { int port; - using (SocketTestServer.SocketTestServerFactory(type, _serverAddress, out port)) + using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, _serverAddress, out port)) { using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) { @@ -102,28 +98,22 @@ public void NotConnected_Throw() }); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void NullList_Throws(SocketImplementationType type) + [Fact] + public void NullList_Throws() { - AssertExtensions.Throws("e", () => SendPackets(type, (SendPacketsElement[])null, SocketError.Success, 0)); + AssertExtensions.Throws("e", () => SendPackets((SendPacketsElement[])null, SocketError.Success, 0)); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void NullElement_Ignored(SocketImplementationType type) + [Fact] + public void NullElement_Ignored() { - SendPackets(type, (SendPacketsElement)null, 0); + SendPackets((SendPacketsElement)null, 0); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void EmptyList_Ignored(SocketImplementationType type) + [Fact] + public void EmptyList_Ignored() { - SendPackets(type, new SendPacketsElement[0], SocketError.Success, 0); + SendPackets(new SendPacketsElement[0], SocketError.Success, 0); } [Fact] @@ -137,42 +127,32 @@ public void SocketAsyncEventArgs_DefaultSendSize_0() #region Buffers - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void NormalBuffer_Success(SocketImplementationType type) + [Fact] + public void NormalBuffer_Success() { - SendPackets(type, new SendPacketsElement(new byte[10]), 10); + SendPackets(new SendPacketsElement(new byte[10]), 10); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void NormalBufferRange_Success(SocketImplementationType type) + [Fact] + public void NormalBufferRange_Success() { - SendPackets(type, new SendPacketsElement(new byte[10], 5, 5), 5); + SendPackets(new SendPacketsElement(new byte[10], 5, 5), 5); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void EmptyBuffer_Ignored(SocketImplementationType type) + [Fact] + public void EmptyBuffer_Ignored() { - SendPackets(type, new SendPacketsElement(new byte[0]), 0); + SendPackets(new SendPacketsElement(new byte[0]), 0); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void BufferZeroCount_Ignored(SocketImplementationType type) + [Fact] + public void BufferZeroCount_Ignored() { - SendPackets(type, new SendPacketsElement(new byte[10], 4, 0), 0); + SendPackets(new SendPacketsElement(new byte[10], 4, 0), 0); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void BufferMixedBuffers_ZeroCountBufferIgnored(SocketImplementationType type) + [Fact] + public void BufferMixedBuffers_ZeroCountBufferIgnored() { SendPacketsElement[] elements = new SendPacketsElement[] { @@ -180,20 +160,18 @@ public void BufferMixedBuffers_ZeroCountBufferIgnored(SocketImplementationType t new SendPacketsElement(new byte[10], 4, 4), new SendPacketsElement(new byte[10], 0, 4) }; - SendPackets(type, elements, SocketError.Success, 8); + SendPackets(elements, SocketError.Success, 8); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void BufferZeroCountThenNormal_ZeroCountIgnored(SocketImplementationType type) + [Fact] + public void BufferZeroCountThenNormal_ZeroCountIgnored() { Assert.True(Capability.IPv6Support()); EventWaitHandle completed = new ManualResetEvent(false); int port; - using (SocketTestServer.SocketTestServerFactory(type, _serverAddress, out port)) + using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, _serverAddress, out port)) { using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) { @@ -238,42 +216,32 @@ public void BufferZeroCountThenNormal_ZeroCountIgnored(SocketImplementationType #region Memory - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void NormalMemory_Success(SocketImplementationType type) + [Fact] + public void NormalMemory_Success() { - SendPackets(type, new SendPacketsElement(new ReadOnlyMemory(new byte[10])), 10); + SendPackets(new SendPacketsElement(new ReadOnlyMemory(new byte[10])), 10); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void NormalMemoryRange_Success(SocketImplementationType type) + [Fact] + public void NormalMemoryRange_Success() { - SendPackets(type, new SendPacketsElement(new ReadOnlyMemory(new byte[10], 5, 5)), 5); + SendPackets(new SendPacketsElement(new ReadOnlyMemory(new byte[10], 5, 5)), 5); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void EmptyMemory_Ignored(SocketImplementationType type) + [Fact] + public void EmptyMemory_Ignored() { - SendPackets(type, new SendPacketsElement(new ReadOnlyMemory(new byte[0])), 0); + SendPackets(new SendPacketsElement(new ReadOnlyMemory(new byte[0])), 0); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void MemoryZeroCount_Ignored(SocketImplementationType type) + [Fact] + public void MemoryZeroCount_Ignored() { - SendPackets(type, new SendPacketsElement(new ReadOnlyMemory(new byte[10], 4, 0)), 0); + SendPackets(new SendPacketsElement(new ReadOnlyMemory(new byte[10], 4, 0)), 0); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void MemoryMixedBuffers_ZeroCountMemoryIgnored(SocketImplementationType type) + [Fact] + public void MemoryMixedBuffers_ZeroCountMemoryIgnored() { SendPacketsElement[] elements = new SendPacketsElement[] { @@ -281,20 +249,18 @@ public void MemoryMixedBuffers_ZeroCountMemoryIgnored(SocketImplementationType t new SendPacketsElement(new ReadOnlyMemory(new byte[10], 4, 4)), new SendPacketsElement(new ReadOnlyMemory(new byte[10], 0, 4)) }; - SendPackets(type, elements, SocketError.Success, 8); + SendPackets(elements, SocketError.Success, 8); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void MemoryZeroCountThenNormal_ZeroCountIgnored(SocketImplementationType type) + [Fact] + public void MemoryZeroCountThenNormal_ZeroCountIgnored() { Assert.True(Capability.IPv6Support()); EventWaitHandle completed = new ManualResetEvent(false); int port; - using (SocketTestServer.SocketTestServerFactory(type, _serverAddress, out port)) + using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, _serverAddress, out port)) { using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) { @@ -338,115 +304,94 @@ public void MemoryZeroCountThenNormal_ZeroCountIgnored(SocketImplementationType #endregion Memory #region TransmitFileOptions - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SocketDisconnected_TransmitFileOptionDisconnect(SocketImplementationType type) + + [Fact] + public void SocketDisconnected_TransmitFileOptionDisconnect() { - SendPackets(type, new SendPacketsElement(new byte[10], 4, 4), TransmitFileOptions.Disconnect, 4); + SendPackets(new SendPacketsElement(new byte[10], 4, 4), TransmitFileOptions.Disconnect, 4); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SocketDisconnectedAndReusable_TransmitFileOptionReuseSocket(SocketImplementationType type) + [Fact] + public void SocketDisconnectedAndReusable_TransmitFileOptionReuseSocket() { - SendPackets(type, new SendPacketsElement(new byte[10], 4, 4), TransmitFileOptions.Disconnect | TransmitFileOptions.ReuseSocket, 4); + SendPackets(new SendPacketsElement(new byte[10], 4, 4), TransmitFileOptions.Disconnect | TransmitFileOptions.ReuseSocket, 4); } #endregion #region Files - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_EmptyFileName_Throws(SocketImplementationType type) + [Fact] + public void SendPacketsElement_EmptyFileName_Throws() { AssertExtensions.Throws("path", null, () => { - SendPackets(type, new SendPacketsElement(string.Empty), 0); + SendPackets(new SendPacketsElement(string.Empty), 0); }); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] + [Fact] [PlatformSpecific(TestPlatforms.Windows)] // whitespace-only is a valid name on Unix - public void SendPacketsElement_BlankFileName_Throws(SocketImplementationType type) + public void SendPacketsElement_BlankFileName_Throws() { AssertExtensions.Throws("path", null, () => { // Existence is validated on send - SendPackets(type, new SendPacketsElement(" "), 0); + SendPackets(new SendPacketsElement(" "), 0); }); } - [Theory] + [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/25099")] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] [PlatformSpecific(TestPlatforms.Windows)] // valid filename chars on Unix - public void SendPacketsElement_BadCharactersFileName_Throws(SocketImplementationType type) + public void SendPacketsElement_BadCharactersFileName_Throws() { AssertExtensions.Throws("path", null, () => { // Existence is validated on send - SendPackets(type, new SendPacketsElement("blarkd@dfa?/sqersf"), 0); + SendPackets(new SendPacketsElement("blarkd@dfa?/sqersf"), 0); }); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_MissingDirectoryName_Throws(SocketImplementationType type) + [Fact] + public void SendPacketsElement_MissingDirectoryName_Throws() { Assert.Throws(() => { // Existence is validated on send - SendPackets(type, new SendPacketsElement(Path.Combine("nodir", "nofile")), 0); + SendPackets(new SendPacketsElement(Path.Combine("nodir", "nofile")), 0); }); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_MissingFile_Throws(SocketImplementationType type) + [Fact] + public void SendPacketsElement_MissingFile_Throws() { Assert.Throws(() => { // Existence is validated on send - SendPackets(type, new SendPacketsElement("DoesntExit"), 0); + SendPackets(new SendPacketsElement("DoesntExit"), 0); }); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_File_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_File_Success() { - SendPackets(type, new SendPacketsElement(TestFileName), s_testFileSize); // Whole File + SendPackets(new SendPacketsElement(TestFileName), s_testFileSize); // Whole File } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileZeroCount_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileZeroCount_Success() { - SendPackets(type, new SendPacketsElement(TestFileName, 0, 0), s_testFileSize); // Whole File + SendPackets(new SendPacketsElement(TestFileName, 0, 0), s_testFileSize); // Whole File } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FilePart_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FilePart_Success() { - SendPackets(type, new SendPacketsElement(TestFileName, 10, 20), 20); + SendPackets(new SendPacketsElement(TestFileName, 10, 20), 20); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileMultiPart_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileMultiPart_Success() { var elements = new[] { @@ -454,31 +399,25 @@ public void SendPacketsElement_FileMultiPart_Success(SocketImplementationType ty new SendPacketsElement(TestFileName, 30, 10), new SendPacketsElement(TestFileName, 0, 10), }; - SendPackets(type, elements, SocketError.Success, 40); + SendPackets(elements, SocketError.Success, 40); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileLargeOffset_Throws(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileLargeOffset_Throws() { // Length is validated on Send - SendPackets(type, new SendPacketsElement(TestFileName, 11000, 1), SocketError.InvalidArgument, 0); + SendPackets(new SendPacketsElement(TestFileName, 11000, 1), SocketError.InvalidArgument, 0); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileLargeCount_Throws(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileLargeCount_Throws() { // Length is validated on Send - SendPackets(type, new SendPacketsElement(TestFileName, 5, 10000), SocketError.InvalidArgument, 0); + SendPackets(new SendPacketsElement(TestFileName, 5, 10000), SocketError.InvalidArgument, 0); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamIsReleasedOnError(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileStreamIsReleasedOnError() { // this test checks that FileStreams opened by the implementation of SendPacketsAsync // are properly disposed of when the SendPacketsAsync operation fails asynchronously. @@ -490,7 +429,7 @@ public void SendPacketsElement_FileStreamIsReleasedOnError(SocketImplementationT EventWaitHandle completed1 = new ManualResetEvent(false); EventWaitHandle completed2 = new ManualResetEvent(false); - using (SocketTestServer.SocketTestServerFactory(type, _serverAddress, out int port)) + using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, _serverAddress, out int port)) { using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) { @@ -531,28 +470,22 @@ public void SendPacketsElement_FileStreamIsReleasedOnError(SocketImplementationT } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileZeroCount_OffsetLong_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileZeroCount_OffsetLong_Success() { var element = new SendPacketsElement(TestFileName, 0L, 0); - SendPackets(type, element, s_testFileSize, GetExpectedContent(element)); // Whole File + SendPackets(element, s_testFileSize, GetExpectedContent(element)); // Whole File } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FilePart_OffsetLong_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FilePart_OffsetLong_Success() { var element = new SendPacketsElement(TestFileName, 10L, 20); - SendPackets(type, element, 20, GetExpectedContent(element)); + SendPackets(element, 20, GetExpectedContent(element)); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileMultiPart_OffsetLong_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileMultiPart_OffsetLong_Success() { var elements = new[] { @@ -560,102 +493,88 @@ public void SendPacketsElement_FileMultiPart_OffsetLong_Success(SocketImplementa new SendPacketsElement(TestFileName, 30L, 10), new SendPacketsElement(TestFileName, 0L, 10), }; - SendPackets(type, elements, SocketError.Success, 40, GetExpectedContent(elements)); + SendPackets(elements, SocketError.Success, 40, GetExpectedContent(elements)); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileLargeOffset_OffsetLong_Throws(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileLargeOffset_OffsetLong_Throws() { // Length is validated on Send - SendPackets(type, new SendPacketsElement(TestFileName, (long)uint.MaxValue + 11000, 1), SocketError.InvalidArgument, 0); + SendPackets(new SendPacketsElement(TestFileName, (long)uint.MaxValue + 11000, 1), SocketError.InvalidArgument, 0); } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileLargeCount_OffsetLong_Throws(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileLargeCount_OffsetLong_Throws() { // Length is validated on Send - SendPackets(type, new SendPacketsElement(TestFileName, 5L, 10000), SocketError.InvalidArgument, 0); + SendPackets(new SendPacketsElement(TestFileName, 5L, 10000), SocketError.InvalidArgument, 0); } #endregion Files #region FileStreams - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStream_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileStream_Success() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true)) { stream.Seek(s_testFileSize / 2, SeekOrigin.Begin); - SendPackets(type, new SendPacketsElement(stream), s_testFileSize); // Whole File + SendPackets(new SendPacketsElement(stream), s_testFileSize); // Whole File Assert.Equal(s_testFileSize / 2, stream.Position); - SendPackets(type, new SendPacketsElement(stream), s_testFileSize); // Whole File + SendPackets(new SendPacketsElement(stream), s_testFileSize); // Whole File Assert.Equal(s_testFileSize / 2, stream.Position); } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamZeroCount_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileStreamZeroCount_Success() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true)) { stream.Seek(s_testFileSize / 2, SeekOrigin.Begin); - SendPackets(type, new SendPacketsElement(stream, 0, 0), s_testFileSize); // Whole File + SendPackets(new SendPacketsElement(stream, 0, 0), s_testFileSize); // Whole File Assert.Equal(s_testFileSize / 2, stream.Position); - SendPackets(type, new SendPacketsElement(stream, 0, 0), s_testFileSize); // Whole File + SendPackets(new SendPacketsElement(stream, 0, 0), s_testFileSize); // Whole File Assert.Equal(s_testFileSize / 2, stream.Position); } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamSizeCount_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileStreamSizeCount_Success() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true)) { stream.Seek(s_testFileSize / 2, SeekOrigin.Begin); - SendPackets(type, new SendPacketsElement(stream, 0, s_testFileSize), s_testFileSize); // Whole File + SendPackets(new SendPacketsElement(stream, 0, s_testFileSize), s_testFileSize); // Whole File Assert.Equal(s_testFileSize / 2, stream.Position); - SendPackets(type, new SendPacketsElement(stream, 0, s_testFileSize), s_testFileSize); // Whole File + SendPackets(new SendPacketsElement(stream, 0, s_testFileSize), s_testFileSize); // Whole File Assert.Equal(s_testFileSize / 2, stream.Position); } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamPart_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileStreamPart_Success() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true)) { stream.Seek(s_testFileSize - 10, SeekOrigin.Begin); - SendPackets(type, new SendPacketsElement(stream, 0, 20), 20); + SendPackets(new SendPacketsElement(stream, 0, 20), 20); Assert.Equal(s_testFileSize - 10, stream.Position); - SendPackets(type, new SendPacketsElement(stream, 10, 20), 20); + SendPackets(new SendPacketsElement(stream, 10, 20), 20); Assert.Equal(s_testFileSize - 10, stream.Position); - SendPackets(type, new SendPacketsElement(stream, s_testFileSize - 20, 20), 20); + SendPackets(new SendPacketsElement(stream, s_testFileSize - 20, 20), 20); Assert.Equal(s_testFileSize - 10, stream.Position); } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamMultiPart_Success(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileStreamMultiPart_Success() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) { @@ -668,48 +587,42 @@ public void SendPacketsElement_FileStreamMultiPart_Success(SocketImplementationT new SendPacketsElement(stream, 30, 10), }; stream.Seek(s_testFileSize - 10, SeekOrigin.Begin); - SendPackets(type, elements, SocketError.Success, 70, GetExpectedContent(elements)); + SendPackets(elements, SocketError.Success, 70, GetExpectedContent(elements)); Assert.Equal(s_testFileSize - 10, stream.Position); - SendPackets(type, elements, SocketError.Success, 70, GetExpectedContent(elements)); + SendPackets(elements, SocketError.Success, 70, GetExpectedContent(elements)); Assert.Equal(s_testFileSize - 10, stream.Position); } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamLargeOffset_Throws(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileStreamLargeOffset_Throws() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true)) { stream.Seek(s_testFileSize / 2, SeekOrigin.Begin); // Length is validated on Send - SendPackets(type, new SendPacketsElement(stream, (long)uint.MaxValue + 11000, 1), SocketError.InvalidArgument, 0); + SendPackets(new SendPacketsElement(stream, (long)uint.MaxValue + 11000, 1), SocketError.InvalidArgument, 0); } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamLargeCount_Throws(SocketImplementationType type) + [Fact] + public void SendPacketsElement_FileStreamLargeCount_Throws() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true)) { stream.Seek(s_testFileSize / 2, SeekOrigin.Begin); // Length is validated on Send - SendPackets(type, new SendPacketsElement(stream, 5, 10000), - SocketError.InvalidArgument, 0); + SendPackets(new SendPacketsElement(stream, 5, 10000), SocketError.InvalidArgument, + 0); } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamWithOptions_Success(SocketImplementationType type) { + [Fact] + public void SendPacketsElement_FileStreamWithOptions_Success() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan)) { var element = new SendPacketsElement(stream, 0, s_testFileSize); - SendPackets(type, element, s_testFileSize, GetExpectedContent(element)); + SendPackets(element, s_testFileSize, GetExpectedContent(element)); } } @@ -717,10 +630,8 @@ public void SendPacketsElement_FileStreamWithOptions_Success(SocketImplementatio #region Mixed Buffer, FilePath, FileStream tests - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamMultiPartMixed_Success(SocketImplementationType type) { + [Fact] + public void SendPacketsElement_FileStreamMultiPartMixed_Success() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) { var elements = new[] { @@ -734,14 +645,12 @@ public void SendPacketsElement_FileStreamMultiPartMixed_Success(SocketImplementa new SendPacketsElement(new byte[] { 8, 9, 10 }, 0, 3), }; byte[] expected = GetExpectedContent(elements); - SendPackets(type, elements, SocketError.Success, expected.Length, expected); + SendPackets(elements, SocketError.Success, expected.Length, expected); } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamMultiPartMixed_MultipleFileStreams_Success(SocketImplementationType type) { + [Fact] + public void SendPacketsElement_FileStreamMultiPartMixed_MultipleFileStreams_Success() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) using (var stream2 = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) { var elements = new[] @@ -756,14 +665,12 @@ public void SendPacketsElement_FileStreamMultiPartMixed_MultipleFileStreams_Succ new SendPacketsElement(TestFileName, 30, 10), }; byte[] expected = GetExpectedContent(elements); - SendPackets(type, elements, SocketError.Success, expected.Length, expected); + SendPackets(elements, SocketError.Success, expected.Length, expected); } } - [Theory] - [InlineData(SocketImplementationType.APM)] - [InlineData(SocketImplementationType.Async)] - public void SendPacketsElement_FileStreamMultiPartMixed_MultipleWholeFiles_Success(SocketImplementationType type) { + [Fact] + public void SendPacketsElement_FileStreamMultiPartMixed_MultipleWholeFiles_Success() { using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) { var elements = new[] { @@ -773,21 +680,22 @@ public void SendPacketsElement_FileStreamMultiPartMixed_MultipleWholeFiles_Succe new SendPacketsElement(TestFileName, 0L, 10), }; byte[] expected = GetExpectedContent(elements); - SendPackets(type, elements, SocketError.Success, expected.Length, expected); + SendPackets(elements, SocketError.Success, expected.Length, expected); } } #endregion #region Helpers - private void SendPackets(SocketImplementationType type, SendPacketsElement element, TransmitFileOptions flags, int bytesExpected) + + private void SendPackets(SendPacketsElement element, TransmitFileOptions flags, int bytesExpected) { Assert.True(Capability.IPv6Support()); EventWaitHandle completed = new ManualResetEvent(false); int port; - using (SocketTestServer.SocketTestServerFactory(type, _serverAddress, out port)) + using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, _serverAddress, out port)) { using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) { @@ -822,24 +730,24 @@ private void SendPackets(SocketImplementationType type, SendPacketsElement eleme } } - private void SendPackets(SocketImplementationType type, SendPacketsElement element, int bytesExpected, byte[] contentExpected = null) + private void SendPackets(SendPacketsElement element, int bytesExpected, byte[] contentExpected = null) { - SendPackets(type, new[] {element}, SocketError.Success, bytesExpected, contentExpected); + SendPackets(new[] { element }, SocketError.Success, bytesExpected, contentExpected); } - private void SendPackets(SocketImplementationType type, SendPacketsElement element, SocketError expectedResult, int bytesExpected) + private void SendPackets(SendPacketsElement element, SocketError expectedResult, int bytesExpected) { - SendPackets(type, new[] {element}, expectedResult, bytesExpected); + SendPackets(new[] { element }, expectedResult, bytesExpected); } - private void SendPackets(SocketImplementationType type, SendPacketsElement[] elements, SocketError expectedResult, int bytesExpected, byte[] contentExpected = null) + private void SendPackets(SendPacketsElement[] elements, SocketError expectedResult, int bytesExpected, byte[] contentExpected = null) { Assert.True(Capability.IPv6Support()); EventWaitHandle completed = new ManualResetEvent(false); int port; - using (SocketTestServer.SocketTestServerFactory(type, _serverAddress, out port)) + using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, _serverAddress, out port)) { using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) { From 35d27fefc8b30ddffbee57d0e2245b1890ab41ec Mon Sep 17 00:00:00 2001 From: Geoffrey Kizer Date: Thu, 14 Jan 2021 21:25:39 -0800 Subject: [PATCH 5/7] parameterize some buffer tests --- .../tests/FunctionalTests/SendPacketsAsync.cs | 84 ++++++++++++++++--- 1 file changed, 72 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs index 8c663fe78b0c47..d27f542aa362bb 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers; using System.IO; using System.Net.Test.Common; using System.Threading; @@ -127,28 +128,56 @@ public void SocketAsyncEventArgs_DefaultSendSize_0() #region Buffers - [Fact] - public void NormalBuffer_Success() + [Theory] + [InlineData(BufferType.ByteArray)] + [InlineData(BufferType.ManagedMemory)] + [InlineData(BufferType.NativeMemory)] + public void NormalBuffer_Success(BufferType bufferType) { - SendPackets(new SendPacketsElement(new byte[10]), 10); + (SendPacketsElement element, MemoryManager memoryManager) = CreateElementForBuffer(bufferType, 10); + using (memoryManager) + { + SendPackets(element, 10); + } } - [Fact] - public void NormalBufferRange_Success() + [Theory] + [InlineData(BufferType.ByteArray)] + [InlineData(BufferType.ManagedMemory)] + [InlineData(BufferType.NativeMemory)] + public void NormalBufferRange_Success(BufferType bufferType) { - SendPackets(new SendPacketsElement(new byte[10], 5, 5), 5); + (SendPacketsElement element, MemoryManager memoryManager) = CreateElementForBuffer(bufferType, 10, 5, 5); + using (memoryManager) + { + SendPackets(element, 5); + } } - [Fact] - public void EmptyBuffer_Ignored() + [Theory] + [InlineData(BufferType.ByteArray)] + [InlineData(BufferType.ManagedMemory)] + [InlineData(BufferType.NativeMemory)] + public void EmptyBuffer_Ignored(BufferType bufferType) { - SendPackets(new SendPacketsElement(new byte[0]), 0); + (SendPacketsElement element, MemoryManager memoryManager) = CreateElementForBuffer(bufferType, 0); + using (memoryManager) + { + SendPackets(element, 0); + } } - [Fact] - public void BufferZeroCount_Ignored() + [Theory] + [InlineData(BufferType.ByteArray)] + [InlineData(BufferType.ManagedMemory)] + [InlineData(BufferType.NativeMemory)] + public void BufferZeroCount_Ignored(BufferType bufferType) { - SendPackets(new SendPacketsElement(new byte[10], 4, 0), 0); + (SendPacketsElement element, MemoryManager memoryManager) = CreateElementForBuffer(bufferType, 10, 4, 0); + using (memoryManager) + { + SendPackets(element, 0); + } } [Fact] @@ -844,6 +873,37 @@ int FileCount(SendPacketsElement element) { return result; } + public enum BufferType + { + ByteArray, + ManagedMemory, + NativeMemory + } + + private static (SendPacketsElement, MemoryManager) CreateElementForNativeBuffer(int size, int offset, int count) + { + MemoryManager memoryManager = new NativeMemoryManager(size); + return (new SendPacketsElement(memoryManager.Memory.Slice(offset, count)), memoryManager); + } + + private static (SendPacketsElement, MemoryManager) CreateElementForBuffer(BufferType bufferType, int size) => + bufferType switch + { + BufferType.ByteArray => (new SendPacketsElement(new byte[size]), null), + BufferType.ManagedMemory => (new SendPacketsElement(new ReadOnlyMemory(new byte[size])), null), + BufferType.NativeMemory => CreateElementForNativeBuffer(size, 0, size), + _ => throw new InvalidOperationException() + }; + + private static (SendPacketsElement, MemoryManager) CreateElementForBuffer(BufferType bufferType, int size, int offset, int count) => + bufferType switch + { + BufferType.ByteArray => (new SendPacketsElement(new byte[size], offset, count), null), + BufferType.ManagedMemory => (new SendPacketsElement(new ReadOnlyMemory(new byte[size], offset, count)), null), + BufferType.NativeMemory => CreateElementForNativeBuffer(size, offset, count), + _ => throw new InvalidOperationException() + }; + #endregion Helpers } } From 4a3964e898cc8902b4e2cf9c7b60220e94f85a74 Mon Sep 17 00:00:00 2001 From: Geoffrey Kizer Date: Thu, 14 Jan 2021 21:44:21 -0800 Subject: [PATCH 6/7] rework MemoryManager handling --- .../tests/FunctionalTests/SendPacketsAsync.cs | 77 ++++++++++--------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs index d27f542aa362bb..57a46a3e6b7381 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs @@ -134,11 +134,8 @@ public void SocketAsyncEventArgs_DefaultSendSize_0() [InlineData(BufferType.NativeMemory)] public void NormalBuffer_Success(BufferType bufferType) { - (SendPacketsElement element, MemoryManager memoryManager) = CreateElementForBuffer(bufferType, 10); - using (memoryManager) - { - SendPackets(element, 10); - } + using var e = CreateElementForBuffer(bufferType, 10); + SendPackets(e.Element, 10); } [Theory] @@ -147,11 +144,8 @@ public void NormalBuffer_Success(BufferType bufferType) [InlineData(BufferType.NativeMemory)] public void NormalBufferRange_Success(BufferType bufferType) { - (SendPacketsElement element, MemoryManager memoryManager) = CreateElementForBuffer(bufferType, 10, 5, 5); - using (memoryManager) - { - SendPackets(element, 5); - } + using var e = CreateElementForBuffer(bufferType, 10, 5, 5); + SendPackets(e.Element, 5); } [Theory] @@ -160,11 +154,8 @@ public void NormalBufferRange_Success(BufferType bufferType) [InlineData(BufferType.NativeMemory)] public void EmptyBuffer_Ignored(BufferType bufferType) { - (SendPacketsElement element, MemoryManager memoryManager) = CreateElementForBuffer(bufferType, 0); - using (memoryManager) - { - SendPackets(element, 0); - } + using var e = CreateElementForBuffer(bufferType, 0); + SendPackets(e.Element, 0); } [Theory] @@ -173,22 +164,21 @@ public void EmptyBuffer_Ignored(BufferType bufferType) [InlineData(BufferType.NativeMemory)] public void BufferZeroCount_Ignored(BufferType bufferType) { - (SendPacketsElement element, MemoryManager memoryManager) = CreateElementForBuffer(bufferType, 10, 4, 0); - using (memoryManager) - { - SendPackets(element, 0); - } + using var e = CreateElementForBuffer(bufferType, 10, 4, 0); + SendPackets(e.Element, 0); } - [Fact] - public void BufferMixedBuffers_ZeroCountBufferIgnored() + [Theory] + [InlineData(BufferType.ByteArray)] + [InlineData(BufferType.ManagedMemory)] + [InlineData(BufferType.NativeMemory)] + public void BufferMixedBuffers_ZeroCountBufferIgnored(BufferType bufferType) { - SendPacketsElement[] elements = new SendPacketsElement[] - { - new SendPacketsElement(new byte[10], 4, 0), // Ignored - new SendPacketsElement(new byte[10], 4, 4), - new SendPacketsElement(new byte[10], 0, 4) - }; + using var e1 = CreateElementForBuffer(bufferType, 10, 4, 0); + using var e2 = CreateElementForBuffer(bufferType, 10, 4, 4); + using var e3 = CreateElementForBuffer(bufferType, 10, 0, 4); + + SendPacketsElement[] elements = new SendPacketsElement[] { e1.Element, e2.Element, e3.Element }; SendPackets(elements, SocketError.Success, 8); } @@ -880,26 +870,41 @@ public enum BufferType NativeMemory } - private static (SendPacketsElement, MemoryManager) CreateElementForNativeBuffer(int size, int offset, int count) + private struct ElementWithMemoryManager : IDisposable + { + public ElementWithMemoryManager(SendPacketsElement element, MemoryManager memoryManager) + { + Element = element; + MemoryManager = memoryManager; + } + + public SendPacketsElement Element { get; init; } + public MemoryManager MemoryManager { get; init; } + + public void Dispose() => ((IDisposable)MemoryManager)?.Dispose(); + + } + + private static ElementWithMemoryManager CreateElementForNativeBuffer(int size, int offset, int count) { MemoryManager memoryManager = new NativeMemoryManager(size); - return (new SendPacketsElement(memoryManager.Memory.Slice(offset, count)), memoryManager); + return new ElementWithMemoryManager(new SendPacketsElement(memoryManager.Memory.Slice(offset, count)), memoryManager); } - private static (SendPacketsElement, MemoryManager) CreateElementForBuffer(BufferType bufferType, int size) => + private static ElementWithMemoryManager CreateElementForBuffer(BufferType bufferType, int size) => bufferType switch { - BufferType.ByteArray => (new SendPacketsElement(new byte[size]), null), - BufferType.ManagedMemory => (new SendPacketsElement(new ReadOnlyMemory(new byte[size])), null), + BufferType.ByteArray => new ElementWithMemoryManager(new SendPacketsElement(new byte[size]), null), + BufferType.ManagedMemory => new ElementWithMemoryManager(new SendPacketsElement(new ReadOnlyMemory(new byte[size])), null), BufferType.NativeMemory => CreateElementForNativeBuffer(size, 0, size), _ => throw new InvalidOperationException() }; - private static (SendPacketsElement, MemoryManager) CreateElementForBuffer(BufferType bufferType, int size, int offset, int count) => + private static ElementWithMemoryManager CreateElementForBuffer(BufferType bufferType, int size, int offset, int count) => bufferType switch { - BufferType.ByteArray => (new SendPacketsElement(new byte[size], offset, count), null), - BufferType.ManagedMemory => (new SendPacketsElement(new ReadOnlyMemory(new byte[size], offset, count)), null), + BufferType.ByteArray => new ElementWithMemoryManager(new SendPacketsElement(new byte[size], offset, count), null), + BufferType.ManagedMemory => new ElementWithMemoryManager(new SendPacketsElement(new ReadOnlyMemory(new byte[size], offset, count)), null), BufferType.NativeMemory => CreateElementForNativeBuffer(size, offset, count), _ => throw new InvalidOperationException() }; From 172a3a1dadbab4825b3199d1bc47fe1b79c9373f Mon Sep 17 00:00:00 2001 From: Geoffrey Kizer Date: Thu, 14 Jan 2021 23:30:47 -0800 Subject: [PATCH 7/7] finish test parameterization --- .../tests/FunctionalTests/SendPacketsAsync.cs | 113 ++---------------- 1 file changed, 12 insertions(+), 101 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs index 57a46a3e6b7381..6a17ca72a9681d 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs @@ -182,8 +182,11 @@ public void BufferMixedBuffers_ZeroCountBufferIgnored(BufferType bufferType) SendPackets(elements, SocketError.Success, 8); } - [Fact] - public void BufferZeroCountThenNormal_ZeroCountIgnored() + [Theory] + [InlineData(BufferType.ByteArray)] + [InlineData(BufferType.ManagedMemory)] + [InlineData(BufferType.NativeMemory)] + public void BufferZeroCountThenNormal_ZeroCountIgnored(BufferType bufferType) { Assert.True(Capability.IPv6Support()); @@ -201,118 +204,26 @@ public void BufferZeroCountThenNormal_ZeroCountIgnored() args.UserToken = completed; // First do an empty send, ignored - args.SendPacketsElements = new SendPacketsElement[] - { - new SendPacketsElement(new byte[5], 3, 0) - }; - + using var e1 = CreateElementForBuffer(bufferType, 5, 3, 0); + args.SendPacketsElements = new SendPacketsElement[] { e1.Element }; if (sock.SendPacketsAsync(args)) { Assert.True(completed.WaitOne(TestSettings.PassingTestTimeout), "Timed out"); } - Assert.Equal(SocketError.Success, args.SocketError); - Assert.Equal(0, args.BytesTransferred); - - completed.Reset(); - // Now do a real send - args.SendPacketsElements = new SendPacketsElement[] - { - new SendPacketsElement(new byte[5], 1, 4) - }; - if (sock.SendPacketsAsync(args)) - { - Assert.True(completed.WaitOne(TestSettings.PassingTestTimeout), "Timed out"); - } - Assert.Equal(SocketError.Success, args.SocketError); - Assert.Equal(4, args.BytesTransferred); - } - } - } - } - - #endregion Buffers - - #region Memory - - [Fact] - public void NormalMemory_Success() - { - SendPackets(new SendPacketsElement(new ReadOnlyMemory(new byte[10])), 10); - } - - [Fact] - public void NormalMemoryRange_Success() - { - SendPackets(new SendPacketsElement(new ReadOnlyMemory(new byte[10], 5, 5)), 5); - } - - [Fact] - public void EmptyMemory_Ignored() - { - SendPackets(new SendPacketsElement(new ReadOnlyMemory(new byte[0])), 0); - } - - [Fact] - public void MemoryZeroCount_Ignored() - { - SendPackets(new SendPacketsElement(new ReadOnlyMemory(new byte[10], 4, 0)), 0); - } - - [Fact] - public void MemoryMixedBuffers_ZeroCountMemoryIgnored() - { - SendPacketsElement[] elements = new SendPacketsElement[] - { - new SendPacketsElement(new ReadOnlyMemory(new byte[10], 4, 0)), // Ignored - new SendPacketsElement(new ReadOnlyMemory(new byte[10], 4, 4)), - new SendPacketsElement(new ReadOnlyMemory(new byte[10], 0, 4)) - }; - SendPackets(elements, SocketError.Success, 8); - } - - [Fact] - public void MemoryZeroCountThenNormal_ZeroCountIgnored() - { - Assert.True(Capability.IPv6Support()); - - EventWaitHandle completed = new ManualResetEvent(false); - - int port; - using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, _serverAddress, out port)) - { - using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) - { - sock.Connect(new IPEndPoint(_serverAddress, port)); - using (SocketAsyncEventArgs args = new SocketAsyncEventArgs()) - { - args.Completed += OnCompleted; - args.UserToken = completed; - - // First do an empty send, ignored - args.SendPacketsElements = new SendPacketsElement[] - { - new SendPacketsElement(new ReadOnlyMemory(new byte[5], 3, 0)) - }; - - if (sock.SendPacketsAsync(args)) - { - Assert.True(completed.WaitOne(TestSettings.PassingTestTimeout), "Timed out"); - } Assert.Equal(SocketError.Success, args.SocketError); Assert.Equal(0, args.BytesTransferred); completed.Reset(); - // Now do a real send - args.SendPacketsElements = new SendPacketsElement[] - { - new SendPacketsElement(new ReadOnlyMemory(new byte[5], 1, 4)) - }; + // Now do a real send + using var e2 = CreateElementForBuffer(bufferType, 5, 1, 4); + args.SendPacketsElements = new SendPacketsElement[] { e2.Element }; if (sock.SendPacketsAsync(args)) { Assert.True(completed.WaitOne(TestSettings.PassingTestTimeout), "Timed out"); } + Assert.Equal(SocketError.Success, args.SocketError); Assert.Equal(4, args.BytesTransferred); } @@ -320,7 +231,7 @@ public void MemoryZeroCountThenNormal_ZeroCountIgnored() } } - #endregion Memory + #endregion Buffers #region TransmitFileOptions