From 9446ab76f918abf7699fc1ef7d05b041d80a8fbc Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Fri, 22 Dec 2023 21:53:23 -0500 Subject: [PATCH] Make integration tests fail when logging console errors (#4747) * Make tests fail when logging console errors * Add log convenience property --- .../Console/ClientConsoleHost.Completions.cs | 2 +- Robust.Client/Console/ClientConsoleHost.cs | 3 ++- Robust.Server/Console/ServerConsoleHost.cs | 9 ++++++- Robust.UnitTesting/RobustIntegrationTest.cs | 9 +++++++ .../Shared/EngineIntegrationTest_Test.cs | 18 ++++++++++++++ Robust.UnitTesting/TestingConsoleHost.cs | 24 +++++++++++++++++++ 6 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 Robust.UnitTesting/TestingConsoleHost.cs diff --git a/Robust.Client/Console/ClientConsoleHost.Completions.cs b/Robust.Client/Console/ClientConsoleHost.Completions.cs index c1ad7d095..7bda1199f 100644 --- a/Robust.Client/Console/ClientConsoleHost.Completions.cs +++ b/Robust.Client/Console/ClientConsoleHost.Completions.cs @@ -8,7 +8,7 @@ using Robust.Shared.Network.Messages; namespace Robust.Client.Console; -internal sealed partial class ClientConsoleHost +internal partial class ClientConsoleHost { private readonly Dictionary _completionsPending = new(); private int _completionSeq; diff --git a/Robust.Client/Console/ClientConsoleHost.cs b/Robust.Client/Console/ClientConsoleHost.cs index b3a6f844f..2dfec611d 100644 --- a/Robust.Client/Console/ClientConsoleHost.cs +++ b/Robust.Client/Console/ClientConsoleHost.cs @@ -47,7 +47,8 @@ namespace Robust.Client.Console } /// - internal sealed partial class ClientConsoleHost : ConsoleHost, IClientConsoleHost, IConsoleHostInternal, IPostInjectInit + [Virtual] + internal partial class ClientConsoleHost : ConsoleHost, IClientConsoleHost, IConsoleHostInternal, IPostInjectInit { [Dependency] private readonly IClientConGroupController _conGroup = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; diff --git a/Robust.Server/Console/ServerConsoleHost.cs b/Robust.Server/Console/ServerConsoleHost.cs index a86f3d738..af88e701e 100644 --- a/Robust.Server/Console/ServerConsoleHost.cs +++ b/Robust.Server/Console/ServerConsoleHost.cs @@ -15,7 +15,8 @@ using Robust.Shared.Utility; namespace Robust.Server.Console { /// - internal sealed class ServerConsoleHost : ConsoleHost, IServerConsoleHost, IConsoleHostInternal + [Virtual] + internal class ServerConsoleHost : ConsoleHost, IServerConsoleHost, IConsoleHostInternal { [Dependency] private readonly IConGroupController _groupController = default!; [Dependency] private readonly IPlayerManager _players = default!; @@ -127,11 +128,17 @@ namespace Robust.Server.Console // toolshed time _toolshed.InvokeCommand(shell, command, null, out var res, out var ctx); + bool anyErrors = false; foreach (var err in ctx.GetErrors()) { + anyErrors = true; ctx.WriteLine(err.Describe()); } + // why does ctx not have any write-error support? + if (anyErrors) + shell.WriteError($"Failed to execute toolshed command"); + shell.WriteLine(FormattedMessage.FromMarkupPermissive(_toolshed.PrettyPrintType(res, out var more, moreUsed: true))); ctx.WriteVar("more", more); } diff --git a/Robust.UnitTesting/RobustIntegrationTest.cs b/Robust.UnitTesting/RobustIntegrationTest.cs index 974f54978..c3c6bc23b 100644 --- a/Robust.UnitTesting/RobustIntegrationTest.cs +++ b/Robust.UnitTesting/RobustIntegrationTest.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; using Moq; using NUnit.Framework; using Robust.Client; +using Robust.Client.Console; using Robust.Client.GameStates; using Robust.Client.Player; using Robust.Client.Timing; @@ -271,6 +272,7 @@ namespace Robust.UnitTesting public IGameTiming Timing { get; private set; } = default!; public IMapManager MapMan { get; private set; } = default!; public IConsoleHost ConsoleHost { get; private set; } = default!; + public ISawmill Log { get; private set; } = default!; protected virtual void ResolveIoC(IDependencyCollection deps) { @@ -281,6 +283,7 @@ namespace Robust.UnitTesting Timing = deps.Resolve(); MapMan = deps.Resolve(); ConsoleHost = deps.Resolve(); + Log = deps.Resolve().GetSawmill("test"); } public T System() where T : IEntitySystem @@ -668,6 +671,9 @@ namespace Robust.UnitTesting deps.Register(true); deps.RegisterInstance(new Mock().Object, true); deps.Register(true); + deps.Register(true); + deps.Register(true); + deps.Register(true); Options?.InitIoC?.Invoke(); deps.BuildGraph(); //ServerProgram.SetupLogging(); @@ -836,6 +842,9 @@ namespace Robust.UnitTesting deps.Register(true); deps.Register(true); deps.Register(true); + deps.Register(true); + deps.Register(true); + deps.Register(true); Options?.InitIoC?.Invoke(); deps.BuildGraph(); diff --git a/Robust.UnitTesting/Shared/EngineIntegrationTest_Test.cs b/Robust.UnitTesting/Shared/EngineIntegrationTest_Test.cs index 7d20a52fe..b2b021143 100644 --- a/Robust.UnitTesting/Shared/EngineIntegrationTest_Test.cs +++ b/Robust.UnitTesting/Shared/EngineIntegrationTest_Test.cs @@ -27,6 +27,24 @@ namespace Robust.UnitTesting.Shared Assert.That(client, Is.Not.Null); } + [Test] + public async Task ConsoleErrorsFailTest() + { + var server = StartServer(); + var client = StartClient(); + await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync()); + + // test missing commands + await client.WaitPost(() => Assert.Throws(() => client.ConsoleHost.ExecuteCommand("aaaaaaaa"))); + + // test invalid commands / missing arguments + await client.WaitPost(() => Assert.Throws(() => client.ConsoleHost.ExecuteCommand("cvar"))); + + // and repeat for the server + await server.WaitPost(() => Assert.Throws(() => server.ConsoleHost.ExecuteCommand("aaaaaaaa"))); + await server.WaitPost(() => Assert.Throws(() => server.ConsoleHost.ExecuteCommand("cvar"))); + } + [Test] public async Task ServerClientPairConnectCorrectlyTest() { diff --git a/Robust.UnitTesting/TestingConsoleHost.cs b/Robust.UnitTesting/TestingConsoleHost.cs new file mode 100644 index 000000000..f1ba74130 --- /dev/null +++ b/Robust.UnitTesting/TestingConsoleHost.cs @@ -0,0 +1,24 @@ +using NUnit.Framework; +using Robust.Client.Console; +using Robust.Server.Console; +using Robust.Shared.Player; + +namespace Robust.UnitTesting; + +internal sealed class TestingServerConsoleHost : ServerConsoleHost +{ + public override void WriteError(ICommonSession? session, string text) + { + base.WriteError(session, text); + Assert.Fail($"Console command encountered an error: {text}"); + } +} + +internal sealed class TestingClientConsoleHost : ClientConsoleHost +{ + public override void WriteError(ICommonSession? session, string text) + { + base.WriteError(session, text); + Assert.Fail($"Console command encountered an error: {text}"); + } +}