Skip to content

fix: Unity.Netcode.RuntimeTests Failing on Console - v1.1.0 #1653

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
using NUnit.Framework;
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Unity.Netcode.UTP.RuntimeTests
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these changes are part of a backport, approved by Simon

{
public static class RuntimeTestsHelpers
{
// Half a second might seem like a very long time to wait for a network event, but in CI
// many of the machines are underpowered (e.g. old Android devices or Macs) and there are
// sometimes lag spikes that cause can cause delays upwards of 300ms.
// sometimes very high lag spikes. PS4 and Switch are particularly sensitive in this regard
// so we allow even more time for these platforms.
#if UNITY_PS4 || UNITY_SWITCH
public const float MaxNetworkEventWaitTime = 2.0f;
#else
public const float MaxNetworkEventWaitTime = 0.5f;
#endif

// Wait for an event to appear in the given event list (must be the very next event).
public static IEnumerator WaitForNetworkEvent(NetworkEvent type, List<TransportEvent> events)
public static IEnumerator WaitForNetworkEvent(NetworkEvent type, List<TransportEvent> events,
float timeout = MaxNetworkEventWaitTime)
{
int initialCount = events.Count;
float startTime = Time.realtimeSinceStartup;

while (Time.realtimeSinceStartup - startTime < MaxNetworkEventWaitTime)
while (Time.realtimeSinceStartup - startTime < timeout)
{
if (events.Count > initialCount)
{
Assert.AreEqual(type, events[initialCount].Type);
yield break;
}

yield return null;
yield return new WaitForSeconds(0.01f);
}

Assert.Fail("Timed out while waiting for network event.");
Expand Down Expand Up @@ -56,23 +60,22 @@ public struct TransportEvent
public ArraySegment<byte> Data;
public float ReceiveTime;
}

// Utility class that logs events generated by a UnityTransport. Set it up by adding the
// HandleEvent method as an OnTransportEvent delegate of the transport. The list of events
// (in order in which they were generated) can be accessed through the Events property.
public class TransportEventLogger
{
private readonly List<TransportEvent> m_Events = new List<TransportEvent>();
public List<TransportEvent> Events => m_Events;

public void HandleEvent(NetworkEvent type, ulong clientID, ArraySegment<byte> data, float receiveTime)
{
// Copy the data since the backing array will be reused for future messages.
if (data != default(ArraySegment<byte>))
{
data = new ArraySegment<byte>(data.ToArray());
var dataCopy = new byte[data.Count];
Array.Copy(data.Array, data.Offset, dataCopy, 0, data.Count);
data = new ArraySegment<byte>(dataCopy);
}

m_Events.Add(new TransportEvent
{
Type = type,
Expand Down
46 changes: 30 additions & 16 deletions com.unity.netcode.adapter.utp/Tests/Runtime/TransportTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// todo @simon-lemay-unity: un-guard/re-enable after validating UTP on consoles
#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_IOS || UNITY_ANDROID
using NUnit.Framework;
using System;
using System.Collections;
Expand Down Expand Up @@ -30,19 +32,25 @@ public IEnumerator Cleanup()
if (m_Server)
{
m_Server.Shutdown();
UnityEngine.Object.DestroyImmediate(m_Server);

// Need to destroy the GameObject (all assigned components will get destroyed too)
UnityEngine.Object.DestroyImmediate(m_Server.gameObject);
}

if (m_Client1)
{
m_Client1.Shutdown();
UnityEngine.Object.DestroyImmediate(m_Client1);

// Need to destroy the GameObject (all assigned components will get destroyed too)
UnityEngine.Object.DestroyImmediate(m_Client1.gameObject);
}

if (m_Client2)
{
m_Client2.Shutdown();
UnityEngine.Object.DestroyImmediate(m_Client2);

// Need to destroy the GameObject (all assigned components will get destroyed too)
UnityEngine.Object.DestroyImmediate(m_Client2.gameObject);
}

m_ServerEvents?.Clear();
Expand All @@ -62,7 +70,7 @@ public IEnumerator PingPong([ValueSource("k_DeliveryParameters")] NetworkDeliver
m_Server.StartServer();
m_Client1.StartClient();

yield return WaitForNetworkEvent(NetworkEvent.Connect, m_ServerEvents);
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);

var ping = new ArraySegment<byte>(Encoding.ASCII.GetBytes("ping"));
m_Client1.Send(m_Client1.ServerClientId, ping, delivery);
Expand Down Expand Up @@ -91,7 +99,7 @@ public IEnumerator PingPongSimultaneous([ValueSource("k_DeliveryParameters")] Ne
m_Server.StartServer();
m_Client1.StartClient();

yield return WaitForNetworkEvent(NetworkEvent.Connect, m_ServerEvents);
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);

var ping = new ArraySegment<byte>(Encoding.ASCII.GetBytes("ping"));
m_Server.Send(m_ServerEvents[0].ClientID, ping, delivery);
Expand Down Expand Up @@ -128,7 +136,7 @@ public IEnumerator SendMaximumPayloadSize([ValueSource("k_DeliveryParameters")]
m_Server.StartServer();
m_Client1.StartClient();

yield return WaitForNetworkEvent(NetworkEvent.Connect, m_ServerEvents);
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);

var payloadData = new byte[payloadSize];
for (int i = 0; i < payloadData.Length; i++)
Expand All @@ -139,7 +147,7 @@ public IEnumerator SendMaximumPayloadSize([ValueSource("k_DeliveryParameters")]
var payload = new ArraySegment<byte>(payloadData);
m_Client1.Send(m_Client1.ServerClientId, payload, delivery);

yield return WaitForNetworkEvent(NetworkEvent.Data, m_ServerEvents);
yield return WaitForNetworkEvent(NetworkEvent.Data, m_ServerEvents, MaxNetworkEventWaitTime * 2);

Assert.AreEqual(payloadSize, m_ServerEvents[1].Data.Count);

Expand All @@ -162,7 +170,7 @@ public IEnumerator FilledSendQueueMultipleSends([ValueSource("k_DeliveryParamete
m_Server.StartServer();
m_Client1.StartClient();

yield return WaitForNetworkEvent(NetworkEvent.Connect, m_ServerEvents);
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);

var numSends = UnityTransport.InitialMaxSendQueueSize / 1024;

Expand All @@ -180,7 +188,7 @@ public IEnumerator FilledSendQueueMultipleSends([ValueSource("k_DeliveryParamete
yield return new WaitForSeconds(numSends * 0.02f);

// Extra event is the connect event.
Assert.AreEqual(m_ServerEvents.Count, numSends + 1);
Assert.AreEqual(numSends + 1, m_ServerEvents.Count);

for (int i = 1; i <= numSends; i++)
{
Expand All @@ -201,7 +209,7 @@ public IEnumerator MultipleSendsSingleFrame([ValueSource("k_DeliveryParameters")
m_Server.StartServer();
m_Client1.StartClient();

yield return WaitForNetworkEvent(NetworkEvent.Connect, m_ServerEvents);
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);

var data1 = new ArraySegment<byte>(new byte[] { 11 });
m_Client1.Send(m_Client1.ServerClientId, data1, delivery);
Expand Down Expand Up @@ -232,7 +240,11 @@ public IEnumerator SendMultipleClients([ValueSource("k_DeliveryParameters")] Net
m_Client1.StartClient();
m_Client2.StartClient();

yield return WaitForNetworkEvent(NetworkEvent.Connect, m_ServerEvents);
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);
if (m_Client2Events.Count == 0)
{
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client2Events);
}

// Ensure we got both Connect events.
Assert.AreEqual(2, m_ServerEvents.Count);
Expand All @@ -252,7 +264,7 @@ public IEnumerator SendMultipleClients([ValueSource("k_DeliveryParameters")] Net

byte c1Data = m_Client1Events[1].Data.First();
byte c2Data = m_Client2Events[1].Data.First();
Assert.True((c1Data == 11 && c2Data == 22) || (c1Data == 22 && c2Data == 11));
Assert.That((c1Data == 11 && c2Data == 22) || (c1Data == 22 && c2Data == 11));

yield return null;
}
Expand All @@ -270,9 +282,10 @@ public IEnumerator ReceiveMultipleClients([ValueSource("k_DeliveryParameters")]
m_Client2.StartClient();

yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);

// Ensure we got the Connect event on the other client too.
Assert.AreEqual(1, m_Client2Events.Count);
if (m_Client2Events.Count == 0)
{
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client2Events);
}

var data1 = new ArraySegment<byte>(new byte[] { 11 });
m_Client1.Send(m_Client1.ServerClientId, data1, delivery);
Expand All @@ -288,9 +301,10 @@ public IEnumerator ReceiveMultipleClients([ValueSource("k_DeliveryParameters")]

byte sData1 = m_ServerEvents[2].Data.First();
byte sData2 = m_ServerEvents[3].Data.First();
Assert.True((sData1 == 11 && sData2 == 22) || (sData1 == 22 && sData2 == 11));
Assert.That((sData1 == 11 && sData2 == 22) || (sData1 == 22 && sData2 == 11));

yield return null;
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void Serialize(FastBufferWriter writer)
// This var does not belong to the currently iterating delivery group.
if (NetworkBehaviour.NetworkManager.NetworkConfig.EnsureNetworkVariableLengthSafety)
{
writer.WriteValueSafe((short)0);
writer.WriteValueSafe((ushort)0);
}
else
{
Expand Down Expand Up @@ -69,7 +69,12 @@ public void Serialize(FastBufferWriter writer)
var tmpWriter = new FastBufferWriter(MessagingSystem.NON_FRAGMENTED_MESSAGE_MAX_SIZE, Allocator.Temp, short.MaxValue);
NetworkBehaviour.NetworkVariableFields[k].WriteDelta(tmpWriter);

writer.WriteValueSafe((ushort)tmpWriter.Length);
if (!writer.TryBeginWrite(FastBufferWriter.GetWriteSize<ushort>() + tmpWriter.Length))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this does not fix the issue with NetworkLists that exceed the MessagingSystem.NON_FRAGMENTED_MESSAGE_MAX_SIZE, I put this in place as it was missed in the back port.
This will not actually fix the issue until MTT-2434 is resolved but should handle this particular issue within NetworkVariableDeltaMessage.

{
throw new OverflowException($"Not enough space in the buffer to write {nameof(NetworkVariableDeltaMessage)}");
}

writer.WriteValue((ushort)tmpWriter.Length);
tmpWriter.CopyTo(writer);
}
else
Expand Down
Loading