From b5618d9e293a8c151b047a53375d04ec6e9739d2 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 22 Apr 2023 18:14:17 -0400 Subject: [PATCH] - Fix test issues. - Fix non-swarm mode updates. - Add node ID logging context for live test. --- .../Extensions/ServiceCollectionExtensions.cs | 11 ++++- .../Swarm/SwarmService.cs | 3 ++ .../Live/LiveTestingServer.cs | 23 +++++++++-- .../Live/TestLiveServer.cs | 41 ++++--------------- 4 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/Tgstation.Server.Host/Extensions/ServiceCollectionExtensions.cs b/src/Tgstation.Server.Host/Extensions/ServiceCollectionExtensions.cs index 8e88c63ebf..a5cd24ca6f 100644 --- a/src/Tgstation.Server.Host/Extensions/ServiceCollectionExtensions.cs +++ b/src/Tgstation.Server.Host/Extensions/ServiceCollectionExtensions.cs @@ -23,7 +23,16 @@ namespace Tgstation.Server.Host.Extensions /// /// Common template used for adding our custom log context to serilog. /// - public const string SerilogContextTemplate = "(Instance:{Instance}|Job:{Job}|Request:{Request}|User:{User}|Monitor:{Monitor}|Bridge:{Bridge}|Chat:{ChatMessage}"; + /// Should not be changed. Only mutable for the sake of identifying swarm nodes under a single test environment + public static string SerilogContextTemplate { get; set; } + + /// + /// Initializes static members of the class. + /// + static ServiceCollectionExtensions() + { + SerilogContextTemplate = "(Instance:{Instance}|Job:{Job}|Request:{Request}|User:{User}|Monitor:{Monitor}|Bridge:{Bridge}|Chat:{ChatMessage}"; + } /// /// Add a standard binding. diff --git a/src/Tgstation.Server.Host/Swarm/SwarmService.cs b/src/Tgstation.Server.Host/Swarm/SwarmService.cs index bc1fe2a3f0..023e0b9273 100644 --- a/src/Tgstation.Server.Host/Swarm/SwarmService.cs +++ b/src/Tgstation.Server.Host/Swarm/SwarmService.cs @@ -59,6 +59,9 @@ namespace Tgstation.Server.Host.Swarm { get { + if (!SwarmMode) + return true; + lock (swarmServers) return swarmServers.Count - 1 >= swarmConfiguration.UpdateRequiredNodeCount; } diff --git a/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs b/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs index fb54b3696b..60f177837e 100644 --- a/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs +++ b/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs @@ -1,4 +1,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Serilog.Context; + using System; using System.Collections.Generic; using System.Globalization; @@ -11,6 +14,7 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Host; using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.Core; +using Tgstation.Server.Host.Extensions; using Tgstation.Server.Host.Setup; namespace Tgstation.Server.Tests.Live @@ -32,8 +36,15 @@ namespace Tgstation.Server.Tests.Live readonly List args; readonly List swarmArgs; + string swarmNodeId; + public IServer RealServer { get; private set; } + static LiveTestingServer() + { + ServiceCollectionExtensions.SerilogContextTemplate += "|Node:{node}"; + } + public LiveTestingServer(SwarmConfiguration swarmConfiguration, bool enableOAuth, ushort port = 5010) { Directory = Environment.GetEnvironmentVariable("TGS_TEST_TEMP_DIRECTORY"); @@ -146,6 +157,8 @@ namespace Tgstation.Server.Tests.Live if (swarmConfiguration.UpdateRequiredNodeCount != 0) swarmArgs.Add($"Swarm:UpdateRequiredNodeCount={swarmConfiguration.UpdateRequiredNodeCount}"); + + swarmNodeId = swarmConfiguration.Identifier; } public async Task RunNoArgumentsTest(CancellationToken cancellationToken) @@ -163,7 +176,8 @@ namespace Tgstation.Server.Tests.Live public async Task Run(CancellationToken cancellationToken) { - Console.WriteLine("TEST SERVER START"); + var messageAddition = swarmNodeId != null ? $": {swarmNodeId}" : String.Empty; + Console.WriteLine("TEST SERVER START" + messageAddition); var firstRun = RealServer == null; var arrayArgs = args.Concat(swarmArgs).ToArray(); RealServer = await Application @@ -176,8 +190,11 @@ namespace Tgstation.Server.Tests.Live if (firstRun) args[0] = string.Format(CultureInfo.InvariantCulture, "Database:DropDatabase={0}", false); - await RealServer.Run(cancellationToken); - Console.WriteLine("TEST SERVER END"); + using (swarmNodeId != null + ? LogContext.PushProperty("node", swarmNodeId) + : null) + await RealServer.Run(cancellationToken); + Console.WriteLine($"TEST SERVER END" + messageAddition); } } } diff --git a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs index d5337b2f0d..e76e552077 100644 --- a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs +++ b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs @@ -424,22 +424,12 @@ namespace Tgstation.Server.Tests.Live using var controllerClient2 = await CreateAdminClient(controller.Url, cancellationToken); using var node1Client2 = await CreateAdminClient(node1.Url, cancellationToken); - await controllerClient2.Administration.Update( + await ApiAssert.ThrowsException(() => controllerClient2.Administration.Update( new ServerUpdateRequest { NewVersion = testUpdateVersion }, - cancellationToken); - - // wait a few seconds and check we can do it again without getting ErrorCode.UpdateInProgress - await Task.Delay(TimeSpan.FromSeconds(3)); - - await controllerClient2.Administration.Update( - new ServerUpdateRequest - { - NewVersion = testUpdateVersion - }, - cancellationToken); + cancellationToken), ErrorCode.SwarmIntegrityCheckFailed); // regression: test updating also works from the controller serverTask = Task.WhenAll( @@ -492,7 +482,8 @@ namespace Tgstation.Server.Tests.Live { Address = controllerAddress, Identifier = "controller", - PrivateKey = PrivateKey + PrivateKey = PrivateKey, + UpdateRequiredNodeCount = 2, }, false, 5011)) { using var node1 = new LiveTestingServer(new SwarmConfiguration @@ -622,30 +613,16 @@ namespace Tgstation.Server.Tests.Live Task.Delay(TimeSpan.FromMinutes(1))); Assert.IsTrue(node1Task.IsCompleted); - // should remain registered + // should have unregistered controllerInfo = await controllerClient2.ServerInformation(cancellationToken); - Assert.AreEqual(2, controllerInfo.SwarmServers.Count); - Assert.IsNotNull(controllerInfo.SwarmServers.SingleOrDefault(x => x.Identifier == "node2")); + Assert.AreEqual(1, controllerInfo.SwarmServers.Count); + Assert.IsNull(controllerInfo.SwarmServers.SingleOrDefault(x => x.Identifier == "node2")); // update should fail - await controllerClient2.Administration.Update(new ServerUpdateRequest + await ApiAssert.ThrowsException(() => controllerClient2.Administration.Update(new ServerUpdateRequest { NewVersion = new Version(4, 6, 2) - }, cancellationToken); - - async Task WaitForUpdateFailure() - { - ServerInformationResponse serverInformation; - serverInformation = await controllerClient2.ServerInformation(cancellationToken); - while (serverInformation.UpdateInProgress) - { - await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken); - serverInformation = await controllerClient2.ServerInformation(cancellationToken); - } - } - - var updateFailureTask = WaitForUpdateFailure(); - await Task.WhenAny(updateFailureTask, Task.Delay(TimeSpan.FromMinutes(5), cancellationToken)); + }, cancellationToken), ErrorCode.SwarmIntegrityCheckFailed); node2Task = node2.Run(cancellationToken); using var node2Client2 = await CreateAdminClient(node2.Url, cancellationToken);