Skip to content

Commit 1e7a70c

Browse files
committed
Add tests for exceptions thrown during startup
1 parent a819265 commit 1e7a70c

File tree

4 files changed

+165
-9
lines changed

4 files changed

+165
-9
lines changed

com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,7 +1357,6 @@ public bool StartServer()
13571357
Debug.LogException(ex);
13581358
// Always shutdown to assure everything is cleaned up
13591359
ShutdownInternal();
1360-
ConnectionManager.LocalClient.SetRole(false, false);
13611360
IsListening = false;
13621361
}
13631362

@@ -1412,7 +1411,7 @@ public bool StartClient()
14121411
catch (Exception ex)
14131412
{
14141413
Debug.LogException(ex);
1415-
ConnectionManager.LocalClient.SetRole(false, false);
1414+
ShutdownInternal();
14161415
IsListening = false;
14171416
}
14181417

@@ -1471,7 +1470,6 @@ public bool StartHost()
14711470
Debug.LogException(ex);
14721471
// Always shutdown to assure everything is cleaned up
14731472
ShutdownInternal();
1474-
ConnectionManager.LocalClient.SetRole(false, false);
14751473
IsListening = false;
14761474
}
14771475

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
using System;
2+
using System.Collections;
3+
using NUnit.Framework;
4+
using Unity.Netcode.TestHelpers.Runtime;
5+
using Unity.Netcode.Transports.UTP;
6+
using UnityEngine;
7+
using UnityEngine.TestTools;
8+
using Object = System.Object;
9+
10+
namespace Unity.Netcode.RuntimeTests
11+
{
12+
[TestFixture(StartType.Server)]
13+
[TestFixture(StartType.Host)]
14+
[TestFixture(StartType.Client)]
15+
internal class StartupExceptionTests : NetcodeIntegrationTest
16+
{
17+
protected override int NumberOfClients => 0;
18+
19+
public enum StartType
20+
{
21+
Server,
22+
Host,
23+
Client
24+
}
25+
26+
private StartType m_StartType;
27+
public StartupExceptionTests(StartType startType) : base(startType == StartType.Server ? HostOrServer.Server : HostOrServer.Host)
28+
{
29+
m_StartType = startType;
30+
}
31+
32+
private const string k_ExceptionText = "This is a test exception";
33+
34+
private void ThrowExceptionAction()
35+
{
36+
throw new Exception(k_ExceptionText);
37+
}
38+
39+
private SessionConfig SessionConfigExceptionThrower()
40+
{
41+
throw new Exception(k_ExceptionText);
42+
}
43+
44+
private void OnPeerConnectedException(NetworkManager networkManager, ConnectionEventData connectionEventData)
45+
{
46+
if (connectionEventData.EventType == ConnectionEvent.PeerConnected)
47+
{
48+
ThrowExceptionAction();
49+
}
50+
}
51+
52+
private void OnClientConnectedException(NetworkManager networkManager, ConnectionEventData connectionEventData)
53+
{
54+
if (connectionEventData.EventType == ConnectionEvent.ClientConnected)
55+
{
56+
ThrowExceptionAction();
57+
}
58+
}
59+
60+
61+
[UnityTest]
62+
public IEnumerator VerifyNetworkManagerHandlesExceptionDuringStart()
63+
{
64+
var startType = m_StartType;
65+
NetworkManager toTest;
66+
if (startType == StartType.Client)
67+
{
68+
toTest = CreateNewClient();
69+
}
70+
else
71+
{
72+
toTest = GetAuthorityNetworkManager();
73+
yield return StopOneClient(toTest);
74+
}
75+
76+
var transport = toTest.NetworkConfig.NetworkTransport as UnityTransport;
77+
Assert.That(transport, Is.Not.Null, "Transport should not be null");
78+
79+
var isListening = true;
80+
81+
/*
82+
* Test exception being thrown during NetworkManager.Initialize()
83+
*/
84+
85+
// It's not possible to throw an exception during server initialization
86+
if (startType != StartType.Server)
87+
{
88+
// OnSessionConfig is called within Initialize only in DAMode
89+
toTest.NetworkConfig.NetworkTopology = NetworkTopologyTypes.DistributedAuthority;
90+
91+
toTest.OnGetSessionConfig += SessionConfigExceptionThrower;
92+
93+
LogAssert.Expect(LogType.Exception, $"Exception: {k_ExceptionText}");
94+
isListening = startType == StartType.Host ? toTest.StartHost() : toTest.StartClient();
95+
96+
Assert.That(isListening, Is.False, "Should not have started after exception during Initialize()");
97+
Assert.That(transport.GetNetworkDriver().IsCreated, Is.False, "NetworkDriver should not be created.");
98+
99+
toTest.OnGetSessionConfig -= SessionConfigExceptionThrower;
100+
toTest.NetworkConfig.NetworkTopology = NetworkTopologyTypes.ClientServer;
101+
}
102+
103+
/*
104+
* Test exception being thrown after NetworkTransport.StartClient()
105+
*/
106+
107+
toTest.OnClientStarted += ThrowExceptionAction;
108+
toTest.OnServerStarted += ThrowExceptionAction;
109+
110+
LogAssert.Expect(LogType.Exception, $"Exception: {k_ExceptionText}");
111+
isListening = startType switch
112+
{
113+
StartType.Server => toTest.StartServer(),
114+
StartType.Host => toTest.StartHost(),
115+
StartType.Client => toTest.StartClient(),
116+
_ => true
117+
};
118+
119+
Assert.That(isListening, Is.False, "Should not have started after exception during startup");
120+
Assert.That(transport.GetNetworkDriver().IsCreated, Is.False, "NetworkDriver should not be created.");
121+
122+
toTest.OnClientStarted -= ThrowExceptionAction;
123+
toTest.OnServerStarted -= ThrowExceptionAction;
124+
125+
if (startType == StartType.Client)
126+
{
127+
// Start the client fully to ensure startup still works with no exceptions
128+
yield return StartClient(toTest);
129+
130+
Assert.That(toTest.IsListening, Is.True, "Client failed to start");
131+
Assert.That(transport.GetNetworkDriver().IsCreated, Is.True, "NetworkDriver should be created.");
132+
}
133+
else
134+
{
135+
var isHost = startType == StartType.Host;
136+
NetcodeIntegrationTestHelpers.StartServer(isHost, toTest);
137+
var hostOrServer = isHost ? "Host" : "Server";
138+
Assert.That(toTest.IsListening, Is.True, $"{hostOrServer} failed to start");
139+
Assert.That(transport.GetNetworkDriver().IsCreated, Is.True, "NetworkDriver should be created.");
140+
141+
yield return CreateAndStartNewClient();
142+
}
143+
}
144+
145+
}
146+
}

com.unity.netcode.gameobjects/Tests/Runtime/Connection/StartupExceptionTests.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTestHelpers.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -571,17 +571,26 @@ public static bool Start(bool host, NetworkManager server, NetworkManager[] clie
571571
}
572572

573573
s_IsStarted = true;
574+
return StartInternal(host, server, clients, callback, startServer);
575+
}
576+
577+
internal static bool StartServer(bool host, NetworkManager server)
578+
{
579+
return StartInternal(host, server, new NetworkManager[]{});
580+
}
581+
582+
583+
private static bool StartInternal(bool host, NetworkManager server, NetworkManager[] clients, BeforeClientStartCallback callback = null, bool startServer = true)
584+
{
574585
s_ClientCount = clients.Length;
575586
var hooks = (MultiInstanceHooks)null;
576587
if (startServer)
577588
{
578-
if (host)
579-
{
580-
server.StartHost();
581-
}
582-
else
589+
var isListening = host ? server.StartHost() : server.StartServer();
590+
591+
if (!isListening)
583592
{
584-
server.StartServer();
593+
return false;
585594
}
586595

587596
hooks = new MultiInstanceHooks();

0 commit comments

Comments
 (0)