mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
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.
223 lines
8.7 KiB
C#
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;
|
|
}
|