Skip to content

Commit

Permalink
Add some tests and fix some miscellaneous bugs (#22836)
Browse files Browse the repository at this point in the history
* Add some tests and fix some bugs

* Add more helper methods

* remove submodule

* fix merge

* also fix DirtyAll()

* poke
  • Loading branch information
ElectroJr authored Dec 27, 2023
1 parent 44adc32 commit 35ba42a
Show file tree
Hide file tree
Showing 14 changed files with 292 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -773,9 +773,10 @@ private void AssignSlots(List<SlotAssignment> assignments)
if (_actionsSystem == null)
return;

for (var i = 0; i < assignments.Count; i++)
_actions.Clear();
foreach (var assign in assignments)
{
_actions[i] = assignments[i].ActionId;
_actions.Add(assign.ActionId);
}

_container?.SetActionData(_actionsSystem, _actions.ToArray());
Expand Down
10 changes: 10 additions & 0 deletions Content.IntegrationTests/Pair/TestPair.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ public sealed partial class TestPair
public RobustIntegrationTest.ServerIntegrationInstance Server { get; private set; } = default!;
public RobustIntegrationTest.ClientIntegrationInstance Client { get; private set; } = default!;

public void Deconstruct(
out RobustIntegrationTest.ServerIntegrationInstance server,
out RobustIntegrationTest.ClientIntegrationInstance client)
{
server = Server;
client = Client;
}

public ICommonSession? Player => Server.PlayerMan.Sessions.FirstOrDefault();
public ContentPlayerData? PlayerData => Player?.Data.ContentData();

Expand Down Expand Up @@ -78,6 +86,8 @@ await Client.WaitPost(() =>
public void Kill()
{
State = PairState.Dead;
ServerLogHandler.ShuttingDown = true;
ClientLogHandler.ShuttingDown = true;
Server.Dispose();
Client.Dispose();
}
Expand Down
8 changes: 7 additions & 1 deletion Content.IntegrationTests/PoolTestLogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,22 @@ public PoolTestLogHandler(string? prefix)
_prefix = prefix != null ? $"{prefix}: " : "";
}

public bool ShuttingDown;

public void Log(string sawmillName, LogEvent message)
{
var level = message.Level.ToRobust();

if (ShuttingDown && (FailureLevel == null || level < FailureLevel))
return;

if (ActiveContext is not { } testContext)
{
// If this gets hit it means something is logging to this instance while it's "between" tests.
// This is a bug in either the game or the testing system, and must always be investigated.
throw new InvalidOperationException("Log to pool test log handler without active test context");
}

var level = message.Level.ToRobust();
var name = LogMessage.LogLevelToName(level);
var seconds = _stopwatch.Elapsed.TotalSeconds;
var rendered = message.RenderMessage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ public async Task CancelWallDeconstruct()
AssertAnchored(false);

// Repeat for screwdriver interaction.
AssertDeleted(false);
AssertExists();
await Interact(Screw, awaitDoAfters: false);
await CancelDoAfters();
AssertDeleted(false);
AssertExists();
await Interact(Screw);
AssertDeleted();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ await Server.WaitPost(() =>
/// <remarks>
/// Automatically enables welders.
/// </remarks>
protected async Task<EntityUid?> PlaceInHands(string? id, int quantity = 1, bool enableWelder = true)
protected async Task<NetEntity> PlaceInHands(string id, int quantity = 1, bool enableWelder = true)
{
return await PlaceInHands(id == null ? null : (id, quantity), enableWelder);
return await PlaceInHands((id, quantity), enableWelder);
}

/// <summary>
Expand All @@ -145,23 +145,17 @@ await Server.WaitPost(() =>
/// <remarks>
/// Automatically enables welders.
/// </remarks>
protected async Task<EntityUid?> PlaceInHands(EntitySpecifier? entity, bool enableWelder = true)
protected async Task<NetEntity> PlaceInHands(EntitySpecifier entity, bool enableWelder = true)
{
if (Hands.ActiveHand == null)
{
Assert.Fail("No active hand");
return default;
}

Assert.That(!string.IsNullOrWhiteSpace(entity.Prototype));
await DeleteHeldEntity();

if (entity == null || string.IsNullOrWhiteSpace(entity.Prototype))
{
await RunTicks(1);
Assert.That(Hands.ActiveHandEntity, Is.Null);
return null;
}

// spawn and pick up the new item
var item = await SpawnEntity(entity, SEntMan.GetCoordinates(PlayerCoords));
ItemToggleComponent? itemToggle = null;
Expand All @@ -184,7 +178,7 @@ await Server.WaitPost(() =>
if (enableWelder && itemToggle != null)
Assert.That(itemToggle.Activated);

return item;
return SEntMan.GetNetEntity(item);
}

/// <summary>
Expand Down Expand Up @@ -330,6 +324,17 @@ protected async Task Interact(params EntitySpecifier[] specifiers)
}
}

/// <summary>
/// Throw the currently held entity. Defaults to targeting the current <see cref="TargetCoords"/>
/// </summary>
protected async Task<bool> ThrowItem(NetCoordinates? target = null, float minDistance = 4)
{
var actualTarget = SEntMan.GetCoordinates(target ?? TargetCoords);
var result = false;
await Server.WaitPost(() => result = HandSys.ThrowHeldItem(SEntMan.GetEntity(Player), actualTarget, minDistance));
return result;
}

#endregion

/// <summary>
Expand Down Expand Up @@ -483,7 +488,7 @@ protected void AssertAnchored(bool anchored = true, NetEntity? target = null)
});
}

protected void AssertDeleted(bool deleted = true, NetEntity? target = null)
protected void AssertDeleted(NetEntity? target = null)
{
target ??= Target;
if (target == null)
Expand All @@ -494,8 +499,24 @@ protected void AssertDeleted(bool deleted = true, NetEntity? target = null)

Assert.Multiple(() =>
{
Assert.That(SEntMan.Deleted(SEntMan.GetEntity(target)), Is.EqualTo(deleted));
Assert.That(CEntMan.Deleted(CEntMan.GetEntity(target)), Is.EqualTo(deleted));
Assert.That(SEntMan.Deleted(SEntMan.GetEntity(target)));
Assert.That(CEntMan.Deleted(CEntMan.GetEntity(target)));
});
}

protected void AssertExists(NetEntity? target = null)
{
target ??= Target;
if (target == null)
{
Assert.Fail("No target specified");
return;
}

Assert.Multiple(() =>
{
Assert.That(SEntMan.EntityExists(SEntMan.GetEntity(target)));
Assert.That(CEntMan.EntityExists(CEntMan.GetEntity(target)));
});
}

Expand Down Expand Up @@ -733,6 +754,11 @@ protected async Task Delete(EntityUid uid)
await RunTicks(5);
}

protected Task Delete(NetEntity nuid)
{
return Delete(SEntMan.GetEntity(nuid));
}

#region Time/Tick managment

protected async Task RunTicks(int ticks)
Expand Down Expand Up @@ -1064,4 +1090,35 @@ protected async Task Move(DirectionFlag dir, float seconds)
}

#endregion

#region Networking

protected EntityUid ToServer(NetEntity nent) => SEntMan.GetEntity(nent);
protected EntityUid ToClient(NetEntity nent) => CEntMan.GetEntity(nent);
protected EntityUid? ToServer(NetEntity? nent) => SEntMan.GetEntity(nent);
protected EntityUid? ToClient(NetEntity? nent) => CEntMan.GetEntity(nent);
protected EntityUid ToServer(EntityUid cuid) => SEntMan.GetEntity(CEntMan.GetNetEntity(cuid));
protected EntityUid ToClient(EntityUid cuid) => CEntMan.GetEntity(SEntMan.GetNetEntity(cuid));
protected EntityUid? ToServer(EntityUid? cuid) => SEntMan.GetEntity(CEntMan.GetNetEntity(cuid));
protected EntityUid? ToClient(EntityUid? cuid) => CEntMan.GetEntity(SEntMan.GetNetEntity(cuid));

protected EntityCoordinates ToServer(NetCoordinates coords) => SEntMan.GetCoordinates(coords);
protected EntityCoordinates ToClient(NetCoordinates coords) => CEntMan.GetCoordinates(coords);
protected EntityCoordinates? ToServer(NetCoordinates? coords) => SEntMan.GetCoordinates(coords);
protected EntityCoordinates? ToClient(NetCoordinates? coords) => CEntMan.GetCoordinates(coords);

#endregion

#region Metadata & Transforms

protected MetaDataComponent Meta(NetEntity uid) => Meta(ToServer(uid));
protected MetaDataComponent Meta(EntityUid uid) => SEntMan.GetComponent<MetaDataComponent>(uid);

protected TransformComponent Xform(NetEntity uid) => Xform(ToServer(uid));
protected TransformComponent Xform(EntityUid uid) => SEntMan.GetComponent<TransformComponent>(uid);

protected EntityCoordinates Position(NetEntity uid) => Position(ToServer(uid));
protected EntityCoordinates Position(EntityUid uid) => Xform(uid).Coordinates;

#endregion
}
12 changes: 9 additions & 3 deletions Content.IntegrationTests/Tests/Interaction/InteractionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
using Content.Client.Examine;
using Content.IntegrationTests.Pair;
using Content.Server.Body.Systems;
using Content.Server.Hands.Systems;
using Content.Server.Stack;
using Content.Server.Tools;
using Content.Shared.Body.Part;
using Content.Shared.DoAfter;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Server.Item;
using Content.Shared.Mind;
Expand Down Expand Up @@ -66,6 +66,9 @@ public abstract partial class InteractionTest
/// </summary>
protected NetEntity Player;

protected EntityUid SPlayer => ToServer(Player);
protected EntityUid CPlayer => ToClient(Player);

protected ICommonSession ClientSession = default!;
protected ICommonSession ServerSession = default!;

Expand All @@ -81,6 +84,9 @@ public abstract partial class InteractionTest
/// </remarks>
protected NetEntity? Target;

protected EntityUid? STarget => ToServer(Target);
protected EntityUid? CTarget => ToClient(Target);

/// <summary>
/// When attempting to start construction, this is the client-side ID of the construction ghost.
/// </summary>
Expand All @@ -93,7 +99,7 @@ public abstract partial class InteractionTest
protected IPrototypeManager ProtoMan = default!;
protected IGameTiming STiming = default!;
protected IComponentFactory Factory = default!;
protected SharedHandsSystem HandSys = default!;
protected HandsSystem HandSys = default!;
protected StackSystem Stack = default!;
protected SharedInteractionSystem InteractSys = default!;
protected Content.Server.Construction.ConstructionSystem SConstruction = default!;
Expand Down Expand Up @@ -152,7 +158,7 @@ public virtual async Task Setup()
ProtoMan = Server.ResolveDependency<IPrototypeManager>();
Factory = Server.ResolveDependency<IComponentFactory>();
STiming = Server.ResolveDependency<IGameTiming>();
HandSys = SEntMan.System<SharedHandsSystem>();
HandSys = SEntMan.System<HandsSystem>();
InteractSys = SEntMan.System<SharedInteractionSystem>();
ToolSys = SEntMan.System<ToolSystem>();
ItemToggleSys = SEntMan.System<SharedItemToggleSystem>();
Expand Down
51 changes: 51 additions & 0 deletions Content.IntegrationTests/Tests/Networking/PvsCommandTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Map.Components;
using Robust.Shared.Prototypes;

namespace Content.IntegrationTests.Tests.Networking;

[TestFixture]
public sealed class PvsCommandTest
{
public static EntProtoId TestEnt = "MobHuman";

[Test]
public async Task TestPvsCommands()
{
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false});
var (server, client) = pair;
await pair.RunTicksSync(5);

// Spawn a complex entity.
EntityUid entity = default;
await server.WaitPost(() => entity = server.EntMan.Spawn(TestEnt));
await pair.RunTicksSync(5);

// Check that the client has a variety pf entities.
Assert.That(client.EntMan.EntityCount, Is.GreaterThan(0));
Assert.That(client.EntMan.Count<MapComponent>, Is.GreaterThan(0));
Assert.That(client.EntMan.Count<MapGridComponent>, Is.GreaterThan(0));

var meta = client.MetaData(pair.ToClientUid(entity));
var lastApplied = meta.LastStateApplied;

// Dirty all entities
await server.ExecuteCommand("dirty");
await pair.RunTicksSync(5);
Assert.That(meta.LastStateApplied, Is.GreaterThan(lastApplied));
await pair.RunTicksSync(5);

// Do a client-side full state reset
await client.ExecuteCommand("resetallents");
await pair.RunTicksSync(5);

// Request a full server state.
lastApplied = meta.LastStateApplied;
await client.ExecuteCommand("fullstatereset");
await pair.RunTicksSync(10);
Assert.That(meta.LastStateApplied, Is.GreaterThan(lastApplied));

await server.WaitPost(() => server.EntMan.DeleteEntity(entity));
await pair.CleanReturnAsync();
}
}
Loading

0 comments on commit 35ba42a

Please sign in to comment.