From 0fe9097f63b8049419a776eb735ba1b2c7db04f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Thu, 24 Sep 2026 02:27:09 +0100 Subject: [PATCH] Fix NetworkStream write core - Add back check for bytes sent. - Add unit tests to cover NetworkStream. --- Tests/SocketTests/NetworkStreamTests.cs | 129 ++++++++++++++++++ Tests/SocketTests/SocketTests.nfproj | 1 + .../Sockets/NetworkStream.cs | 2 +- 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 Tests/SocketTests/NetworkStreamTests.cs diff --git a/Tests/SocketTests/NetworkStreamTests.cs b/Tests/SocketTests/NetworkStreamTests.cs new file mode 100644 index 0000000..94c2162 --- /dev/null +++ b/Tests/SocketTests/NetworkStreamTests.cs @@ -0,0 +1,129 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using nanoFramework.TestFramework; +using System; +using System.Net; +using System.Net.Sockets; + +namespace NFUnitTestSocketTests +{ + [TestClass] + public class NetworkStreamTests + { + private const int ServerPort = 7010; + + [Setup] + public void SetupNetworkStreamTests() + { + // Comment next line to run the tests on a real hardware + Assert.SkipTest("Skipping tests using nanoCLR Win32 in a pipeline"); + } + + [TestMethod] + public void NetworkStream_Write_ByteArray_SendsData() + { + byte[] sent = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 }; + + RunLoopbackTest((stream, peer) => + { + stream.Write(sent, 0, sent.Length); + + AssertReceived(peer, sent); + }); + } + + [TestMethod] + public void NetworkStream_Write_ByteArrayWithOffset_SendsData() + { + byte[] buffer = new byte[] { 0xFF, 0x11, 0x22, 0x33, 0xFF }; + + RunLoopbackTest((stream, peer) => + { + stream.Write(buffer, 1, 3); + + AssertReceived(peer, new byte[] { 0x11, 0x22, 0x33 }); + }); + } + + [TestMethod] + public void NetworkStream_Write_Span_SendsData() + { + byte[] sent = new byte[] { 0xAB, 0xCD, 0xEF }; + + RunLoopbackTest((stream, peer) => + { + stream.Write(new ReadOnlySpan(sent)); + + AssertReceived(peer, sent); + }); + } + + [TestMethod] + public void NetworkStream_Write_ZeroLength_DoesNotThrow() + { + RunLoopbackTest((stream, peer) => + { + stream.Write(new byte[0], 0, 0); + }); + } + + private delegate void LoopbackTestAction(NetworkStream stream, Socket peer); + + private static void RunLoopbackTest(LoopbackTestAction test) + { + Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + Socket peer = null; + NetworkStream stream = null; + + try + { + listener.Bind(new IPEndPoint(IPAddress.Loopback, ServerPort)); + listener.Listen(1); + + client.Connect(new IPEndPoint(IPAddress.Loopback, ServerPort)); + peer = listener.Accept(); + + stream = new NetworkStream(client, true); + + test(stream, peer); + } + finally + { + if (stream != null) + { + // stream owns the client socket + stream.Close(); + } + else + { + client.Close(); + } + + peer?.Close(); + listener.Close(); + } + } + + private static void AssertReceived(Socket peer, byte[] expected) + { + byte[] received = new byte[expected.Length]; + int totalRead = 0; + + while (totalRead < expected.Length) + { + int read = peer.Receive(received, totalRead, expected.Length - totalRead, SocketFlags.None); + + Assert.IsTrue(read > 0, "Connection closed before all data was received"); + + totalRead += read; + } + + for (int i = 0; i < expected.Length; i++) + { + Assert.AreEqual(expected[i], received[i], $"Data mismatch at index {i}"); + } + } + } +} diff --git a/Tests/SocketTests/SocketTests.nfproj b/Tests/SocketTests/SocketTests.nfproj index b6f0608..0be3bc0 100644 --- a/Tests/SocketTests/SocketTests.nfproj +++ b/Tests/SocketTests/SocketTests.nfproj @@ -27,6 +27,7 @@ + diff --git a/nanoFramework.System.Net/Sockets/NetworkStream.cs b/nanoFramework.System.Net/Sockets/NetworkStream.cs index 3df43fa..225c498 100644 --- a/nanoFramework.System.Net/Sockets/NetworkStream.cs +++ b/nanoFramework.System.Net/Sockets/NetworkStream.cs @@ -487,7 +487,7 @@ private void WriteCore(byte[] buffer, int offset, int count) throw new NotSupportedException(); } - if (0 != count) + if (bytesSent != count) { throw new IOException(); }