Skip to content

Commit db05292

Browse files
test
Adding the base ComponentController test.
1 parent 1ceb76c commit db05292

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using NUnit.Framework;
5+
using Unity.Netcode.Components;
6+
using Unity.Netcode.TestHelpers.Runtime;
7+
using UnityEngine;
8+
using UnityEngine.TestTools;
9+
10+
namespace Unity.Netcode.RuntimeTests
11+
{
12+
[TestFixture(HostOrServer.Host)]
13+
[TestFixture(HostOrServer.Server)]
14+
[TestFixture(HostOrServer.DAHost)]
15+
internal class ComponentControllerTests : NetcodeIntegrationTest
16+
{
17+
protected override int NumberOfClients => 2;
18+
19+
private StringBuilder m_ErrorLog = new StringBuilder();
20+
private GameObject m_TestPrefab;
21+
22+
private NetworkManager m_Authority;
23+
private ComponentController m_AuthorityController;
24+
25+
public ComponentControllerTests(HostOrServer hostOrServer) : base(hostOrServer) { }
26+
27+
protected override IEnumerator OnSetup()
28+
{
29+
m_ErrorLog.Clear();
30+
yield return base.OnSetup();
31+
}
32+
33+
protected override void OnServerAndClientsCreated()
34+
{
35+
// The source prefab contains the nested NetworkBehaviour that
36+
// will be parented under the target prefab.
37+
m_TestPrefab = CreateNetworkObjectPrefab("TestObject");
38+
var sourceChild = new GameObject("Child");
39+
sourceChild.transform.parent = m_TestPrefab.transform;
40+
var meshRenderer = sourceChild.AddComponent<MeshRenderer>();
41+
var boxCollider = sourceChild.AddComponent<BoxCollider>();
42+
var controller = m_TestPrefab.AddComponent<ComponentController>();
43+
controller.Components = new List<ComponentControllerEntry>
44+
{
45+
new ComponentControllerEntry()
46+
{
47+
Component = meshRenderer,
48+
},
49+
new ComponentControllerEntry()
50+
{
51+
InvertEnabled = true,
52+
Component = boxCollider,
53+
}
54+
};
55+
base.OnServerAndClientsCreated();
56+
}
57+
58+
private bool AllClientsSpawnedInstances()
59+
{
60+
m_ErrorLog.Clear();
61+
foreach (var networkManager in m_NetworkManagers)
62+
{
63+
if (!networkManager.SpawnManager.SpawnedObjects.ContainsKey(m_AuthorityController.NetworkObjectId))
64+
{
65+
m_ErrorLog.AppendLine($"[Client-{networkManager.LocalClientId}] Has not spawned {m_AuthorityController.name} yet!");
66+
}
67+
}
68+
return m_ErrorLog.Length == 0;
69+
}
70+
71+
private void ControllerStateMatches(ComponentController controller)
72+
{
73+
if (m_AuthorityController.EnabledState != controller.EnabledState)
74+
{
75+
m_ErrorLog.AppendLine($"[Client-{controller.NetworkManager.LocalClientId}] The authority controller state ({m_AuthorityController.EnabledState})" +
76+
$" does not match the local controller state ({controller.EnabledState})!");
77+
return;
78+
}
79+
80+
if (m_AuthorityController.ValidComponents.Count != controller.ValidComponents.Count)
81+
{
82+
m_ErrorLog.AppendLine($"[Client-{controller.NetworkManager.LocalClientId}] The authority controller has {m_AuthorityController.ValidComponents.Count} valid components but " +
83+
$"the local instance has {controller.ValidComponents.Count}!");
84+
return;
85+
}
86+
87+
for (int i = 0; i < m_AuthorityController.ValidComponents.Count; i++)
88+
{
89+
var authorityEntry = m_AuthorityController.ValidComponents[i];
90+
var nonAuthorityEntry = controller.ValidComponents[i];
91+
if (authorityEntry.InvertEnabled != nonAuthorityEntry.InvertEnabled)
92+
{
93+
m_ErrorLog.AppendLine($"[Client-{controller.NetworkManager.LocalClientId}] The authority controller's component entry ({i}) " +
94+
$"has an inverted state of {authorityEntry.InvertEnabled} but the local instance has a value of " +
95+
$"{nonAuthorityEntry.InvertEnabled}!");
96+
}
97+
98+
var authorityIsEnabled = (bool)authorityEntry.PropertyInfo.GetValue(authorityEntry.Component);
99+
var nonAuthorityIsEnabled = (bool)nonAuthorityEntry.PropertyInfo.GetValue(authorityEntry.Component);
100+
if (authorityIsEnabled != nonAuthorityIsEnabled)
101+
{
102+
m_ErrorLog.AppendLine($"[Client-{controller.NetworkManager.LocalClientId}] The authority controller's component ({i}) " +
103+
$"entry's enabled state is {authorityIsEnabled} but the local instance's value is {nonAuthorityIsEnabled}!");
104+
}
105+
}
106+
}
107+
108+
private bool AllComponentStatesMatch()
109+
{
110+
m_ErrorLog.Clear();
111+
foreach (var networkManager in m_NetworkManagers)
112+
{
113+
if (!networkManager.SpawnManager.SpawnedObjects.ContainsKey(m_AuthorityController.NetworkObjectId))
114+
{
115+
m_ErrorLog.AppendLine($"[Client-{networkManager.LocalClientId}] Does not have a spawned instance of {m_AuthorityController.name}!");
116+
}
117+
var controller = networkManager.SpawnManager.SpawnedObjects[m_AuthorityController.NetworkObjectId].GetComponent<ComponentController>();
118+
ControllerStateMatches(controller);
119+
}
120+
return m_ErrorLog.Length == 0;
121+
}
122+
123+
private bool AllComponentStatesAreCorrect(bool isEnabled)
124+
{
125+
m_ErrorLog.Clear();
126+
foreach (var networkManager in m_NetworkManagers)
127+
{
128+
if (!networkManager.SpawnManager.SpawnedObjects.ContainsKey(m_AuthorityController.NetworkObjectId))
129+
{
130+
m_ErrorLog.AppendLine($"[Client-{networkManager.LocalClientId}] Does not have a spawned instance of {m_AuthorityController.name}!");
131+
}
132+
var controller = networkManager.SpawnManager.SpawnedObjects[m_AuthorityController.NetworkObjectId].GetComponent<ComponentController>();
133+
for (int i = 0; i < controller.ValidComponents.Count; i++)
134+
{
135+
var componentEntry = controller.ValidComponents[i];
136+
137+
var componentEntryIsEnabled = (bool)componentEntry.PropertyInfo.GetValue(componentEntry.Component);
138+
var valueToCheck = componentEntry.InvertEnabled ? !isEnabled : isEnabled;
139+
140+
if (valueToCheck != componentEntryIsEnabled)
141+
{
142+
m_ErrorLog.AppendLine($"[Client-{controller.NetworkManager.LocalClientId}] The enabled state for entry ({i}) " +
143+
$"should be {valueToCheck} but is {componentEntryIsEnabled}!");
144+
}
145+
}
146+
}
147+
return m_ErrorLog.Length == 0;
148+
}
149+
150+
[UnityTest]
151+
public IEnumerator EnabledDisabledSynchronizationTests()
152+
{
153+
m_Authority = GetAuthorityNetworkManager();
154+
155+
m_AuthorityController = SpawnObject(m_TestPrefab, m_Authority).GetComponent<ComponentController>();
156+
157+
yield return WaitForConditionOrTimeOut(AllClientsSpawnedInstances);
158+
AssertOnTimeout($"All clients did not spawn an instance of {m_AuthorityController.name}!\n {m_ErrorLog}");
159+
160+
// Validate that clients start off with matching states.
161+
yield return WaitForConditionOrTimeOut(AllComponentStatesMatch);
162+
AssertOnTimeout($"Not all client instances matched the authority instance {m_AuthorityController.name}! \n {m_ErrorLog}");
163+
164+
// Validate that all controllers have the correct enabled value for the current authority controller instance's value.
165+
yield return WaitForConditionOrTimeOut(() => AllComponentStatesAreCorrect(m_AuthorityController.EnabledState));
166+
AssertOnTimeout($"Not all client instances have the correct enabled state!\n {m_ErrorLog}");
167+
168+
// Toggle the enabled state of the authority controller
169+
m_AuthorityController.SetEnabled(!m_AuthorityController.EnabledState);
170+
171+
// Validate that all controllers' states match
172+
yield return WaitForConditionOrTimeOut(AllComponentStatesMatch);
173+
AssertOnTimeout($"Not all client instances matched the authority instance {m_AuthorityController.name}! \n {m_ErrorLog}");
174+
175+
// Validate that all controllers have the correct enabled value for the current authority controller instance's value.
176+
yield return WaitForConditionOrTimeOut(() => AllComponentStatesAreCorrect(m_AuthorityController.EnabledState));
177+
AssertOnTimeout($"Not all client instances have the correct enabled state!\n {m_ErrorLog}");
178+
179+
// Late join a client to assure the late joining client's values are synchronized properly
180+
yield return CreateAndStartNewClient();
181+
182+
// Validate that all controllers' states match
183+
yield return WaitForConditionOrTimeOut(AllComponentStatesMatch);
184+
AssertOnTimeout($"Not all client instances matched the authority instance {m_AuthorityController.name}! \n {m_ErrorLog}");
185+
186+
// Validate that all controllers have the correct enabled value for the current authority controller instance's value.
187+
yield return WaitForConditionOrTimeOut(() => AllComponentStatesAreCorrect(m_AuthorityController.EnabledState));
188+
AssertOnTimeout($"Not all client instances have the correct enabled state!\n {m_ErrorLog}");
189+
}
190+
}
191+
}

com.unity.netcode.gameobjects/Tests/Runtime/ComponentControllerTests.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.

0 commit comments

Comments
 (0)