From 8ab819a41456fec3a0c931a5c67c2d3c3fc178b3 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 22 Apr 2023 10:27:52 -0400 Subject: [PATCH] Reorganize integration tests --- .github/workflows/ci-suite.yml | 4 +- .../{ => Live}/AdministrationTest.cs | 8 +- .../{ => Live}/Instance/ByondTest.cs | 6 +- .../{ => Live}/Instance/ChatTest.cs | 4 +- .../{ => Live}/Instance/ConfigurationTest.cs | 6 +- .../{ => Live}/Instance/DeploymentTest.cs | 23 +- .../{ => Live}/Instance/InstanceTest.cs | 2 +- .../{ => Live}/Instance/JobsRequiredTest.cs | 8 +- .../{ => Live}/Instance/RepositoryTest.cs | 4 +- .../{ => Live}/Instance/TestBridgeHandler.cs | 6 +- .../{ => Live}/Instance/WatchdogTest.cs | 55 ++-- .../{ => Live}/InstanceManagerTest.cs | 10 +- .../LiveTestingServer.cs} | 50 ++-- .../{ => Live}/RawRequestTests.cs | 22 +- .../TestLiveServer.cs} | 256 +++++++----------- .../{ => Live}/UsersTest.cs | 6 +- .../Tgstation.Server.Tests/TestRepository.cs | 46 ++++ .../TestSystemInteraction.cs | 36 +++ 18 files changed, 292 insertions(+), 260 deletions(-) rename tests/Tgstation.Server.Tests/{ => Live}/AdministrationTest.cs (91%) rename tests/Tgstation.Server.Tests/{ => Live}/Instance/ByondTest.cs (96%) rename tests/Tgstation.Server.Tests/{ => Live}/Instance/ChatTest.cs (98%) rename tests/Tgstation.Server.Tests/{ => Live}/Instance/ConfigurationTest.cs (95%) rename tests/Tgstation.Server.Tests/{ => Live}/Instance/DeploymentTest.cs (90%) rename tests/Tgstation.Server.Tests/{ => Live}/Instance/InstanceTest.cs (97%) rename tests/Tgstation.Server.Tests/{ => Live}/Instance/JobsRequiredTest.cs (91%) rename tests/Tgstation.Server.Tests/{ => Live}/Instance/RepositoryTest.cs (98%) rename tests/Tgstation.Server.Tests/{ => Live}/Instance/TestBridgeHandler.cs (94%) rename tests/Tgstation.Server.Tests/{ => Live}/Instance/WatchdogTest.cs (95%) rename tests/Tgstation.Server.Tests/{ => Live}/InstanceManagerTest.cs (98%) rename tests/Tgstation.Server.Tests/{TestingServer.cs => Live/LiveTestingServer.cs} (77%) rename tests/Tgstation.Server.Tests/{ => Live}/RawRequestTests.cs (96%) rename tests/Tgstation.Server.Tests/{IntegrationTest.cs => Live/TestLiveServer.cs} (91%) rename tests/Tgstation.Server.Tests/{ => Live}/UsersTest.cs (99%) create mode 100644 tests/Tgstation.Server.Tests/TestRepository.cs create mode 100644 tests/Tgstation.Server.Tests/TestSystemInteraction.cs diff --git a/.github/workflows/ci-suite.yml b/.github/workflows/ci-suite.yml index 6bcfef3623..6d04ce288f 100644 --- a/.github/workflows/ci-suite.yml +++ b/.github/workflows/ci-suite.yml @@ -173,7 +173,7 @@ jobs: run: dotnet build -c ${{ matrix.configuration }}NoService - name: Run Unit Tests - run: sudo dotnet test --no-build --logger GitHubActions --filter FullyQualifiedName!~IntegrationTest -c ${{ matrix.configuration }}NoService --collect:"XPlat Code Coverage" --settings build/coverlet.runsettings --results-directory ./TestResults tgstation-server.sln + run: sudo dotnet test --no-build --logger GitHubActions --filter FullyQualifiedName!~TestLiveServer -c ${{ matrix.configuration }}NoService --collect:"XPlat Code Coverage" --settings build/coverlet.runsettings --results-directory ./TestResults tgstation-server.sln - name: Store Code Coverage uses: actions/upload-artifact@v3 @@ -204,7 +204,7 @@ jobs: run: dotnet build -c ${{ matrix.configuration }} - name: Run Unit Tests - run: dotnet test --no-build --logger GitHubActions --filter FullyQualifiedName!~IntegrationTest -c ${{ matrix.configuration }} --collect:"XPlat Code Coverage" --settings build/coverlet.runsettings --results-directory ./TestResults tgstation-server.sln + run: dotnet test --no-build --logger GitHubActions --filter FullyQualifiedName!~TestLiveServer -c ${{ matrix.configuration }} --collect:"XPlat Code Coverage" --settings build/coverlet.runsettings --results-directory ./TestResults tgstation-server.sln - name: Store Code Coverage uses: actions/upload-artifact@v3 diff --git a/tests/Tgstation.Server.Tests/AdministrationTest.cs b/tests/Tgstation.Server.Tests/Live/AdministrationTest.cs similarity index 91% rename from tests/Tgstation.Server.Tests/AdministrationTest.cs rename to tests/Tgstation.Server.Tests/Live/AdministrationTest.cs index ab7f9e1430..8d2b6ac4ca 100644 --- a/tests/Tgstation.Server.Tests/AdministrationTest.cs +++ b/tests/Tgstation.Server.Tests/Live/AdministrationTest.cs @@ -8,7 +8,7 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Response; using Tgstation.Server.Client; -namespace Tgstation.Server.Tests +namespace Tgstation.Server.Tests.Live { sealed class AdministrationTest { @@ -30,9 +30,9 @@ namespace Tgstation.Server.Tests { var logs = await client.ListLogs(null, cancellationToken); Assert.AreNotEqual(0, logs.Count); - var logFile = logs.First(); + var logFile = logs[0]; Assert.IsNotNull(logFile); - Assert.IsFalse(String.IsNullOrWhiteSpace(logFile.Name)); + Assert.IsFalse(string.IsNullOrWhiteSpace(logFile.Name)); Assert.IsNull(logFile.FileTicket); var downloadedTuple = await client.GetLog(logFile, cancellationToken); @@ -60,7 +60,7 @@ namespace Tgstation.Server.Tests } catch (RateLimitException) { - if (String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) + if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) { Assert.Inconclusive("GitHub rate limit hit while testing administration endpoint. Set environment variable TGS_TEST_GITHUB_TOKEN to fix this!"); } diff --git a/tests/Tgstation.Server.Tests/Instance/ByondTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs similarity index 96% rename from tests/Tgstation.Server.Tests/Instance/ByondTest.cs rename to tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs index 1b19569b6f..6531ac585b 100644 --- a/tests/Tgstation.Server.Tests/Instance/ByondTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs @@ -17,11 +17,11 @@ using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.IO; using Tgstation.Server.Host.System; -namespace Tgstation.Server.Tests.Instance +namespace Tgstation.Server.Tests.Live.Instance { sealed class ByondTest : JobsRequiredTest { - public static readonly Version TestVersion = new (514, 1588); + public static readonly Version TestVersion = new(514, 1588); readonly IByondClient byondClient; @@ -83,7 +83,7 @@ namespace Tgstation.Server.Tests.Instance var dreamMakerDir = Path.Combine(metadata.Path, "Byond", newModel.Version.ToString(), "byond", "bin"); Assert.IsTrue(Directory.Exists(dreamMakerDir), $"Directory {dreamMakerDir} does not exist!"); - Assert.IsTrue(File.Exists(Path.Combine(dreamMakerDir, dreamMaker)), $"Missing DreamMaker executable! Dir contents: {String.Join(", ", Directory.GetFileSystemEntries(dreamMakerDir))}"); + Assert.IsTrue(File.Exists(Path.Combine(dreamMakerDir, dreamMaker)), $"Missing DreamMaker executable! Dir contents: {string.Join(", ", Directory.GetFileSystemEntries(dreamMakerDir))}"); } async Task TestNoVersion(CancellationToken cancellationToken) diff --git a/tests/Tgstation.Server.Tests/Instance/ChatTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs similarity index 98% rename from tests/Tgstation.Server.Tests/Instance/ChatTest.cs rename to tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs index f354110e89..ee1b718d96 100644 --- a/tests/Tgstation.Server.Tests/Instance/ChatTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/ChatTest.cs @@ -10,7 +10,7 @@ using Tgstation.Server.Api.Models.Request; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; -namespace Tgstation.Server.Tests.Instance +namespace Tgstation.Server.Tests.Live.Instance { sealed class ChatTest { @@ -143,7 +143,7 @@ namespace Tgstation.Server.Tests.Instance Assert.AreEqual(true, updatedBot.Enabled); - var channelId = UInt64.Parse(Environment.GetEnvironmentVariable("TGS_TEST_DISCORD_CHANNEL")); + var channelId = ulong.Parse(Environment.GetEnvironmentVariable("TGS_TEST_DISCORD_CHANNEL")); updatedBot = await chatClient.Update(new ChatBotUpdateRequest { diff --git a/tests/Tgstation.Server.Tests/Instance/ConfigurationTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/ConfigurationTest.cs similarity index 95% rename from tests/Tgstation.Server.Tests/Instance/ConfigurationTest.cs rename to tests/Tgstation.Server.Tests/Live/Instance/ConfigurationTest.cs index e2bc9c7ebe..cb98a62cba 100644 --- a/tests/Tgstation.Server.Tests/Instance/ConfigurationTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/ConfigurationTest.cs @@ -17,7 +17,7 @@ using Tgstation.Server.Client.Components; using Tgstation.Server.Host.IO; using Tgstation.Server.Host.System; -namespace Tgstation.Server.Tests.Instance +namespace Tgstation.Server.Tests.Live.Instance { sealed class ConfigurationTest { @@ -32,7 +32,7 @@ namespace Tgstation.Server.Tests.Instance bool FileExists(IConfigurationFile file) { - var tmp = (file.Path?.StartsWith('/') ?? false) ? '.' + file.Path : file.Path; + var tmp = file.Path?.StartsWith('/') ?? false ? '.' + file.Path : file.Path; var path = Path.Combine(instance.Path, "Configuration", tmp); var result = File.Exists(path); return result; @@ -87,7 +87,7 @@ namespace Tgstation.Server.Tests.Instance await configurationClient.DeleteEmptyDirectory(TestDir, cancellationToken); - var tmp = (TestDir.Path?.StartsWith('/') ?? false) ? '.' + TestDir.Path : TestDir.Path; + var tmp = TestDir.Path?.StartsWith('/') ?? false ? '.' + TestDir.Path : TestDir.Path; var path = Path.Combine(instance.Path, "Configuration", tmp); Assert.IsFalse(Directory.Exists(path)); diff --git a/tests/Tgstation.Server.Tests/Instance/DeploymentTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/DeploymentTest.cs similarity index 90% rename from tests/Tgstation.Server.Tests/Instance/DeploymentTest.cs rename to tests/Tgstation.Server.Tests/Live/Instance/DeploymentTest.cs index 596e52270d..b56d30efd1 100644 --- a/tests/Tgstation.Server.Tests/Instance/DeploymentTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/DeploymentTest.cs @@ -10,8 +10,9 @@ using Tgstation.Server.Api.Rights; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; using Tgstation.Server.Host.System; +using Tgstation.Server.Tests.Live; -namespace Tgstation.Server.Tests.Instance +namespace Tgstation.Server.Tests.Live.Instance { sealed class DeploymentTest : JobsRequiredTest { @@ -24,8 +25,8 @@ namespace Tgstation.Server.Tests.Instance public DeploymentTest(IInstanceClient instanceClient, IJobsClient jobsClient) : base(jobsClient) { this.instanceClient = instanceClient ?? throw new ArgumentNullException(nameof(instanceClient)); - this.dreamMakerClient = instanceClient.DreamMaker; - this.dreamDaemonClient = instanceClient.DreamDaemon; + dreamMakerClient = instanceClient.DreamMaker; + dreamDaemonClient = instanceClient.DreamDaemon; } public async Task RunPreRepoClone(CancellationToken cancellationToken) @@ -50,27 +51,27 @@ namespace Tgstation.Server.Tests.Instance var updatedDM = await dreamMakerClient.Update(new DreamMakerRequest { ProjectName = "tests/DMAPI/ApiFree/api_free", - ApiValidationPort = IntegrationTest.DMPort + ApiValidationPort = TestLiveServer.DMPort }, cancellationToken); - Assert.AreEqual(IntegrationTest.DMPort, updatedDM.ApiValidationPort); + Assert.AreEqual(TestLiveServer.DMPort, updatedDM.ApiValidationPort); Assert.AreEqual("tests/DMAPI/ApiFree/api_free", updatedDM.ProjectName); } else { var updatedDM = await dreamMakerClient.Update(new DreamMakerRequest { - ApiValidationPort = IntegrationTest.DMPort + ApiValidationPort = TestLiveServer.DMPort }, cancellationToken); - Assert.AreEqual(IntegrationTest.DMPort, updatedDM.ApiValidationPort); + Assert.AreEqual(TestLiveServer.DMPort, updatedDM.ApiValidationPort); } var updatedDD = await dreamDaemonClient.Update(new DreamDaemonRequest { StartupTimeout = 15, - Port = IntegrationTest.DDPort + Port = TestLiveServer.DDPort }, cancellationToken); Assert.AreEqual(15U, updatedDD.StartupTimeout); - Assert.AreEqual(IntegrationTest.DDPort, updatedDD.Port); + Assert.AreEqual(TestLiveServer.DDPort, updatedDD.Port); async Task CompileAfterByondInstall() { @@ -82,11 +83,11 @@ namespace Tgstation.Server.Tests.Instance await Task.WhenAll( ApiAssert.ThrowsException(() => dreamDaemonClient.Update(new DreamDaemonRequest { - Port = IntegrationTest.DMPort + Port = TestLiveServer.DMPort }, cancellationToken), ErrorCode.PortNotAvailable), ApiAssert.ThrowsException(() => dreamMakerClient.Update(new DreamMakerRequest { - ApiValidationPort = IntegrationTest.DDPort + ApiValidationPort = TestLiveServer.DDPort }, cancellationToken), ErrorCode.PortNotAvailable), deployJobTask); diff --git a/tests/Tgstation.Server.Tests/Instance/InstanceTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/InstanceTest.cs similarity index 97% rename from tests/Tgstation.Server.Tests/Instance/InstanceTest.cs rename to tests/Tgstation.Server.Tests/Live/Instance/InstanceTest.cs index 6ef7627b7a..dae2bee1d9 100644 --- a/tests/Tgstation.Server.Tests/Instance/InstanceTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/InstanceTest.cs @@ -6,7 +6,7 @@ using Tgstation.Server.Client; using Tgstation.Server.Client.Components; using Tgstation.Server.Host.Components; -namespace Tgstation.Server.Tests.Instance +namespace Tgstation.Server.Tests.Live.Instance { sealed class InstanceTest { diff --git a/tests/Tgstation.Server.Tests/Instance/JobsRequiredTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/JobsRequiredTest.cs similarity index 91% rename from tests/Tgstation.Server.Tests/Instance/JobsRequiredTest.cs rename to tests/Tgstation.Server.Tests/Live/Instance/JobsRequiredTest.cs index 4be2ce4472..be3003b1e3 100644 --- a/tests/Tgstation.Server.Tests/Instance/JobsRequiredTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/JobsRequiredTest.cs @@ -9,7 +9,7 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Response; using Tgstation.Server.Client.Components; -namespace Tgstation.Server.Tests.Instance +namespace Tgstation.Server.Tests.Live.Instance { class JobsRequiredTest { @@ -17,7 +17,7 @@ namespace Tgstation.Server.Tests.Instance public JobsRequiredTest(IJobsClient jobsClient) { - this.JobsClient = jobsClient; + JobsClient = jobsClient; } public async Task WaitForJob(JobResponse originalJob, int timeout, bool? expectFailure, ErrorCode? expectedCode, CancellationToken cancellationToken) @@ -37,9 +37,9 @@ namespace Tgstation.Server.Tests.Instance Assert.Fail($"Job ID {job.Id} \"{job.Description}\" timed out!"); } - if(expectFailure.HasValue && (expectFailure.Value ^ job.ExceptionDetails != null)) + if (expectFailure.HasValue && expectFailure.Value ^ job.ExceptionDetails != null) Assert.Fail(job.ExceptionDetails - ?? $"Expected job \"{job.Id}\" \"{job.Description}\" to fail {(expectedCode.HasValue ? $"with ErrorCode \"{expectedCode.Value}\" " : String.Empty)}but it didn't"); + ?? $"Expected job \"{job.Id}\" \"{job.Description}\" to fail {(expectedCode.HasValue ? $"with ErrorCode \"{expectedCode.Value}\" " : string.Empty)}but it didn't"); if (expectedCode.HasValue) Assert.AreEqual(expectedCode.Value, job.ErrorCode, job.ExceptionDetails); diff --git a/tests/Tgstation.Server.Tests/Instance/RepositoryTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs similarity index 98% rename from tests/Tgstation.Server.Tests/Instance/RepositoryTest.cs rename to tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs index 7d5b5a96a1..b03b676693 100644 --- a/tests/Tgstation.Server.Tests/Instance/RepositoryTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs @@ -1,4 +1,4 @@ - using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Linq; @@ -11,7 +11,7 @@ using Tgstation.Server.Api.Models.Response; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; -namespace Tgstation.Server.Tests.Instance +namespace Tgstation.Server.Tests.Live.Instance { sealed class RepositoryTest : JobsRequiredTest { diff --git a/tests/Tgstation.Server.Tests/Instance/TestBridgeHandler.cs b/tests/Tgstation.Server.Tests/Live/Instance/TestBridgeHandler.cs similarity index 94% rename from tests/Tgstation.Server.Tests/Instance/TestBridgeHandler.cs rename to tests/Tgstation.Server.Tests/Live/Instance/TestBridgeHandler.cs index ef751274b9..c3828ebb6e 100644 --- a/tests/Tgstation.Server.Tests/Instance/TestBridgeHandler.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/TestBridgeHandler.cs @@ -11,7 +11,7 @@ using Newtonsoft.Json; using Tgstation.Server.Host.Components.Interop; using Tgstation.Server.Host.Components.Interop.Bridge; -namespace Tgstation.Server.Tests.Instance +namespace Tgstation.Server.Tests.Live.Instance { sealed class TestBridgeHandler : Chunker, IBridgeHandler { @@ -69,7 +69,7 @@ namespace Tgstation.Server.Tests.Instance var splits = parameters.ChatMessage.Text.Split(':', StringSplitOptions.RemoveEmptyEntries); Assert.AreEqual(2, splits.Length); var coreMessage = splits[0]; - Assert.IsFalse(String.IsNullOrWhiteSpace(coreMessage)); + Assert.IsFalse(string.IsNullOrWhiteSpace(coreMessage)); if (coreMessage == "done") { Assert.IsTrue(chunksProcessed); @@ -84,7 +84,7 @@ namespace Tgstation.Server.Tests.Instance } Assert.AreEqual("payload", coreMessage); - lastBridgeRequestSize = $"http://127.0.0.1:{serverPort}/Bridge?data=".Length + HttpUtility.UrlEncode( + lastBridgeRequestSize = $"http://127.0.0.1:{serverPort}/Bridge?data=".Length + HttpUtility.UrlEncode( JsonConvert.SerializeObject(parameters, DMApiConstants.SerializerSettings)).Length; return new BridgeResponseHack { diff --git a/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs similarity index 95% rename from tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs rename to tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs index ed30eb27e2..d2ff2aa408 100644 --- a/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs @@ -31,8 +31,9 @@ using Tgstation.Server.Host.Controllers; using Tgstation.Server.Host.Extensions; using Tgstation.Server.Host.IO; using Tgstation.Server.Host.System; +using Tgstation.Server.Tests.Live; -namespace Tgstation.Server.Tests.Instance +namespace Tgstation.Server.Tests.Live.Instance { sealed class WatchdogTest : JobsRequiredTest { @@ -52,7 +53,7 @@ namespace Tgstation.Server.Tests.Instance public async Task Run(CancellationToken cancellationToken) { - global::System.Console.WriteLine("TEST: START WATCHDOG TESTS"); + System.Console.WriteLine("TEST: START WATCHDOG TESTS"); await Task.WhenAll( // Increase startup timeout, disable heartbeats @@ -60,7 +61,7 @@ namespace Tgstation.Server.Tests.Instance { StartupTimeout = 15, HeartbeatSeconds = 0, - Port = IntegrationTest.DDPort + Port = TestLiveServer.DDPort }, cancellationToken), ApiAssert.ThrowsException(() => instanceClient.DreamDaemon.Update(new DreamDaemonRequest { @@ -115,7 +116,7 @@ namespace Tgstation.Server.Tests.Instance var topicRequestResult = await TopicClient.SendTopic( IPAddress.Loopback, $"tgs_integration_test_tactics5=1", - IntegrationTest.DDPort, + TestLiveServer.DDPort, cancellationToken); Assert.IsNotNull(topicRequestResult); @@ -164,7 +165,7 @@ namespace Tgstation.Server.Tests.Instance async Task TestDMApiFreeDeploy(CancellationToken cancellationToken) { - global::System.Console.WriteLine("TEST: WATCHDOG API FREE TEST"); + System.Console.WriteLine("TEST: WATCHDOG API FREE TEST"); var daemonStatus = await DeployTestDme("ApiFree/api_free", DreamDaemonSecurity.Safe, false, cancellationToken); Assert.AreEqual(WatchdogStatus.Offline, daemonStatus.Status.Value); @@ -181,7 +182,7 @@ namespace Tgstation.Server.Tests.Instance Assert.AreEqual(WatchdogStatus.Online, daemonStatus.Status.Value); Assert.AreEqual(false, daemonStatus.SoftRestart); Assert.AreEqual(false, daemonStatus.SoftShutdown); - Assert.AreEqual(String.Empty, daemonStatus.AdditionalParameters); + Assert.AreEqual(string.Empty, daemonStatus.AdditionalParameters); var initialCompileJob = daemonStatus.ActiveCompileJob; await CheckDMApiFail(daemonStatus.ActiveCompileJob, cancellationToken); @@ -201,7 +202,7 @@ namespace Tgstation.Server.Tests.Instance async Task RunBasicTest(CancellationToken cancellationToken) { - global::System.Console.WriteLine("TEST: WATCHDOG BASIC TEST"); + System.Console.WriteLine("TEST: WATCHDOG BASIC TEST"); var daemonStatus = await instanceClient.DreamDaemon.Update(new DreamDaemonRequest { @@ -222,7 +223,7 @@ namespace Tgstation.Server.Tests.Instance { blockSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, true); blockSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); - blockSocket.Bind(new IPEndPoint(IPAddress.Any, IntegrationTest.DDPort)); + blockSocket.Bind(new IPEndPoint(IPAddress.Any, TestLiveServer.DDPort)); // Don't use StartDD here startJob = await instanceClient.DreamDaemon.Start(cancellationToken); @@ -248,9 +249,9 @@ namespace Tgstation.Server.Tests.Instance daemonStatus = await instanceClient.DreamDaemon.Update(new DreamDaemonRequest { - AdditionalParameters = String.Empty + AdditionalParameters = string.Empty }, cancellationToken); - Assert.AreEqual(String.Empty, daemonStatus.AdditionalParameters); + Assert.AreEqual(string.Empty, daemonStatus.AdditionalParameters); } async Task RunHeartbeatTest(bool checkDump, CancellationToken cancellationToken) @@ -275,7 +276,7 @@ namespace Tgstation.Server.Tests.Instance using var ddProc = ddProcs.Single(); IProcessExecutor executor = null; executor = new ProcessExecutor( - System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? new WindowsProcessFeatures(Mock.Of>()) : new PosixProcessFeatures(new Lazy(() => executor), Mock.Of(), Mock.Of>()), Mock.Of(), @@ -339,7 +340,7 @@ namespace Tgstation.Server.Tests.Instance { try { - SocketExtensions.BindTest(IntegrationTest.DDPort, false); + SocketExtensions.BindTest(TestLiveServer.DDPort, false); break; } catch @@ -385,7 +386,7 @@ namespace Tgstation.Server.Tests.Instance System.Console.WriteLine("TEST: Sending Bridge tests topic..."); - var bridgeTestTopicResult = await TopicClient.SendTopic(IPAddress.Loopback, "tgs_integration_test_tactics2=1", IntegrationTest.DDPort, cancellationToken); + var bridgeTestTopicResult = await TopicClient.SendTopic(IPAddress.Loopback, "tgs_integration_test_tactics2=1", TestLiveServer.DDPort, cancellationToken); Assert.AreEqual("ack2", bridgeTestTopicResult.StringData); await bridgeTestsTcs.Task.WithToken(cancellationToken); @@ -436,7 +437,7 @@ namespace Tgstation.Server.Tests.Instance topicRequestResult = await TopicClient.SendTopic( IPAddress.Loopback, $"tgs_integration_test_tactics3={TopicClient.SanitizeString(JsonConvert.SerializeObject(topic, DMApiConstants.SerializerSettings))}", - IntegrationTest.DDPort, + TestLiveServer.DDPort, cancellationToken); } catch (ArgumentOutOfRangeException) @@ -474,7 +475,7 @@ namespace Tgstation.Server.Tests.Instance var topicRequestResult = await TopicClient.SendTopic( IPAddress.Loopback, $"tgs_integration_test_tactics4={TopicClient.SanitizeString(currentSize.ToString())}", - IntegrationTest.DDPort, + TestLiveServer.DDPort, cancellationToken); if (topicRequestResult.ResponseType != TopicResponseType.StringResponse @@ -522,7 +523,7 @@ namespace Tgstation.Server.Tests.Instance var embedsResponseTask = ((WatchdogBase)instanceReference.Watchdog).HandleChatCommand( "embeds_test", - String.Empty, + string.Empty, mockChatUser, cancellationToken); @@ -534,13 +535,13 @@ namespace Tgstation.Server.Tests.Instance var overloadResponseTask2 = ((WatchdogBase)instanceReference.Watchdog).HandleChatCommand( "response_overload_test", - String.Empty, + string.Empty, mockChatUser, cancellationToken); overloadResponse = await ((WatchdogBase)instanceReference.Watchdog).HandleChatCommand( "response_overload_test", - String.Empty, + string.Empty, mockChatUser, cancellationToken); @@ -591,7 +592,7 @@ namespace Tgstation.Server.Tests.Instance async Task RunLongRunningTestThenUpdate(CancellationToken cancellationToken) { - global::System.Console.WriteLine("TEST: WATCHDOG LONG RUNNING WITH UPDATE TEST"); + System.Console.WriteLine("TEST: WATCHDOG LONG RUNNING WITH UPDATE TEST"); const string DmeName = "LongRunning/long_running_test"; var daemonStatus = await DeployTestDme(DmeName, DreamDaemonSecurity.Trusted, true, cancellationToken); @@ -633,7 +634,7 @@ namespace Tgstation.Server.Tests.Instance async Task RunLongRunningTestThenUpdateWithNewDme(CancellationToken cancellationToken) { - global::System.Console.WriteLine("TEST: WATCHDOG LONG RUNNING WITH NEW DME TEST"); + System.Console.WriteLine("TEST: WATCHDOG LONG RUNNING WITH NEW DME TEST"); const string DmeName = "LongRunning/long_running_test"; var daemonStatus = await DeployTestDme(DmeName, DreamDaemonSecurity.Trusted, true, cancellationToken); @@ -675,7 +676,7 @@ namespace Tgstation.Server.Tests.Instance async Task RunLongRunningTestThenUpdateWithByondVersionSwitch(CancellationToken cancellationToken) { - global::System.Console.WriteLine("TEST: WATCHDOG BYOND VERSION UPDATE TEST"); + System.Console.WriteLine("TEST: WATCHDOG BYOND VERSION UPDATE TEST"); var versionToInstall = ByondTest.TestVersion; versionToInstall = versionToInstall.Semver(); @@ -730,7 +731,7 @@ namespace Tgstation.Server.Tests.Instance public async Task StartAndLeaveRunning(CancellationToken cancellationToken) { - global::System.Console.WriteLine("TEST: WATCHDOG STARTING ENDLESS"); + System.Console.WriteLine("TEST: WATCHDOG STARTING ENDLESS"); var dd = await instanceClient.DreamDaemon.Read(cancellationToken); if (dd.ActiveCompileJob == null) await DeployTestDme("LongRunning/long_running_test", DreamDaemonSecurity.Trusted, true, cancellationToken); @@ -741,7 +742,7 @@ namespace Tgstation.Server.Tests.Instance var daemonStatus = await instanceClient.DreamDaemon.Read(cancellationToken); Assert.AreEqual(WatchdogStatus.Online, daemonStatus.Status.Value); - Assert.AreEqual(IntegrationTest.DDPort, daemonStatus.CurrentPort); + Assert.AreEqual(TestLiveServer.DDPort, daemonStatus.CurrentPort); // Try killing the DD process to ensure it gets set to the restoring state do @@ -772,7 +773,7 @@ namespace Tgstation.Server.Tests.Instance static bool KillDD(bool require) { var ddProcs = System.Diagnostics.Process.GetProcessesByName("DreamDaemon").Where(x => !x.HasExited).ToList(); - if ((require && ddProcs.Count == 0) || ddProcs.Count > 1) + if (require && ddProcs.Count == 0 || ddProcs.Count > 1) Assert.Fail($"Incorrect number of DD processes: {ddProcs.Count}"); using var ddProc = ddProcs.SingleOrDefault(); @@ -782,7 +783,7 @@ namespace Tgstation.Server.Tests.Instance return ddProc != null; } - public static readonly TopicClient TopicClient = new (new SocketParameters + public static readonly TopicClient TopicClient = new(new SocketParameters { SendTimeout = TimeSpan.FromSeconds(30), ReceiveTimeout = TimeSpan.FromSeconds(30), @@ -798,7 +799,7 @@ namespace Tgstation.Server.Tests.Instance try { System.Console.WriteLine("TEST: Sending world reboot topic..."); - var result = await TopicClient.SendTopic(IPAddress.Loopback, "tgs_integration_test_special_tactics=1", IntegrationTest.DDPort, cancellationToken); + var result = await TopicClient.SendTopic(IPAddress.Loopback, "tgs_integration_test_special_tactics=1", TestLiveServer.DDPort, cancellationToken); Assert.AreEqual("ack", result.StringData); using (var tempCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) @@ -868,7 +869,7 @@ namespace Tgstation.Server.Tests.Instance }, cancellationToken); var newStatus = await instanceClient.DreamDaemon.Read(cancellationToken); - Assert.IsTrue(newStatus.SoftShutdown.Value || (newStatus.Status.Value == WatchdogStatus.Offline)); + Assert.IsTrue(newStatus.SoftShutdown.Value || newStatus.Status.Value == WatchdogStatus.Offline); do { diff --git a/tests/Tgstation.Server.Tests/InstanceManagerTest.cs b/tests/Tgstation.Server.Tests/Live/InstanceManagerTest.cs similarity index 98% rename from tests/Tgstation.Server.Tests/InstanceManagerTest.cs rename to tests/Tgstation.Server.Tests/Live/InstanceManagerTest.cs index 1f21d41eff..99125b5606 100644 --- a/tests/Tgstation.Server.Tests/InstanceManagerTest.cs +++ b/tests/Tgstation.Server.Tests/Live/InstanceManagerTest.cs @@ -19,7 +19,7 @@ using Tgstation.Server.Api.Rights; using Tgstation.Server.Client; using Tgstation.Server.Host.Controllers; -namespace Tgstation.Server.Tests +namespace Tgstation.Server.Tests.Live { sealed class InstanceManagerTest { @@ -33,8 +33,8 @@ namespace Tgstation.Server.Tests public InstanceManagerTest(IServerClient serverClient, string testRootPath) { this.serverClient = serverClient ?? throw new ArgumentNullException(nameof(serverClient)); - this.instanceManagerClient = serverClient.Instances; - this.usersClient = serverClient.Users; + instanceManagerClient = serverClient.Instances; + usersClient = serverClient.Users; this.testRootPath = testRootPath ?? throw new ArgumentNullException(nameof(testRootPath)); } @@ -46,7 +46,7 @@ namespace Tgstation.Server.Tests ChatBotLimit = 2 }, cancellationToken); - static TRequestType FromResponse(InstanceResponse response) where TRequestType : Api.Models.Instance, new() => new () + static TRequestType FromResponse(InstanceResponse response) where TRequestType : Api.Models.Instance, new() => new() { Id = response.Id, Path = response.Path, @@ -181,7 +181,7 @@ namespace Tgstation.Server.Tests var token = serverClient.Token.Bearer; // check that 400s are returned appropriately using var httpClient = new HttpClient(); - using var request = new HttpRequestMessage(HttpMethod.Get, String.Concat(url.ToString(), Routes.ListRoute(Routes.InstanceManager).AsSpan(1), "?pageSize=2")); + using var request = new HttpRequestMessage(HttpMethod.Get, string.Concat(url.ToString(), Routes.ListRoute(Routes.InstanceManager).AsSpan(1), "?pageSize=2")); request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RegressionTest1256", "1.0.0")); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); diff --git a/tests/Tgstation.Server.Tests/TestingServer.cs b/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs similarity index 77% rename from tests/Tgstation.Server.Tests/TestingServer.cs rename to tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs index f1269adce9..fb54b3696b 100644 --- a/tests/Tgstation.Server.Tests/TestingServer.cs +++ b/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs @@ -13,9 +13,9 @@ using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.Core; using Tgstation.Server.Host.Setup; -namespace Tgstation.Server.Tests +namespace Tgstation.Server.Tests.Live { - sealed class TestingServer : IServer, IDisposable + sealed class LiveTestingServer : IServer, IDisposable { public Uri Url { get; } @@ -34,10 +34,10 @@ namespace Tgstation.Server.Tests public IServer RealServer { get; private set; } - public TestingServer(SwarmConfiguration swarmConfiguration, bool enableOAuth, ushort port = 5010) + public LiveTestingServer(SwarmConfiguration swarmConfiguration, bool enableOAuth, ushort port = 5010) { Directory = Environment.GetEnvironmentVariable("TGS_TEST_TEMP_DIRECTORY"); - if (String.IsNullOrWhiteSpace(Directory)) + if (string.IsNullOrWhiteSpace(Directory)) { Directory = Path.Combine(Path.GetTempPath(), "TGS_INTEGRATION_TEST"); if (System.IO.Directory.Exists(Directory) && swarmConfiguration == null) @@ -61,32 +61,32 @@ namespace Tgstation.Server.Tests var gitHubAccessToken = Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"); var dumpOpenAPISpecPathEnvVar = Environment.GetEnvironmentVariable("TGS_TEST_DUMP_API_SPEC"); - if (String.IsNullOrEmpty(DatabaseType)) + if (string.IsNullOrEmpty(DatabaseType)) Assert.Inconclusive("No database type configured in env var TGS_TEST_DATABASE_TYPE!"); - if (String.IsNullOrEmpty(connectionString)) + if (string.IsNullOrEmpty(connectionString)) Assert.Inconclusive("No connection string configured in env var TGS_TEST_CONNECTION_STRING!"); - if (String.IsNullOrEmpty(gitHubAccessToken)) + if (string.IsNullOrEmpty(gitHubAccessToken)) Console.WriteLine("WARNING: No GitHub access token configured, test may fail due to rate limits!"); - DumpOpenApiSpecpath = !String.IsNullOrEmpty(dumpOpenAPISpecPathEnvVar); + DumpOpenApiSpecpath = !string.IsNullOrEmpty(dumpOpenAPISpecPathEnvVar); args = new List() { - String.Format(CultureInfo.InvariantCulture, "Database:DropDatabase={0}", true), // Replaced after first Run - 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), - String.Format(CultureInfo.InvariantCulture, "General:MinimumPasswordLength={0}", 10), - String.Format(CultureInfo.InvariantCulture, "General:InstanceLimit={0}", 11), - String.Format(CultureInfo.InvariantCulture, "General:UserLimit={0}", 150), - String.Format(CultureInfo.InvariantCulture, "General:UserGroupLimit={0}", 47), - String.Format(CultureInfo.InvariantCulture, "General:HostApiDocumentation={0}", DumpOpenApiSpecpath), - String.Format(CultureInfo.InvariantCulture, "FileLogging:Directory={0}", Path.Combine(Directory, "Logs")), - String.Format(CultureInfo.InvariantCulture, "FileLogging:LogLevel={0}", "Trace"), - String.Format(CultureInfo.InvariantCulture, "General:ValidInstancePaths:0={0}", Directory), + string.Format(CultureInfo.InvariantCulture, "Database:DropDatabase={0}", true), // Replaced after first Run + 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), + string.Format(CultureInfo.InvariantCulture, "General:MinimumPasswordLength={0}", 10), + string.Format(CultureInfo.InvariantCulture, "General:InstanceLimit={0}", 11), + string.Format(CultureInfo.InvariantCulture, "General:UserLimit={0}", 150), + string.Format(CultureInfo.InvariantCulture, "General:UserGroupLimit={0}", 47), + string.Format(CultureInfo.InvariantCulture, "General:HostApiDocumentation={0}", DumpOpenApiSpecpath), + string.Format(CultureInfo.InvariantCulture, "FileLogging:Directory={0}", Path.Combine(Directory, "Logs")), + string.Format(CultureInfo.InvariantCulture, "FileLogging:LogLevel={0}", "Trace"), + string.Format(CultureInfo.InvariantCulture, "General:ValidInstancePaths:0={0}", Directory), "General:ByondTopicTimeout=3000" }; @@ -112,8 +112,8 @@ namespace Tgstation.Server.Tests File.Delete("appsettings.Development.yml"); File.Delete("appsettings.Development.json"); - if (!String.IsNullOrEmpty(gitHubAccessToken)) - args.Add(String.Format(CultureInfo.InvariantCulture, "General:GitHubAccessToken={0}", gitHubAccessToken)); + if (!string.IsNullOrEmpty(gitHubAccessToken)) + args.Add(string.Format(CultureInfo.InvariantCulture, "General:GitHubAccessToken={0}", gitHubAccessToken)); if (DumpOpenApiSpecpath) Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); @@ -130,7 +130,7 @@ namespace Tgstation.Server.Tests } catch { - GC.Collect(Int32.MaxValue, GCCollectionMode.Forced, false); + GC.Collect(int.MaxValue, GCCollectionMode.Forced, false); Thread.Sleep(3000); } } @@ -174,7 +174,7 @@ namespace Tgstation.Server.Tests cancellationToken); if (firstRun) - args[0] = String.Format(CultureInfo.InvariantCulture, "Database:DropDatabase={0}", false); + args[0] = string.Format(CultureInfo.InvariantCulture, "Database:DropDatabase={0}", false); await RealServer.Run(cancellationToken); Console.WriteLine("TEST SERVER END"); diff --git a/tests/Tgstation.Server.Tests/RawRequestTests.cs b/tests/Tgstation.Server.Tests/Live/RawRequestTests.cs similarity index 96% rename from tests/Tgstation.Server.Tests/RawRequestTests.cs rename to tests/Tgstation.Server.Tests/Live/RawRequestTests.cs index 61c5260d58..02884dac07 100644 --- a/tests/Tgstation.Server.Tests/RawRequestTests.cs +++ b/tests/Tgstation.Server.Tests/Live/RawRequestTests.cs @@ -16,7 +16,7 @@ using Tgstation.Server.Api.Models.Response; using Tgstation.Server.Client; using Tgstation.Server.Host; -namespace Tgstation.Server.Tests +namespace Tgstation.Server.Tests.Live { static class RawRequestTests { @@ -82,7 +82,7 @@ namespace Tgstation.Server.Tests Assert.AreEqual(ErrorCode.ApiMismatch, message.ErrorCode); } - using (var request = new HttpRequestMessage(HttpMethod.Get, String.Concat(url.ToString(), Routes.Administration.AsSpan(1)))) + using (var request = new HttpRequestMessage(HttpMethod.Get, string.Concat(url.ToString(), Routes.Administration.AsSpan(1)))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); @@ -96,7 +96,7 @@ namespace Tgstation.Server.Tests Assert.AreEqual(ErrorCode.ApiMismatch, message.ErrorCode); } - using (var request = new HttpRequestMessage(HttpMethod.Post, String.Concat(url.ToString(), Routes.Administration.AsSpan(1)))) + using (var request = new HttpRequestMessage(HttpMethod.Post, string.Concat(url.ToString(), Routes.Administration.AsSpan(1)))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); @@ -114,7 +114,7 @@ namespace Tgstation.Server.Tests Assert.AreEqual(ErrorCode.ModelValidationFailure, message.ErrorCode); } - using (var request = new HttpRequestMessage(HttpMethod.Post, String.Concat(url.ToString(), Routes.DreamDaemon.AsSpan(1)))) + using (var request = new HttpRequestMessage(HttpMethod.Post, string.Concat(url.ToString(), Routes.DreamDaemon.AsSpan(1)))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); @@ -124,7 +124,7 @@ namespace Tgstation.Server.Tests Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode); } - using (var request = new HttpRequestMessage(HttpMethod.Post, String.Concat(url.ToString(), Routes.DreamDaemon.AsSpan(1)))) + using (var request = new HttpRequestMessage(HttpMethod.Post, string.Concat(url.ToString(), Routes.DreamDaemon.AsSpan(1)))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); @@ -238,7 +238,7 @@ namespace Tgstation.Server.Tests // check that 400s are returned appropriately using var httpClient = new HttpClient(); - using (var request = new HttpRequestMessage(HttpMethod.Get, String.Concat(url.ToString(), Routes.Transfer.AsSpan(1)))) + using (var request = new HttpRequestMessage(HttpMethod.Get, string.Concat(url.ToString(), Routes.Transfer.AsSpan(1)))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); @@ -253,7 +253,7 @@ namespace Tgstation.Server.Tests Assert.AreEqual(ErrorCode.ModelValidationFailure, message.ErrorCode); } - using (var request = new HttpRequestMessage(HttpMethod.Put, String.Concat(url.ToString(), Routes.Transfer.AsSpan(1)))) + using (var request = new HttpRequestMessage(HttpMethod.Put, string.Concat(url.ToString(), Routes.Transfer.AsSpan(1)))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); @@ -268,7 +268,7 @@ namespace Tgstation.Server.Tests Assert.AreEqual(ErrorCode.ModelValidationFailure, message.ErrorCode); } - using (var request = new HttpRequestMessage(HttpMethod.Get, String.Concat(url.ToString(), Routes.Transfer.AsSpan(1), "?ticket=veryfaketicket"))) + using (var request = new HttpRequestMessage(HttpMethod.Get, string.Concat(url.ToString(), Routes.Transfer.AsSpan(1), "?ticket=veryfaketicket"))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); @@ -280,7 +280,7 @@ namespace Tgstation.Server.Tests Assert.AreEqual(HttpStatusCode.NotAcceptable, response.StatusCode); } - using (var request = new HttpRequestMessage(HttpMethod.Get, String.Concat(url.ToString(), Routes.Transfer.AsSpan(1), "?ticket=veryfaketicket"))) + using (var request = new HttpRequestMessage(HttpMethod.Get, string.Concat(url.ToString(), Routes.Transfer.AsSpan(1), "?ticket=veryfaketicket"))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); @@ -293,7 +293,7 @@ namespace Tgstation.Server.Tests Assert.AreEqual(HttpStatusCode.Gone, response.StatusCode); } - using (var request = new HttpRequestMessage(HttpMethod.Put, String.Concat(url.ToString(), Routes.Transfer.AsSpan(1), "?ticket=veryfaketicket"))) + using (var request = new HttpRequestMessage(HttpMethod.Put, string.Concat(url.ToString(), Routes.Transfer.AsSpan(1), "?ticket=veryfaketicket"))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); @@ -315,7 +315,7 @@ namespace Tgstation.Server.Tests // check that 400s are returned appropriately using var httpClient = new HttpClient(); - using (var request = new HttpRequestMessage(HttpMethod.Get, String.Concat(url.ToString(), Routes.User.AsSpan(1)))) + using (var request = new HttpRequestMessage(HttpMethod.Get, string.Concat(url.ToString(), Routes.User.AsSpan(1)))) { request.Headers.Accept.Clear(); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0")); diff --git a/tests/Tgstation.Server.Tests/IntegrationTest.cs b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs similarity index 91% rename from tests/Tgstation.Server.Tests/IntegrationTest.cs rename to tests/Tgstation.Server.Tests/Live/TestLiveServer.cs index 323e820c83..d5337b2f0d 100644 --- a/tests/Tgstation.Server.Tests/IntegrationTest.cs +++ b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs @@ -1,14 +1,4 @@ -using Byond.TopicSender; - -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Newtonsoft.Json; -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -22,6 +12,14 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Newtonsoft.Json; + using Tgstation.Server.Api; using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Request; @@ -30,29 +28,59 @@ using Tgstation.Server.Api.Rights; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; using Tgstation.Server.Host.Components; -using Tgstation.Server.Host.Components.Events; -using Tgstation.Server.Host.Components.Repository; using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.Database; using Tgstation.Server.Host.Database.Migrations; using Tgstation.Server.Host.Extensions; -using Tgstation.Server.Host.IO; -using Tgstation.Server.Host.Jobs; using Tgstation.Server.Host.System; -using Tgstation.Server.Tests.Instance; +using Tgstation.Server.Tests.Live.Instance; -namespace Tgstation.Server.Tests +namespace Tgstation.Server.Tests.Live { [TestClass] [TestCategory("SkipWhenLiveUnitTesting")] - public sealed class IntegrationTest + public sealed class TestLiveServer { + public static ushort DDPort { get; } = FreeTcpPort(); + public static ushort DMPort { get; } = GetDMPort(); + readonly IServerClientFactory clientFactory = new ServerClientFactory(new ProductHeaderValue(Assembly.GetExecutingAssembly().GetName().Name, Assembly.GetExecutingAssembly().GetName().Version.ToString())); + static void TerminateAllDDs() + { + foreach (var proc in System.Diagnostics.Process.GetProcessesByName("DreamDaemon")) + using (proc) + proc.Kill(); + } + + static ushort GetDMPort() + { + ushort result; + do + { + result = FreeTcpPort(); + } while (result == DDPort); + return result; + } + + static ushort FreeTcpPort() + { + var l = new TcpListener(IPAddress.Loopback, 0); + l.Start(); + try + { + return (ushort)((IPEndPoint)l.LocalEndpoint).Port; + } + finally + { + l.Stop(); + } + } + [TestMethod] public async Task TestUpdateProtocolAndDisabledOAuth() { - using var server = new TestingServer(null, false); + using var server = new LiveTestingServer(null, false); using var serverCts = new CancellationTokenSource(); var cancellationToken = serverCts.Token; var serverTask = server.Run(cancellationToken); @@ -102,7 +130,7 @@ namespace Tgstation.Server.Tests } catch (RateLimitException ex) { - if (String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) + if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) throw; Assert.Inconclusive("GitHub rate limit hit: {0}", ex); @@ -129,12 +157,12 @@ namespace Tgstation.Server.Tests public async Task TestOneServerSwarmUpdate() { // cleanup existing directories - new TestingServer(null, false).Dispose(); + new LiveTestingServer(null, false).Dispose(); const string PrivateKey = "adlfj73ywifhks7iwrgfegjs"; var controllerAddress = new Uri("http://localhost:5011"); - using (var controller = new TestingServer(new SwarmConfiguration + using (var controller = new LiveTestingServer(new SwarmConfiguration { Address = controllerAddress, Identifier = "controller", @@ -175,7 +203,7 @@ namespace Tgstation.Server.Tests await Task.WhenAny(Task.Delay(TimeSpan.FromMinutes(2)), serverTask); Assert.IsTrue(serverTask.IsCompleted); - void CheckServerUpdated(TestingServer server) + void CheckServerUpdated(LiveTestingServer server) { Assert.IsTrue(Directory.Exists(server.UpdatePath), "Update directory not present!"); @@ -191,7 +219,7 @@ namespace Tgstation.Server.Tests } catch (RateLimitException ex) { - if (String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) + if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) throw; Assert.Inconclusive("GitHub rate limit hit: {0}", ex); @@ -203,13 +231,13 @@ namespace Tgstation.Server.Tests } } - new TestingServer(null, false).Dispose(); + new LiveTestingServer(null, false).Dispose(); } [TestMethod] public async Task TestCreateServerWithNoArguments() { - using var server = new TestingServer(null, false); + using var server = new LiveTestingServer(null, false); await server.RunNoArgumentsTest(default); } @@ -217,26 +245,26 @@ namespace Tgstation.Server.Tests public async Task TestSwarmSynchronizationAndUpdates() { // cleanup existing directories - new TestingServer(null, false).Dispose(); + new LiveTestingServer(null, false).Dispose(); const string PrivateKey = "adlfj73ywifhks7iwrgfegjs"; var controllerAddress = new Uri("http://localhost:5011"); - using (var controller = new TestingServer(new SwarmConfiguration + using (var controller = new LiveTestingServer(new SwarmConfiguration { Address = controllerAddress, Identifier = "controller", PrivateKey = PrivateKey }, false, 5011)) { - using var node1 = new TestingServer(new SwarmConfiguration + using var node1 = new LiveTestingServer(new SwarmConfiguration { Address = new Uri("http://localhost:5012"), ControllerAddress = controllerAddress, Identifier = "node1", PrivateKey = PrivateKey }, false, 5012); - using var node2 = new TestingServer(new SwarmConfiguration + using var node2 = new LiveTestingServer(new SwarmConfiguration { Address = new Uri("http://localhost:5013"), ControllerAddress = controllerAddress, @@ -365,7 +393,7 @@ namespace Tgstation.Server.Tests await Task.WhenAny(Task.Delay(TimeSpan.FromMinutes(2)), serverTask); Assert.IsTrue(serverTask.IsCompleted); - void CheckServerUpdated(TestingServer server) + void CheckServerUpdated(LiveTestingServer server) { Assert.IsTrue(Directory.Exists(server.UpdatePath), "Update directory not present!"); @@ -436,7 +464,7 @@ namespace Tgstation.Server.Tests } catch (RateLimitException ex) { - if (String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) + if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) throw; Assert.Inconclusive("GitHub rate limit hit: {0}", ex); @@ -448,33 +476,33 @@ namespace Tgstation.Server.Tests } } - new TestingServer(null, false).Dispose(); + new LiveTestingServer(null, false).Dispose(); } [TestMethod] public async Task TestSwarmReconnection() { // cleanup existing directories - new TestingServer(null, false).Dispose(); + new LiveTestingServer(null, false).Dispose(); const string PrivateKey = "adlfj73ywifhks7iwrgfegjs"; var controllerAddress = new Uri("http://localhost:5011"); - using (var controller = new TestingServer(new SwarmConfiguration + using (var controller = new LiveTestingServer(new SwarmConfiguration { Address = controllerAddress, Identifier = "controller", PrivateKey = PrivateKey }, false, 5011)) { - using var node1 = new TestingServer(new SwarmConfiguration + using var node1 = new LiveTestingServer(new SwarmConfiguration { Address = new Uri("http://localhost:5012"), ControllerAddress = controllerAddress, Identifier = "node1", PrivateKey = PrivateKey }, false, 5012); - using var node2 = new TestingServer(new SwarmConfiguration + using var node2 = new LiveTestingServer(new SwarmConfiguration { Address = new Uri("http://localhost:5013"), ControllerAddress = controllerAddress, @@ -633,7 +661,7 @@ namespace Tgstation.Server.Tests } catch (RateLimitException ex) { - if (String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) + if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN"))) throw; Assert.Inconclusive("GitHub rate limit hit: {0}", ex); @@ -645,47 +673,7 @@ namespace Tgstation.Server.Tests } } - new TestingServer(null, false).Dispose(); - } - - static void TerminateAllDDs() - { - foreach (var proc in System.Diagnostics.Process.GetProcessesByName("DreamDaemon")) - using (proc) - proc.Kill(); - } - - async Task CreateAdminClient(Uri url, CancellationToken cancellationToken) - { - var giveUpAt = DateTimeOffset.UtcNow.AddMinutes(2); - for (var I = 1; ; ++I) - { - try - { - System.Console.WriteLine($"TEST: CreateAdminClient attempt {I}..."); - return await clientFactory.CreateFromLogin( - url, - DefaultCredentials.AdminUserName, - DefaultCredentials.DefaultAdminUserPassword, - attemptLoginRefresh: false, - cancellationToken: cancellationToken) - ; - } - catch (HttpRequestException) - { - //migrating, to be expected - if (DateTimeOffset.UtcNow > giveUpAt) - throw; - await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); - } - catch (ServiceUnavailableException) - { - // migrating, to be expected - if (DateTimeOffset.UtcNow > giveUpAt) - throw; - await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); - } - } + new LiveTestingServer(null, false).Dispose(); } [TestMethod] @@ -693,7 +681,7 @@ namespace Tgstation.Server.Tests { var connectionString = Environment.GetEnvironmentVariable("TGS_TEST_CONNECTION_STRING"); - if (String.IsNullOrEmpty(connectionString)) + if (string.IsNullOrEmpty(connectionString)) Assert.Inconclusive("No connection string configured in env var TGS_TEST_CONNECTION_STRING!"); var databaseTypeString = Environment.GetEnvironmentVariable("TGS_TEST_DATABASE_TYPE"); @@ -704,7 +692,7 @@ namespace Tgstation.Server.Tests DatabaseContext CreateContext() { string serverVersion = Environment.GetEnvironmentVariable($"{DatabaseConfiguration.Section}__{nameof(DatabaseConfiguration.ServerVersion)}"); - if (String.IsNullOrWhiteSpace(serverVersion)) + if (string.IsNullOrWhiteSpace(serverVersion)) serverVersion = null; switch (databaseType) { @@ -786,8 +774,8 @@ namespace Tgstation.Server.Tests Visibility = DreamDaemonVisibility.Public, StartupTimeout = 1000, TopicRequestTimeout = 1000, - AdditionalParameters = String.Empty, - StartProfiler = false, + AdditionalParameters = string.Empty, + StartProfiler = false, LogOutput = true, }, DreamMakerSettings = new Host.Models.DreamMakerSettings @@ -840,7 +828,7 @@ namespace Tgstation.Server.Tests } [TestMethod] - public async Task TestTgs() + public async Task TestStandardTgsOperation() { var procs = System.Diagnostics.Process.GetProcessesByName("byond"); if (procs.Any()) @@ -850,7 +838,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(null, true); + using var server = new LiveTestingServer(null, true); const int MaximumTestMinutes = 20; using var hardTimeoutCancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(MaximumTestMinutes)); @@ -979,7 +967,7 @@ namespace Tgstation.Server.Tests foreach (var job in jobs) { Assert.IsTrue(job.StartedAt.Value >= preStartupTime); - await jrt.WaitForJob(job, 130, job.Description.Contains("Reconnect chat bot") ? (bool?)null : (bool?)false, null, cancellationToken); + await jrt.WaitForJob(job, 130, job.Description.Contains("Reconnect chat bot") ? null : false, null, cancellationToken); } var dd = await instanceClient.DreamDaemon.Read(cancellationToken); @@ -1125,77 +1113,37 @@ namespace Tgstation.Server.Tests await serverTask; } - public static readonly ushort DDPort = FreeTcpPort(); - public static readonly ushort DMPort = GetDMPort(); - - static ushort GetDMPort() + async Task CreateAdminClient(Uri url, CancellationToken cancellationToken) { - ushort result; - do + var giveUpAt = DateTimeOffset.UtcNow.AddMinutes(2); + for (var I = 1; ; ++I) { - result = FreeTcpPort(); - } while (result == DDPort); - return result; - } - - static ushort FreeTcpPort() - { - var l = new TcpListener(IPAddress.Loopback, 0); - l.Start(); - try - { - return (ushort)((IPEndPoint)l.LocalEndpoint).Port; + try + { + System.Console.WriteLine($"TEST: CreateAdminClient attempt {I}..."); + return await clientFactory.CreateFromLogin( + url, + DefaultCredentials.AdminUserName, + DefaultCredentials.DefaultAdminUserPassword, + attemptLoginRefresh: false, + cancellationToken: cancellationToken) + ; + } + catch (HttpRequestException) + { + //migrating, to be expected + if (DateTimeOffset.UtcNow > giveUpAt) + throw; + await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); + } + catch (ServiceUnavailableException) + { + // migrating, to be expected + if (DateTimeOffset.UtcNow > giveUpAt) + throw; + await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); + } } - finally - { - l.Stop(); - } - } - - [TestMethod] - public async Task TestScriptExecution() - { - var platformIdentifier = new PlatformIdentifier(); - var processExecutor = new ProcessExecutor( - Mock.Of(), - Mock.Of(), - Mock.Of>(), - LoggerFactory.Create(x => { })); - - await using var process = await processExecutor.LaunchProcess("test." + platformIdentifier.ScriptFileExtension, ".", String.Empty, null, true, true); - using var cts = new CancellationTokenSource(); - cts.CancelAfter(3000); - var exitCode = await process.Lifetime.WithToken(cts.Token); - - Assert.AreEqual(0, exitCode); - Assert.AreEqual("Hello World!", (await process.GetCombinedOutput(default)).Trim()); - } - - [TestMethod] - public async Task TestRepoParentLookup() - { - 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 Repository( - libGit2Repo, - new LibGit2Commands(), - Mock.Of(), - Mock.Of(), - Mock.Of(), - Mock.Of(), - Mock.Of(), - Mock.Of>(), - () => { }); - - const string StartSha = "af4da8beb9f9b374b04a3cc4d65acca662e8cc1a"; - await repo.CheckoutObject(StartSha, null, null, true, new JobProgressReporter(Mock.Of>(), null, (stage, progress) => { }), default); - var result = await repo.ShaIsParent("2f8588a3ca0f6b027704a2a04381215619de3412", default); - Assert.IsTrue(result); - Assert.AreEqual(StartSha, repo.Head); - result = await repo.ShaIsParent("f636418bf47d238d33b0e4a34f0072b23a8aad0e", default); - Assert.IsFalse(result); - Assert.AreEqual(StartSha, repo.Head); } } } diff --git a/tests/Tgstation.Server.Tests/UsersTest.cs b/tests/Tgstation.Server.Tests/Live/UsersTest.cs similarity index 99% rename from tests/Tgstation.Server.Tests/UsersTest.cs rename to tests/Tgstation.Server.Tests/Live/UsersTest.cs index 1f006d5617..e83f7244c6 100644 --- a/tests/Tgstation.Server.Tests/UsersTest.cs +++ b/tests/Tgstation.Server.Tests/Live/UsersTest.cs @@ -12,7 +12,7 @@ using Tgstation.Server.Api.Rights; using Tgstation.Server.Client; using Tgstation.Server.Host.System; -namespace Tgstation.Server.Tests +namespace Tgstation.Server.Tests.Live { sealed class UsersTest { @@ -149,7 +149,7 @@ namespace Tgstation.Server.Tests UserUpdateRequest testUserUpdate = new UserCreateRequest { Name = "TestUserWithNoPassword", - Password = String.Empty + Password = string.Empty }; await ApiAssert.ThrowsException(() => serverClient.Users.Create((UserCreateRequest)testUserUpdate, cancellationToken), ErrorCode.UserPasswordLength); @@ -273,7 +273,7 @@ namespace Tgstation.Server.Tests await ApiAssert.ThrowsException(() => serverClient.Users.List( new PaginationSettings { - PageSize = Int32.MaxValue + PageSize = int.MaxValue }, cancellationToken), ErrorCode.ApiPageTooLarge); await serverClient.Users.List( diff --git a/tests/Tgstation.Server.Tests/TestRepository.cs b/tests/Tgstation.Server.Tests/TestRepository.cs new file mode 100644 index 0000000000..7366c43e44 --- /dev/null +++ b/tests/Tgstation.Server.Tests/TestRepository.cs @@ -0,0 +1,46 @@ +using System.Threading.Tasks; + +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Moq; + +using Tgstation.Server.Host.Components.Events; +using Tgstation.Server.Host.Components.Repository; +using Tgstation.Server.Host.IO; +using Tgstation.Server.Host.Jobs; +using Tgstation.Server.Tests.Live; + +namespace Tgstation.Server.Tests +{ + [TestClass] + public sealed class TestRepository + { + [TestMethod] + public async Task TestRepoParentLookup() + { + using var testingServer = new LiveTestingServer(null, false); + LibGit2Sharp.Repository.Clone("https://github.com/Cyberboss/test", testingServer.Directory); + var libGit2Repo = new LibGit2Sharp.Repository(testingServer.Directory); + using var repo = new Repository( + libGit2Repo, + new LibGit2Commands(), + Mock.Of(), + Mock.Of(), + Mock.Of(), + Mock.Of(), + Mock.Of(), + Mock.Of>(), + () => { }); + + const string StartSha = "af4da8beb9f9b374b04a3cc4d65acca662e8cc1a"; + await repo.CheckoutObject(StartSha, null, null, true, new JobProgressReporter(Mock.Of>(), null, (stage, progress) => { }), default); + var result = await repo.ShaIsParent("2f8588a3ca0f6b027704a2a04381215619de3412", default); + Assert.IsTrue(result); + Assert.AreEqual(StartSha, repo.Head); + result = await repo.ShaIsParent("f636418bf47d238d33b0e4a34f0072b23a8aad0e", default); + Assert.IsFalse(result); + Assert.AreEqual(StartSha, repo.Head); + } + } +} diff --git a/tests/Tgstation.Server.Tests/TestSystemInteraction.cs b/tests/Tgstation.Server.Tests/TestSystemInteraction.cs new file mode 100644 index 0000000000..2309e34486 --- /dev/null +++ b/tests/Tgstation.Server.Tests/TestSystemInteraction.cs @@ -0,0 +1,36 @@ +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +using Tgstation.Server.Host.Extensions; +using Tgstation.Server.Host.IO; +using Tgstation.Server.Host.System; + +namespace Tgstation.Server.Tests +{ + [TestClass] + public sealed class TestSystemInteraction + { + [TestMethod] + public async Task TestScriptExecution() + { + var platformIdentifier = new PlatformIdentifier(); + var processExecutor = new ProcessExecutor( + Mock.Of(), + Mock.Of(), + Mock.Of>(), + LoggerFactory.Create(x => { })); + + await using var process = await processExecutor.LaunchProcess("test." + platformIdentifier.ScriptFileExtension, ".", string.Empty, null, true, true); + using var cts = new CancellationTokenSource(); + cts.CancelAfter(3000); + var exitCode = await process.Lifetime.WithToken(cts.Token); + + Assert.AreEqual(0, exitCode); + Assert.AreEqual("Hello World!", (await process.GetCombinedOutput(default)).Trim()); + } + } +}