Skip to content

Commit

Permalink
Merge pull request #1289 from nunit/port-1183
Browse files Browse the repository at this point in the history
Fix hang when test processes fail to terminate correctly
  • Loading branch information
CharliePoole authored Jan 6, 2023
2 parents 70fddea + 3787aed commit acf7239
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 9 deletions.
71 changes: 71 additions & 0 deletions src/NUnitEngine/nunit.engine.tests/Transport/Tcp/TcpServerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using NUnit.Framework;

namespace NUnit.Engine.Communication.Transports.Tcp
{
public class TcpServerTests
{
private TcpServer _server;
private List<Socket> _serverConnections;

[SetUp]
public void StartServer()
{
_serverConnections = new List<Socket>();
_server = new TcpServer();
_server.ClientConnected += (c, g) => _serverConnections.Add(c);
_server.Start();
}

[TearDown]
public void StopServer()
{
_server.Stop();
}

[Test]
public void SingleClientConnection()
{
using (TcpClient client = new TcpClient())
{
client.Connect(_server.EndPoint);
client.Client.Send(new Guid().ToByteArray());

Thread.Sleep(1); // Allow the connection event to run
Assert.That(_serverConnections.Count, Is.EqualTo(1), "Should have received 1 connection event");
Assert.That(_serverConnections[0].Connected, "Server is not connected to client");

Assert.True(client.Connected, "Client is not connected to server");
}
}

[Test]
public void MultipleClientConnections()
{
TcpClient[] clients = new[] { new TcpClient(), new TcpClient(), new TcpClient() };
int num = clients.Length;

foreach (var client in clients)
{
client.Connect(_server.EndPoint);
client.Client.Send(new Guid().ToByteArray());
}

Thread.Sleep(1); // Allow the connection events to run
Assert.That(_serverConnections.Count, Is.EqualTo(num), $"Should have received {num} connection events");

for (int i = 0; i < num; i++)
{
Assert.That(_serverConnections[i].Connected, $"Server is not connected to client {i + 1}");
Assert.True(clients[i].Connected, $"Client {i + 1} is not connected to server");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class TcpServer

private const int GUID_BUFFER_SIZE = 16;

TcpListener _listenerSocket;
TcpListener _tcpListener;
Thread _listenerThread;
volatile bool _running;

Expand All @@ -24,17 +24,21 @@ public class TcpServer

public TcpServer(int port = 0)
{
_listenerSocket = new TcpListener(IPAddress.Loopback, port);
_tcpListener = new TcpListener(IPAddress.Loopback, port);
}

public IPEndPoint EndPoint => (IPEndPoint)_listenerSocket.LocalEndpoint;
public IPEndPoint EndPoint => (IPEndPoint)_tcpListener.LocalEndpoint;

public void Start()
{
_listenerSocket.Start();
_tcpListener.Start();
_running = true;

_listenerThread = new Thread(WaitForClientConnections);
_listenerThread = new Thread(WaitForClientConnections)
{
Name = "TCPLisstenerThread",
IsBackground = true
};
_listenerThread.Start();
}

Expand All @@ -43,7 +47,7 @@ public void Stop()
try
{
_running = false;
_listenerSocket.Stop();
_tcpListener.Stop();
}
catch (Exception exception)
{
Expand All @@ -57,7 +61,7 @@ private void WaitForClientConnections()
{
try
{
var clientSocket = _listenerSocket.AcceptSocket();
var clientSocket = _tcpListener.AcceptSocket();
if (clientSocket.Connected)
{
// Upon connection, remote agent must immediately send its Id as identification.
Expand All @@ -74,7 +78,7 @@ private void WaitForClientConnections()
// 1. We were trying to stop the socket
// 2. The connection was dropped due to some external event
// In either case, we stop the socket and wait a while
_listenerSocket.Stop();
_tcpListener.Stop();

// If we were trying to stop, that's all
if (!_running)
Expand All @@ -84,7 +88,7 @@ private void WaitForClientConnections()
Thread.Sleep(500);
try
{
_listenerSocket.Start();
_tcpListener.Start();
}
catch (Exception exception)
{
Expand Down

0 comments on commit acf7239

Please sign in to comment.