This repository has been archived on 2025-04-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
com.unity.netcode.gameobjects/Tests/Editor/Transports/BatchedSendQueueTests.cs
Unity Technologies ffef45b50f com.unity.netcode.gameobjects@1.7.0
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com).

## [1.7.0] - 2023-10-11

### Added

- exposed NetworkObject.GetNetworkBehaviourAtOrderIndex as a public API (#2724)
- Added context menu tool that provides users with the ability to quickly update the GlobalObjectIdHash value for all in-scene placed prefab instances that were created prior to adding a NetworkObject component to it. (#2707)
- Added methods NetworkManager.SetPeerMTU and NetworkManager.GetPeerMTU to be able to set MTU sizes per-peer (#2676)
- Added `GenerateSerializationForGenericParameterAttribute`, which can be applied to user-created Network Variable types to ensure the codegen generates serialization for the generic types they wrap. (#2694)
- Added `GenerateSerializationForTypeAttribute`, which can be applied to any class or method to ensure the codegen generates serialization for the specific provided type. (#2694)
- Exposed `NetworkVariableSerialization<T>.Read`, `NetworkVariableSerialization<T>.Write`, `NetworkVariableSerialization<T>.AreEqual`, and `NetworkVariableSerialization<T>.Duplicate` to further support the creation of user-created network variables by allowing users to access the generated serialization methods and serialize generic types efficiently without boxing. (#2694)
- Added `NetworkVariableBase.MarkNetworkBehaviourDirty` so that user-created network variable types can mark their containing `NetworkBehaviour` to be processed by the update loop. (#2694)

### Fixed

- Fixed issue where the server side `NetworkSceneManager` instance was not adding the currently active scene to its list of scenes loaded. (#2723)
- Generic NetworkBehaviour types no longer result in compile errors or runtime errors (#2720)
- Rpcs within Generic NetworkBehaviour types can now serialize parameters of the class's generic types (but may not have generic types of their own) (#2720)
- Errors are no longer thrown when entering play mode with domain reload disabled (#2720)
- NetworkSpawn is now correctly called each time when entering play mode with scene reload disabled (#2720)
- NetworkVariables of non-integer types will no longer break the inspector (#2714)
- NetworkVariables with NonSerializedAttribute will not appear in the inspector (#2714)
- Fixed issue where `UnityTransport` would attempt to establish WebSocket connections even if using UDP/DTLS Relay allocations when the build target was WebGL. This only applied to working in the editor since UDP/DTLS can't work in the browser. (#2695)
- Fixed issue where a `NetworkBehaviour` component's `OnNetworkDespawn` was not being invoked on the host-server side for an in-scene placed `NetworkObject` when a scene was unloaded (during a scene transition) and the `NetworkBehaviour` component was positioned/ordered before the `NetworkObject` component. (#2685)
- Fixed issue where `SpawnWithObservers` was not being honored when `NetworkConfig.EnableSceneManagement` was disabled. (#2682)
- Fixed issue where `NetworkAnimator` was not internally tracking changes to layer weights which prevented proper layer weight synchronization back to the original layer weight value. (#2674)
- Fixed "writing past the end of the buffer" error when calling ResetDirty() on managed network variables that are larger than 256 bytes when serialized. (#2670)
- Fixed issue where generation of the `DefaultNetworkPrefabs` asset was not enabled by default. (#2662)
- Fixed issue where the `GlobalObjectIdHash` value could be updated but the asset not marked as dirty. (#2662)
- Fixed issue where the `GlobalObjectIdHash` value of a (network) prefab asset could be assigned an incorrect value when editing the prefab in a temporary scene. (#2662)
- Fixed issue where the `GlobalObjectIdHash` value generated after creating a (network) prefab from an object constructed within the scene would not be the correct final value in a stand alone build. (#2662)

### Changed

- Updated dependency on `com.unity.transport` to version 1.4.0. (#2716)
2023-10-11 00:00:00 +00:00

366 lines
13 KiB
C#

using System;
using NUnit.Framework;
using Unity.Collections;
using Unity.Netcode.Transports.UTP;
using Unity.Networking.Transport;
namespace Unity.Netcode.EditorTests
{
public class BatchedSendQueueTests
{
private const int k_TestQueueCapacity = 16 * 1024;
private const int k_TestMessageSize = 1020;
private const int k_NumMessagesToFillQueue = k_TestQueueCapacity / (k_TestMessageSize + BatchedSendQueue.PerMessageOverhead);
private ArraySegment<byte> m_TestMessage;
private void AssertIsTestMessage(NativeArray<byte> data)
{
var reader = new DataStreamReader(data);
Assert.AreEqual(k_TestMessageSize, reader.ReadInt());
for (int i = 0; i < k_TestMessageSize; i++)
{
Assert.AreEqual(m_TestMessage.Array[i], reader.ReadByte());
}
}
[OneTimeSetUp]
public void InitializeTestMessage()
{
var data = new byte[k_TestMessageSize];
for (int i = 0; i < k_TestMessageSize; i++)
{
data[i] = (byte)i;
}
m_TestMessage = new ArraySegment<byte>(data);
}
[Test]
public void BatchedSendQueue_EmptyOnCreation()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
Assert.AreEqual(0, q.Length);
Assert.True(q.IsEmpty);
}
[Test]
public void BatchedSendQueue_NotCreatedAfterDispose()
{
var q = new BatchedSendQueue(k_TestQueueCapacity);
q.Dispose();
Assert.False(q.IsCreated);
}
[Test]
public void BatchedSendQueue_InitialCapacityLessThanMaximum()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
Assert.AreEqual(q.Capacity, BatchedSendQueue.MinimumMinimumCapacity);
}
[Test]
public void BatchedSendQueue_PushMessage_ReturnValue()
{
// Will fit a single test message, but not two (with overhead included).
var queueCapacity = (k_TestMessageSize * 2) + BatchedSendQueue.PerMessageOverhead;
using var q = new BatchedSendQueue(queueCapacity);
Assert.True(q.PushMessage(m_TestMessage));
Assert.False(q.PushMessage(m_TestMessage));
}
[Test]
public void BatchedSendQueue_PushMessage_IncreasesLength()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
q.PushMessage(m_TestMessage);
Assert.AreEqual(k_TestMessageSize + BatchedSendQueue.PerMessageOverhead, q.Length);
}
[Test]
public void BatchedSendQueue_PushMessage_SucceedsAfterConsume()
{
var messageLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
var queueCapacity = messageLength * 2;
using var q = new BatchedSendQueue(queueCapacity);
q.PushMessage(m_TestMessage);
q.PushMessage(m_TestMessage);
q.Consume(messageLength);
Assert.IsTrue(q.PushMessage(m_TestMessage));
Assert.AreEqual(queueCapacity, q.Length);
}
[Test]
public void BatchedSendQueue_PushMessage_GrowsDataIfNeeded()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
var messageLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
Assert.AreEqual(q.Capacity, BatchedSendQueue.MinimumMinimumCapacity);
var numMessagesToFillMinimum = BatchedSendQueue.MinimumMinimumCapacity / messageLength;
for (int i = 0; i < numMessagesToFillMinimum; i++)
{
q.PushMessage(m_TestMessage);
}
Assert.AreEqual(q.Capacity, BatchedSendQueue.MinimumMinimumCapacity);
q.PushMessage(m_TestMessage);
Assert.AreEqual(q.Capacity, BatchedSendQueue.MinimumMinimumCapacity * 2);
}
[Test]
public void BatchedSendQueue_PushMessage_DoesNotGrowDataPastMaximum()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
for (int i = 0; i < k_NumMessagesToFillQueue; i++)
{
Assert.IsTrue(q.PushMessage(m_TestMessage));
}
Assert.AreEqual(q.Capacity, k_TestQueueCapacity);
Assert.IsFalse(q.PushMessage(m_TestMessage));
Assert.AreEqual(q.Capacity, k_TestQueueCapacity);
}
[Test]
public void BatchedSendQueue_PushMessage_TrimsDataAfterGrowing()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
var messageLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
for (int i = 0; i < k_NumMessagesToFillQueue; i++)
{
Assert.IsTrue(q.PushMessage(m_TestMessage));
}
Assert.AreEqual(q.Capacity, k_TestQueueCapacity);
q.Consume(messageLength * (k_NumMessagesToFillQueue - 1));
Assert.IsTrue(q.PushMessage(m_TestMessage));
Assert.AreEqual(messageLength * 2, q.Length);
Assert.AreEqual(q.Capacity, BatchedSendQueue.MinimumMinimumCapacity * 2);
}
[Test]
public void BatchedSendQueue_FillWriterWithMessages_ReturnValue()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(k_TestQueueCapacity, Allocator.Temp);
q.PushMessage(m_TestMessage);
var writer = new DataStreamWriter(data);
var filled = q.FillWriterWithMessages(ref writer);
Assert.AreEqual(k_TestMessageSize + BatchedSendQueue.PerMessageOverhead, filled);
}
[Test]
public void BatchedSendQueue_FillWriterWithMessages_NoopIfNoPushedMessages()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(k_TestQueueCapacity, Allocator.Temp);
var writer = new DataStreamWriter(data);
Assert.AreEqual(0, q.FillWriterWithMessages(ref writer));
}
[Test]
public void BatchedSendQueue_FillWriterWithMessages_NoopIfNotEnoughCapacity()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(2, Allocator.Temp);
q.PushMessage(m_TestMessage);
var writer = new DataStreamWriter(data);
Assert.AreEqual(0, q.FillWriterWithMessages(ref writer));
}
[Test]
public void BatchedSendQueue_FillWriterWithMessages_SinglePushedMessage()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(k_TestQueueCapacity, Allocator.Temp);
q.PushMessage(m_TestMessage);
var writer = new DataStreamWriter(data);
q.FillWriterWithMessages(ref writer);
AssertIsTestMessage(data);
}
[Test]
public void BatchedSendQueue_FillWriterWithMessages_MultiplePushedMessages()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(k_TestQueueCapacity, Allocator.Temp);
q.PushMessage(m_TestMessage);
q.PushMessage(m_TestMessage);
var writer = new DataStreamWriter(data);
q.FillWriterWithMessages(ref writer);
var messageLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
AssertIsTestMessage(data);
AssertIsTestMessage(data.GetSubArray(messageLength, messageLength));
}
[Test]
public void BatchedSendQueue_FillWriterWithMessages_PartialPushedMessages()
{
var messageLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(messageLength, Allocator.Temp);
q.PushMessage(m_TestMessage);
q.PushMessage(m_TestMessage);
var writer = new DataStreamWriter(data);
Assert.AreEqual(messageLength, q.FillWriterWithMessages(ref writer));
AssertIsTestMessage(data);
q.Consume(messageLength);
writer = new DataStreamWriter(data);
Assert.AreEqual(messageLength, q.FillWriterWithMessages(ref writer));
AssertIsTestMessage(data);
}
[Test]
public void BatchedSendQueue_FillWriterWithBytes_NoopIfNoData()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(k_TestQueueCapacity, Allocator.Temp);
var writer = new DataStreamWriter(data);
Assert.AreEqual(0, q.FillWriterWithBytes(ref writer));
}
[Test]
public void BatchedSendQueue_FillWriterWithBytes_WriterCapacityMoreThanLength()
{
var dataLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(k_TestQueueCapacity, Allocator.Temp);
q.PushMessage(m_TestMessage);
var writer = new DataStreamWriter(data);
Assert.AreEqual(dataLength, q.FillWriterWithBytes(ref writer));
AssertIsTestMessage(data);
}
[Test]
public void BatchedSendQueue_FillWriterWithBytes_WriterCapacityLessThanLength()
{
var dataLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(dataLength, Allocator.Temp);
q.PushMessage(m_TestMessage);
q.PushMessage(m_TestMessage);
var writer = new DataStreamWriter(data);
Assert.AreEqual(dataLength, q.FillWriterWithBytes(ref writer));
AssertIsTestMessage(data);
}
[Test]
public void BatchedSendQueue_FillWriterWithBytes_WriterCapacityEqualToLength()
{
var dataLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(dataLength, Allocator.Temp);
q.PushMessage(m_TestMessage);
var writer = new DataStreamWriter(data);
Assert.AreEqual(dataLength, q.FillWriterWithBytes(ref writer));
AssertIsTestMessage(data);
}
[Test]
public void BatchedSendQueue_FillWriterWithBytes_MaxBytesGreaterThanCapacity()
{
var dataLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
using var q = new BatchedSendQueue(k_TestQueueCapacity);
using var data = new NativeArray<byte>(dataLength, Allocator.Temp);
q.PushMessage(m_TestMessage);
q.PushMessage(m_TestMessage);
var writer = new DataStreamWriter(data);
Assert.AreEqual(dataLength, q.FillWriterWithBytes(ref writer, dataLength * 2));
AssertIsTestMessage(data);
Assert.False(writer.HasFailedWrites);
}
[Test]
public void BatchedSendQueue_Consume_LessThanLength()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
q.PushMessage(m_TestMessage);
q.PushMessage(m_TestMessage);
var messageLength = k_TestMessageSize + BatchedSendQueue.PerMessageOverhead;
q.Consume(messageLength);
Assert.AreEqual(messageLength, q.Length);
}
[Test]
public void BatchedSendQueue_Consume_ExactLength()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
q.PushMessage(m_TestMessage);
q.Consume(k_TestMessageSize + BatchedSendQueue.PerMessageOverhead);
Assert.AreEqual(0, q.Length);
Assert.True(q.IsEmpty);
}
[Test]
public void BatchedSendQueue_Consume_MoreThanLength()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
q.PushMessage(m_TestMessage);
q.Consume(k_TestQueueCapacity);
Assert.AreEqual(0, q.Length);
Assert.True(q.IsEmpty);
}
[Test]
public void BatchedSendQueue_Consume_TrimsDataOnEmpty()
{
using var q = new BatchedSendQueue(k_TestQueueCapacity);
for (int i = 0; i < k_NumMessagesToFillQueue; i++)
{
q.PushMessage(m_TestMessage);
}
Assert.AreEqual(q.Capacity, k_TestQueueCapacity);
q.Consume(k_TestQueueCapacity);
Assert.AreEqual(q.Capacity, BatchedSendQueue.MinimumMinimumCapacity);
}
}
}