Skip to content

Commit 6446754

Browse files
test
Adding the integration test to validate the analytics data collection flow/process. Adding the ability to make adjustments during integration testing from assemblies outside of the TestHelper runtime scope.
1 parent 97fc86d commit 6446754

File tree

5 files changed

+216
-0
lines changed

5 files changed

+216
-0
lines changed

com.unity.netcode.gameobjects/TestHelpers/Runtime/AssemblyInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[assembly: InternalsVisibleTo("Unity.Netcode.RuntimeTests")]
55
[assembly: InternalsVisibleTo("TestProject.RuntimeTests")]
66
#if UNITY_EDITOR
7+
[assembly: InternalsVisibleTo("Unity.Netcode.Editor")]
78
[assembly: InternalsVisibleTo("TestProject.EditorTests")]
89
#endif // UNITY_EDITOR
910
#if MULTIPLAYER_TOOLS

com.unity.netcode.gameobjects/TestHelpers/Runtime/NetcodeIntegrationTest.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@ public void OneTimeSetup()
301301

302302
// Enable NetcodeIntegrationTest auto-label feature
303303
NetcodeIntegrationTestHelpers.RegisterNetcodeIntegrationTest(true);
304+
305+
#if UNITY_INCLUDE_TESTS
306+
// Provide an external hook to be able to make adjustments to netcode classes prior to running any tests
307+
NetworkManager.OnOneTimeSetup();
308+
#endif
309+
304310
OnOneTimeSetup();
305311

306312
VerboseDebug($"Exiting {nameof(OneTimeSetup)}");
@@ -1293,6 +1299,10 @@ public void OneTimeTearDown()
12931299
UnloadRemainingScenes();
12941300

12951301
VerboseDebug($"Exiting {nameof(OneTimeTearDown)}");
1302+
#if UNITY_INCLUDE_TESTS
1303+
// Provide an external hook to be able to make adjustments to netcode classes after running tests
1304+
NetworkManager.OnOneTimeTearDown();
1305+
#endif
12961306

12971307
IsRunning = false;
12981308
}
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
#if UNITY_EDITOR
2+
using System.Collections;
3+
using NUnit.Framework;
4+
using Unity.Netcode;
5+
using Unity.Netcode.Editor;
6+
using Unity.Netcode.TestHelpers.Runtime;
7+
using UnityEngine.TestTools;
8+
9+
namespace TestProject.RuntimeTests
10+
{
11+
/// <summary>
12+
/// In-Editor only test<br />
13+
/// Validates the analytics event data collection process.<br />
14+
/// <see cref="ValidateCollectionProcess"/>
15+
/// </summary>
16+
internal class AnalyticsTests : NetcodeIntegrationTest
17+
{
18+
protected override int NumberOfClients => 0;
19+
20+
private NetcodeAnalytics m_NetcodeAnalytics;
21+
22+
protected override IEnumerator OnSetup()
23+
{
24+
NetcodeAnalytics.IsIntegrationTest = true;
25+
m_NetcodeAnalytics = Unity.Netcode.Editor.NetworkManagerHelper.Singleton.NetcodeAnalytics;
26+
yield return base.OnSetup();
27+
}
28+
29+
protected override IEnumerator OnTearDown()
30+
{
31+
NetcodeAnalytics.IsIntegrationTest = false;
32+
yield return base.OnTearDown();
33+
}
34+
35+
private bool m_NetworkManagerStarted;
36+
private bool m_NetworkManagerStopped;
37+
private IEnumerator StartAndStopSession(int expectedCount, bool isHost, bool isDistributedAuthority)
38+
{
39+
m_NetworkManagerStarted = false;
40+
m_NetworkManagerStopped = false;
41+
42+
m_ServerNetworkManager.NetworkConfig.NetworkTopology = isDistributedAuthority ? NetworkTopologyTypes.DistributedAuthority : NetworkTopologyTypes.ClientServer;
43+
44+
if (!isHost)
45+
{
46+
m_ServerNetworkManager.StartServer();
47+
}
48+
else
49+
{
50+
m_ServerNetworkManager.StartHost();
51+
}
52+
yield return WaitForConditionOrTimeOut(() => m_NetworkManagerStarted);
53+
var serverOrHost = isHost ? "Host" : "Server";
54+
AssertOnTimeout($"Failed to start {nameof(NetworkManager)} as a {serverOrHost} using a {m_ServerNetworkManager.NetworkConfig.NetworkTopology} {nameof(NetworkConfig.NetworkTopology)}!");
55+
56+
yield return StopNetworkManager();
57+
}
58+
59+
private IEnumerator StopNetworkManager()
60+
{
61+
var serverOrHost = m_ServerNetworkManager.IsHost ? "Host" : "Server";
62+
63+
m_ServerNetworkManager.Shutdown();
64+
yield return WaitForConditionOrTimeOut(() => m_NetworkManagerStopped);
65+
AssertOnTimeout($"Failed to stop {nameof(NetworkManager)} as a {serverOrHost} using a {m_ServerNetworkManager.NetworkConfig.NetworkTopology} {nameof(NetworkConfig.NetworkTopology)}!");
66+
}
67+
68+
private void OnServerStarted()
69+
{
70+
m_NetworkManagerStarted = true;
71+
}
72+
73+
private void OnServerStopped(bool wasHost)
74+
{
75+
m_NetworkManagerStopped = true;
76+
}
77+
78+
/// <summary>
79+
/// Validates the NGO analytics gathering process: <br />
80+
/// - When entering play mode any previous analytics events should be cleared.<br />
81+
/// - Each session while in play mode should be tracked (minimal processing).<br />
82+
/// - When exiting play mode the sessions should be processed and cleared.<br />
83+
/// - There should only be one unique analytic data event per unique session configuration.<br />
84+
/// </summary>
85+
[UnityTest]
86+
public IEnumerator ValidateCollectionProcess()
87+
{
88+
var expectedCount = 0;
89+
var currentCount = 0;
90+
m_ServerNetworkManager.OnServerStarted += OnServerStarted;
91+
m_ServerNetworkManager.OnServerStopped += OnServerStopped;
92+
m_PlayerPrefab.SetActive(false);
93+
m_ServerNetworkManager.NetworkConfig.PlayerPrefab = null;
94+
yield return StopNetworkManager();
95+
Assert.True(m_NetcodeAnalytics.RecentSessions.Count == 1, $"Expected 1 session but found: {m_NetcodeAnalytics.RecentSessions.Count}!");
96+
Assert.True(m_NetcodeAnalytics.AnalyticsTestResults.Count == 0, $"Expected 0 analytics events but found: {m_NetcodeAnalytics.AnalyticsTestResults.Count}!");
97+
98+
// Simulate exiting play mode
99+
m_NetcodeAnalytics.ModeChanged(UnityEditor.PlayModeStateChange.ExitingPlayMode, m_ServerNetworkManager);
100+
Assert.True(m_NetcodeAnalytics.AnalyticsTestResults.Count == 1, $"Expected 1 analytics event but found: {m_NetcodeAnalytics.AnalyticsTestResults.Count}!");
101+
102+
// Simulate entering play mode
103+
m_NetcodeAnalytics.ModeChanged(UnityEditor.PlayModeStateChange.EnteredPlayMode, m_ServerNetworkManager);
104+
105+
Assert.IsFalse(m_ServerNetworkManager.IsListening, $"Networkmanager should be stopped but is still listening!");
106+
// Client-Server
107+
// Start as a Server and then shutdown
108+
yield return StartAndStopSession(expectedCount, false, false);
109+
expectedCount++;
110+
Assert.True(m_NetcodeAnalytics.RecentSessions.Count == expectedCount, $"Expected {expectedCount} session but found: {m_NetcodeAnalytics.RecentSessions.Count}!");
111+
112+
// Start as a server again with the same settings and then shutdown
113+
// (this should be excluded in the final analytics event data)
114+
yield return StartAndStopSession(expectedCount, false, false);
115+
expectedCount++;
116+
Assert.True(m_NetcodeAnalytics.RecentSessions.Count == expectedCount, $"Expected {expectedCount} session but found: {m_NetcodeAnalytics.RecentSessions.Count}!");
117+
118+
// Start as a Host and then shutdown
119+
yield return StartAndStopSession(expectedCount, true, false);
120+
expectedCount++;
121+
Assert.True(m_NetcodeAnalytics.RecentSessions.Count == expectedCount, $"Expected {expectedCount} session but found: {m_NetcodeAnalytics.RecentSessions.Count}!");
122+
123+
// Start as a DAHost and then shutdown
124+
yield return StartAndStopSession(expectedCount, true, true);
125+
expectedCount++;
126+
Assert.True(m_NetcodeAnalytics.RecentSessions.Count == expectedCount, $"Expected {expectedCount} session but found: {m_NetcodeAnalytics.RecentSessions.Count}!");
127+
128+
// Start as a Host again and then shutdown
129+
// (this should be excluded in the final analytics event data)
130+
yield return StartAndStopSession(expectedCount, true, false);
131+
expectedCount++;
132+
Assert.True(m_NetcodeAnalytics.RecentSessions.Count == expectedCount, $"Expected {expectedCount} session but found: {m_NetcodeAnalytics.RecentSessions.Count}!");
133+
Assert.True(m_NetcodeAnalytics.AnalyticsTestResults.Count == 0, $"Expected 0 analytics events but found: {m_NetcodeAnalytics.AnalyticsTestResults.Count}!");
134+
135+
//////////////////////////////////////////////////
136+
// Validating that each session's configuration is tracked for generating the analytics data events.
137+
// Verify session 1
138+
var session = m_NetcodeAnalytics.RecentSessions[currentCount];
139+
Assert.True(session.WasServer && !session.WasClient, $"Expected session to be started as a server session but it was not! Server: {session.WasServer} Client: {session.WasClient}");
140+
Assert.True(session.NetworkConfig.NetworkTopology == NetworkTopologyTypes.ClientServer, $"Expected session to be a {NetworkTopologyTypes.ClientServer} session but it was {session.NetworkConfig.NetworkTopology}!");
141+
142+
// Verify session 2
143+
currentCount++;
144+
session = m_NetcodeAnalytics.RecentSessions[currentCount];
145+
Assert.True(session.WasServer && !session.WasClient, $"Expected session to be started as a server session but it was not! Server: {session.WasServer} Client: {session.WasClient}");
146+
Assert.True(session.NetworkConfig.NetworkTopology == NetworkTopologyTypes.ClientServer, $"Expected session to be a {NetworkTopologyTypes.ClientServer} session but it was {session.NetworkConfig.NetworkTopology}!");
147+
148+
// Verify session 3
149+
currentCount++;
150+
session = m_NetcodeAnalytics.RecentSessions[currentCount];
151+
Assert.True(session.WasServer && session.WasClient, $"Expected session to be started as a host session but it was not! Server: {session.WasServer}Client: {session.WasClient}");
152+
Assert.True(session.NetworkConfig.NetworkTopology == NetworkTopologyTypes.ClientServer, $"Expected session to be a {NetworkTopologyTypes.ClientServer} session but it was {session.NetworkConfig.NetworkTopology}!");
153+
154+
// Verify session 4
155+
currentCount++;
156+
session = m_NetcodeAnalytics.RecentSessions[currentCount];
157+
Assert.True(session.WasServer && session.WasClient, $"Expected session to be started as a host session but it was not! Server: {session.WasServer}Client: {session.WasClient}");
158+
Assert.True(session.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority, $"Expected session to be a {NetworkTopologyTypes.DistributedAuthority} session but it was {session.NetworkConfig.NetworkTopology}!");
159+
160+
// Verify session 5
161+
currentCount++;
162+
session = m_NetcodeAnalytics.RecentSessions[currentCount];
163+
Assert.True(session.WasServer == true && session.WasClient, $"Expected session to be started as a host session but it was not! Server: {session.WasServer}Client: {session.WasClient}");
164+
Assert.True(session.NetworkConfig.NetworkTopology == NetworkTopologyTypes.ClientServer, $"Expected session to be a {NetworkTopologyTypes.ClientServer} session but it was {session.NetworkConfig.NetworkTopology}!");
165+
166+
//////////////////////////////////////////////////
167+
// Validating that the analytics event data that would be sent should only contain information on the 3 unique session configurations
168+
// Client-Server as a Server
169+
// Client-Server as a Host
170+
// Distributed Authority as a DAHost
171+
m_NetcodeAnalytics.ModeChanged(UnityEditor.PlayModeStateChange.ExitingPlayMode, m_ServerNetworkManager);
172+
173+
// Verify that we cleared out the NetcodeAnalytics.RecentSessions when we exited play mode
174+
Assert.True(m_NetcodeAnalytics.RecentSessions.Count == 0, $"After exiting play mode we expected 0 RecentSessions but had {m_NetcodeAnalytics.RecentSessions.Count}");
175+
176+
// Adjust our expected count to be 2 less than the RecentSessions since we intentionally included two identical sessions.
177+
// (There should only be unique session configurations included in the final analytics event data entries)
178+
expectedCount -= 2;
179+
180+
Assert.True(m_NetcodeAnalytics.AnalyticsTestResults.Count == expectedCount, $"Expected {expectedCount} analytics event but found: {m_NetcodeAnalytics.AnalyticsTestResults.Count}!");
181+
currentCount = 0;
182+
// Verify event data 1
183+
var eventData = m_NetcodeAnalytics.AnalyticsTestResults[currentCount].Data;
184+
Assert.True(eventData.WasServer && !eventData.WasClient, $"Expected session to be started as a server session but it was not! WasServer: {eventData.WasServer} WasClient: {eventData.WasClient}");
185+
Assert.True(!eventData.IsDistributedAuthority, $"Expected IsDistributedAuthority to be false but it was true!");
186+
187+
// Verify event data 2
188+
currentCount++;
189+
eventData = m_NetcodeAnalytics.AnalyticsTestResults[currentCount].Data;
190+
Assert.True(eventData.WasServer && eventData.WasClient, $"Expected session to be started as a Host session but it was not! WasServer: {eventData.WasServer} WasClient: {eventData.WasClient}");
191+
Assert.True(!eventData.IsDistributedAuthority, $"Expected IsDistributedAuthority to be false but it was true!");
192+
193+
// Verify event data 3
194+
currentCount++;
195+
eventData = m_NetcodeAnalytics.AnalyticsTestResults[currentCount].Data;
196+
Assert.True(eventData.WasServer && eventData.WasClient, $"Expected session to be started as a host session but it was not! WasServer: {eventData.WasServer} WasClient: {eventData.WasClient}");
197+
Assert.True(eventData.IsDistributedAuthority, $"Expected IsDistributedAuthority to be true but it was false!");
198+
yield return null;
199+
}
200+
}
201+
}
202+
#endif

testproject/Assets/Tests/Runtime/AnalyticsTests.cs.meta

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

testproject/Assets/Tests/Runtime/testproject.runtimetests.asmdef

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"references": [
55
"Unity.Netcode.Runtime",
66
"Unity.Netcode.RuntimeTests",
7+
"Unity.Netcode.Editor",
78
"TestProject.ManualTests",
89
"TestProject",
910
"Unity.Addressables",

0 commit comments

Comments
 (0)