Adds swarm integration test

This commit is contained in:
Cyberboss
2020-12-28 11:00:10 -05:00
parent e22830007a
commit bc90c13322
2 changed files with 190 additions and 9 deletions
+176 -4
View File
@@ -43,7 +43,7 @@ namespace Tgstation.Server.Tests
[TestMethod]
public async Task TestUpdateProtocolAndDisabledOAuth()
{
using var server = new TestingServer(false);
using var server = new TestingServer(null, false);
using var serverCts = new CancellationTokenSource();
var cancellationToken = serverCts.Token;
var serverTask = server.Run(cancellationToken);
@@ -113,6 +113,178 @@ namespace Tgstation.Server.Tests
Assert.IsTrue(server.RestartRequested, "Server not requesting restart!");
}
[TestMethod]
public async Task TestSwarm()
{
const string PrivateKey = "adlfj73ywifhks7iwrgfegjs";
var controllerAddress = new Uri("http://localhost:5011");
using var controller = new TestingServer(new SwarmConfiguration
{
Address = controllerAddress,
Identifier = "controller",
PrivateKey = PrivateKey
}, false, 5011);
using var node1 = new TestingServer(new SwarmConfiguration
{
Address = new Uri("http://localhost:5012"),
ControllerAddress = controllerAddress,
Identifier = "node1",
PrivateKey = PrivateKey
}, false, 5012);
using var node2 = new TestingServer(new SwarmConfiguration
{
Address = new Uri("http://localhost:5013"),
ControllerAddress = controllerAddress,
Identifier = "node2",
PrivateKey = PrivateKey
}, false, 5013);
using var serverCts = new CancellationTokenSource();
var cancellationToken = serverCts.Token;
var serverTask = Task.WhenAll(
node1.Run(cancellationToken),
node2.Run(cancellationToken),
controller.Run(cancellationToken));
try
{
using var controllerClient = await CreateAdminClient(controller.Url, cancellationToken);
using var node1Client = await CreateAdminClient(node1.Url, cancellationToken);
using var node2Client = await CreateAdminClient(node2.Url, cancellationToken);
var controllerInfo = await controllerClient.ServerInformation(cancellationToken);
async Task WaitForSwarmServerUpdate()
{
ServerInformation serverInformation;
do
{
await Task.Delay(TimeSpan.FromSeconds(10));
serverInformation = await node1Client.ServerInformation(cancellationToken);
}
while (serverInformation.SwarmServers.Count == 1);
}
static void CheckInfo(ServerInformation serverInformation)
{
Assert.IsNotNull(serverInformation.SwarmServers);
Assert.AreEqual(3, serverInformation.SwarmServers.Count);
var node1 = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "node1");
Assert.IsNotNull(node1);
Assert.AreEqual(node1.Address, "http://localhost:5012");
Assert.IsFalse(node1.Controller);
var node2 = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "node2");
Assert.IsNotNull(node2);
Assert.AreEqual(node2.Address, "http://localhost:5013");
Assert.IsFalse(node2.Controller);
var controller = serverInformation.SwarmServers.SingleOrDefault(x => x.Identifier == "controller");
Assert.IsNotNull(controller);
Assert.AreEqual(controller.Address, "http://localhost:5011");
Assert.IsTrue(controller.Controller);
}
CheckInfo(controllerInfo);
// wait a few minutes for the updated server list to dispatch
await Task.WhenAny(
WaitForSwarmServerUpdate(),
Task.Delay(TimeSpan.FromMinutes(4)));
var node2Info = await node2Client.ServerInformation(cancellationToken);
var node1Info = await node1Client.ServerInformation(cancellationToken);
CheckInfo(node1Info);
CheckInfo(node2Info);
// check user info is shared
var newUser = await node2Client.Users.Create(new UserUpdate
{
Name = "asdf",
Password = "asdfasdfasdfasdf",
Enabled = true,
PermissionSet = new PermissionSet
{
AdministrationRights = AdministrationRights.ChangeVersion
}
}, cancellationToken);
var node1User = await node1Client.Users.GetId(newUser, cancellationToken);
Assert.AreEqual(newUser.Name, node1User.Name);
Assert.AreEqual(newUser.Enabled, node1User.Enabled);
using var controllerUserClient = await clientFactory.CreateFromLogin(
controllerAddress,
newUser.Name,
"asdfasdfasdfasdf");
using var node1BadClient = clientFactory.CreateFromToken(node1.Url, controllerUserClient.Token);
await Assert.ThrowsExceptionAsync<UnauthorizedException>(() => node1BadClient.Administration.Read(cancellationToken));
// check instance info is not shared
var controllerInstance = await controllerClient.Instances.CreateOrAttach(
new Api.Models.Instance
{
Name = "ControllerInstance",
Path = Path.Combine(controller.Directory, "ControllerInstance")
},
cancellationToken);
var node2Instance = await node2Client.Instances.CreateOrAttach(
new Api.Models.Instance
{
Name = "Node2Instance",
Path = Path.Combine(node2.Directory, "Node2Instance")
},
cancellationToken);
var node2InstanceList = await node2Client.Instances.List(null, cancellationToken);
Assert.AreEqual(1, node2InstanceList.Count);
Assert.AreEqual(node2Instance.Id, node2InstanceList.First().Id);
Assert.IsNotNull(await node2Client.Instances.GetId(node2Instance, cancellationToken));
var controllerInstanceList = await controllerClient.Instances.List(null, cancellationToken);
Assert.AreEqual(1, controllerInstanceList.Count);
Assert.AreEqual(controllerInstance.Id, controllerInstanceList.First().Id);
Assert.IsNotNull(await controllerClient.Instances.GetId(controllerInstance, cancellationToken));
await Assert.ThrowsExceptionAsync<ConflictException>(() => controllerClient.Instances.GetId(node2Instance, cancellationToken));
await Assert.ThrowsExceptionAsync<ConflictException>(() => node1Client.Instances.GetId(controllerInstance, cancellationToken));
// test update
var testUpdateVersion = new Version(4, 6, 2);
await node1Client.Administration.Update(
new Administration
{
NewVersion = testUpdateVersion
},
cancellationToken);
await Task.WhenAny(Task.Delay(TimeSpan.FromMinutes(2)), serverTask);
Assert.IsTrue(serverTask.IsCompleted);
void CheckServerUpdated(TestingServer server)
{
Assert.IsTrue(Directory.Exists(server.UpdatePath), "Update directory not present!");
var updatedAssemblyPath = Path.Combine(server.UpdatePath, "Tgstation.Server.Host.dll");
Assert.IsTrue(File.Exists(updatedAssemblyPath), "Updated assembly missing!");
var updatedAssemblyVersion = FileVersionInfo.GetVersionInfo(updatedAssemblyPath);
Assert.AreEqual(testUpdateVersion, Version.Parse(updatedAssemblyVersion.FileVersion).Semver());
}
CheckServerUpdated(controller);
CheckServerUpdated(node1);
CheckServerUpdated(node2);
}
finally
{
serverCts.Cancel();
await serverTask;
}
Directory.Delete(Path.GetDirectoryName(controller.Directory), true);
}
static void TerminateAllDDs()
{
foreach (var proc in System.Diagnostics.Process.GetProcessesByName("DreamDaemon"))
@@ -122,7 +294,7 @@ namespace Tgstation.Server.Tests
async Task<IServerClient> CreateAdminClient(Uri url, CancellationToken cancellationToken)
{
var giveUpAt = DateTimeOffset.UtcNow.AddSeconds(60);
var giveUpAt = DateTimeOffset.UtcNow.AddMinutes(2);
for(var I = 1; ; ++I)
{
try
@@ -311,7 +483,7 @@ namespace Tgstation.Server.Tests
Assert.Inconclusive("Cannot run server test because DreamDaemon will not start headless while the BYOND pager is running!");
}
using var server = new TestingServer(true);
using var server = new TestingServer(null, true);
const int MaximumTestMinutes = 20;
using var hardTimeoutCancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(MaximumTestMinutes));
@@ -554,7 +726,7 @@ namespace Tgstation.Server.Tests
[TestMethod]
public async Task TestRepoParentLookup()
{
using var testingServer = new TestingServer(false);
using var testingServer = new TestingServer(null, false);
LibGit2Sharp.Repository.Clone("https://github.com/Cyberboss/test", testingServer.Directory);
var libGit2Repo = new LibGit2Sharp.Repository(testingServer.Directory);
using var repo = new Host.Components.Repository.Repository(
+14 -5
View File
@@ -32,13 +32,13 @@ namespace Tgstation.Server.Tests
IServer realServer;
public TestingServer(bool enableOAuth)
public TestingServer(SwarmConfiguration swarmConfiguration, bool enableOAuth, ushort port = 5010)
{
Directory = Environment.GetEnvironmentVariable("TGS4_TEST_TEMP_DIRECTORY");
if (String.IsNullOrWhiteSpace(Directory))
{
Directory = Path.Combine(Path.GetTempPath(), "TGS4_INTEGRATION_TEST");
if (System.IO.Directory.Exists(Directory))
if (System.IO.Directory.Exists(Directory) && swarmConfiguration == null)
try
{
System.IO.Directory.Delete(Directory, true);
@@ -49,8 +49,8 @@ namespace Tgstation.Server.Tests
Directory = Path.Combine(Directory, Guid.NewGuid().ToString());
System.IO.Directory.CreateDirectory(Directory);
const string UrlString = "http://localhost:5010";
Url = new Uri(UrlString);
string urlString = $"http://localhost:{port}";
Url = new Uri(urlString);
//so we need a db
//we have to rely on env vars
@@ -73,7 +73,7 @@ namespace Tgstation.Server.Tests
var args = new List<string>()
{
String.Format(CultureInfo.InvariantCulture, "Database:DropDatabase={0}", true),
String.Format(CultureInfo.InvariantCulture, "General:ApiPort={0}", 5010),
String.Format(CultureInfo.InvariantCulture, "General:ApiPort={0}", port),
String.Format(CultureInfo.InvariantCulture, "Database:DatabaseType={0}", DatabaseType),
String.Format(CultureInfo.InvariantCulture, "Database:ConnectionString={0}", connectionString),
String.Format(CultureInfo.InvariantCulture, "General:SetupWizardMode={0}", SetupWizardMode.Never),
@@ -87,6 +87,15 @@ namespace Tgstation.Server.Tests
"General:ByondTopicTimeout=3000"
};
if (swarmConfiguration != null)
{
args.Add($"Swarm:PrivateKey={swarmConfiguration.PrivateKey}");
args.Add($"Swarm:Identifier={swarmConfiguration.Identifier}");
args.Add($"Swarm:Address={swarmConfiguration.Address}");
if (swarmConfiguration.ControllerAddress != null)
args.Add($"Swarm:ControllerAddress={swarmConfiguration.ControllerAddress}");
}
// enable all oauth providers
if (enableOAuth)
foreach (var I in Enum.GetValues(typeof(OAuthProvider)))