Files
RobustToolbox/Robust.Shared.IntegrationTests/GameState/AutoNetworkingTest.cs
PJB3005 788e9386fd Split up test project
Robust.UnitTesting was both ALL tests for RT, and also API surface for content tests.

Tests are now split into separate projects as appropriate, and the API side has also been split off.
2025-12-16 01:36:53 +01:00

223 lines
8.7 KiB
C#

using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Shared;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Robust.UnitTesting.Shared.GameState;
internal sealed partial class AutoNetworkingTests : RobustIntegrationTest
{
/// <summary>
/// Does basic testing for AutoNetworkedFieldAttribute and AutoGenerateComponentStateAttribute
/// to make sure the datafields are correctly networked to the client when dirtied.
/// TODO: Add test for field deltas.
/// </summary>
[Test]
public async Task AutoNetworkingTest()
{
var serverOpts = new ServerIntegrationOptions { Pool = false };
var clientOpts = new ClientIntegrationOptions { Pool = false };
using var server = StartServer(serverOpts);
using var client = StartClient(clientOpts);
await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync());
var netMan = client.ResolveDependency<IClientNetManager>();
Assert.DoesNotThrow(() => client.SetConnectTarget(server));
client.Post(() => netMan.ClientConnect(null!, 0, null!));
server.Post(() => server.CfgMan.SetCVar(CVars.NetPVS, true));
// Set up map.
EntityUid map = default;
server.Post(() =>
{
map = server.System<SharedMapSystem>().CreateMap();
});
await RunTicks();
// Spawn entities
var coords = new EntityCoordinates(map, default);
EntityUid player = default;
EntityUid cPlayer = default;
EntityUid serverEnt1 = default;
EntityUid serverEnt2 = default;
EntityUid serverEnt3 = default;
NetEntity serverNet1 = default;
NetEntity serverNet2 = default;
NetEntity serverNet3 = default;
await server.WaitPost(() =>
{
// Attach player.
player = server.EntMan.SpawnAttachedTo(null, coords);
var session = server.PlayerMan.Sessions.First();
server.PlayerMan.SetAttachedEntity(session, player);
server.PlayerMan.JoinGame(session);
// Spawn test entities.
serverEnt1 = server.EntMan.SpawnAttachedTo(null, coords);
serverEnt2 = server.EntMan.SpawnAttachedTo(null, coords);
serverEnt3 = server.EntMan.SpawnAttachedTo(null, coords);
serverNet1 = server.EntMan.GetNetEntity(serverEnt1);
serverNet2 = server.EntMan.GetNetEntity(serverEnt2);
serverNet3 = server.EntMan.GetNetEntity(serverEnt3);
// Setup components
server.EntMan.EnsureComponent<AutoNetworkingTestComponent>(serverEnt1);
server.EntMan.EnsureComponent<AutoNetworkingTestChildComponent>(serverEnt2);
server.EntMan.EnsureComponent<AutoNetworkingTestEmptyChildComponent>(serverEnt3);
});
await RunTicks();
// check client
await client.WaitPost(() =>
{
// Get the client-side entities
cPlayer = client.EntMan.GetEntity(server.EntMan.GetNetEntity(player));
var clientEnt1 = client.EntMan.GetEntity(serverNet1);
var clientEnt2 = client.EntMan.GetEntity(serverNet2);
var clientEnt3 = client.EntMan.GetEntity(serverNet3);
// Check player got properly attached
Assert.That(client.AttachedEntity, Is.EqualTo(cPlayer));
Assert.That(client.EntMan.EntityExists(cPlayer));
// Get the client-side components
Assert.That(client.EntMan.TryGetComponent(clientEnt1, out AutoNetworkingTestComponent? cmpClient1));
Assert.That(client.EntMan.TryGetComponent(clientEnt2, out AutoNetworkingTestChildComponent? cmpClient2));
Assert.That(client.EntMan.TryGetComponent(clientEnt3, out AutoNetworkingTestEmptyChildComponent? cmpClient3));
// All datafields should be the default value
Assert.That(cmpClient1?.IsNetworked, Is.EqualTo(1));
Assert.That(cmpClient1?.NotNetworked, Is.EqualTo(2));
Assert.That(cmpClient2?.ChildNetworked, Is.EqualTo(1));
Assert.That(cmpClient2?.Child, Is.EqualTo(2));
Assert.That(cmpClient2?.ParentNetworked, Is.EqualTo(3));
Assert.That(cmpClient2?.Parent, Is.EqualTo(4));
Assert.That(cmpClient3?.ParentNetworked, Is.EqualTo(3));
Assert.That(cmpClient3?.Parent, Is.EqualTo(4));
});
// make changes on the server
await server.WaitPost(() =>
{
// Get the server-side components
var cmpServer1 = server.EntMan.GetComponent<AutoNetworkingTestComponent>(serverEnt1);
var cmpServer2 = server.EntMan.GetComponent<AutoNetworkingTestChildComponent>(serverEnt2);
var cmpServer3 = server.EntMan.GetComponent<AutoNetworkingTestEmptyChildComponent>(serverEnt3);
// All datafields should be the default value
Assert.That(cmpServer1.IsNetworked, Is.EqualTo(1));
Assert.That(cmpServer1.NotNetworked, Is.EqualTo(2));
Assert.That(cmpServer2.ChildNetworked, Is.EqualTo(1));
Assert.That(cmpServer2.Child, Is.EqualTo(2));
Assert.That(cmpServer2.ParentNetworked, Is.EqualTo(3));
Assert.That(cmpServer2.Parent, Is.EqualTo(4));
Assert.That(cmpServer3.ParentNetworked, Is.EqualTo(3));
Assert.That(cmpServer3.Parent, Is.EqualTo(4));
// change the datafields and dirty them
cmpServer1.IsNetworked = 101;
cmpServer1.NotNetworked = 102;
cmpServer2.ChildNetworked = 101;
cmpServer2.Child = 102;
cmpServer2.ParentNetworked = 103;
cmpServer2.Parent = 104;
cmpServer3.ParentNetworked = 103;
cmpServer3.Parent = 104;
server.EntMan.Dirty(serverEnt1, cmpServer1);
server.EntMan.Dirty(serverEnt2, cmpServer2);
server.EntMan.Dirty(serverEnt3, cmpServer3);
});
await RunTicks();
// check the client again
await client.WaitPost(() =>
{
// Get the client-side entities
cPlayer = client.EntMan.GetEntity(server.EntMan.GetNetEntity(player));
var clientEnt1 = client.EntMan.GetEntity(serverNet1);
var clientEnt2 = client.EntMan.GetEntity(serverNet2);
var clientEnt3 = client.EntMan.GetEntity(serverNet3);
// Get the client-side components
Assert.That(client.EntMan.TryGetComponent(clientEnt1, out AutoNetworkingTestComponent? cmpClient1));
Assert.That(client.EntMan.TryGetComponent(clientEnt2, out AutoNetworkingTestChildComponent? cmpClient2));
Assert.That(client.EntMan.TryGetComponent(clientEnt3, out AutoNetworkingTestEmptyChildComponent? cmpClient3));
// All datafields should be the default value
Assert.That(cmpClient1?.IsNetworked, Is.EqualTo(101));
Assert.That(cmpClient1?.NotNetworked, Is.EqualTo(2)); // unchanged
Assert.That(cmpClient2?.ChildNetworked, Is.EqualTo(101));
Assert.That(cmpClient2?.Child, Is.EqualTo(2)); // unchanged
Assert.That(cmpClient2?.ParentNetworked, Is.EqualTo(103));
Assert.That(cmpClient2?.Parent, Is.EqualTo(4)); // unchanged
Assert.That(cmpClient3?.ParentNetworked, Is.EqualTo(103));
Assert.That(cmpClient3?.Parent, Is.EqualTo(4)); // unchanged
});
async Task RunTicks()
{
for (int i = 0; i < 10; i++)
{
await server!.WaitRunTicks(1);
await client!.WaitRunTicks(1);
}
}
await client.WaitPost(() => netMan.ClientDisconnect(""));
await server.WaitRunTicks(5);
await client.WaitRunTicks(5);
}
}
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class AutoNetworkingTestComponent : Component
{
[DataField, AutoNetworkedField]
public int IsNetworked = 1;
[DataField]
public int NotNetworked = 2;
}
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class AutoNetworkingTestChildComponent : AutoNetworkingTestParentComponent
{
[DataField, AutoNetworkedField]
public int ChildNetworked = 1;
[DataField]
public int Child = 2;
}
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class AutoNetworkingTestEmptyChildComponent : AutoNetworkingTestParentComponent
{
}
public abstract partial class AutoNetworkingTestParentComponent : Component
{
[DataField, AutoNetworkedField]
public int ParentNetworked = 3;
[DataField]
public int Parent = 4;
}