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);