Skip to content

Commit

Permalink
Merge pull request #1678 from tgstation/HowTheFuckDidThisGetHere
Browse files Browse the repository at this point in the history
Delete accidentally added submodule. Adjust test timeouts. Add workstation test against /tg/code.
  • Loading branch information
Cyberboss authored Oct 20, 2023
2 parents 76fb1aa + c11afb5 commit d608107
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 4 deletions.
1 change: 0 additions & 1 deletion LinuxTestBed
Submodule LinuxTestBed deleted from 9865a4
2 changes: 1 addition & 1 deletion tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ await instanceClient.DreamDaemon.Update(new DreamDaemonRequest

await Task.WhenAny(ourProcessHandler.Lifetime, Task.Delay(TimeSpan.FromMinutes(1), cancellationToken));

var timeout = 20;
var timeout = 60;
DreamDaemonResponse ddStatus;
do
{
Expand Down
213 changes: 211 additions & 2 deletions tests/Tgstation.Server.Tests/Live/TestLiveServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Net.Mime;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -954,6 +955,216 @@ await Task.WhenAny(
new LiveTestingServer(null, false).Dispose();
}

[TestMethod]
public async Task TestTgstationInteractive() => await TestTgstation(true);

[TestMethod]
public async Task TestTgstationHeadless() => await TestTgstation(false);

async ValueTask TestTgstation(bool interactive)
{
// i'm only running this on dev machines, actions is too taxed
if (TestingUtils.RunningInGitHubActions)
Assert.Inconclusive("lol. lmao.");

var discordConnectionString = Environment.GetEnvironmentVariable("TGS_TEST_DISCORD_TOKEN");

var procs = System.Diagnostics.Process.GetProcessesByName("byond");
if (procs.Any())
{
foreach (var proc in procs)
proc.Dispose();

// Inconclusive and not fail because we don't want to unexpectedly kill a dev's BYOND.exe
Assert.Inconclusive("Cannot run server test because DreamDaemon will not start headless while the BYOND pager is running!");
}


using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Trace);
});
using var server = new LiveTestingServer(null, true);

TerminateAllDDs();

using var serverCts = new CancellationTokenSource();
var cancellationToken = serverCts.Token;
var serverTask = server.Run(cancellationToken);
try
{
using var adminClient = await CreateAdminClient(server.Url, cancellationToken);

var instanceManagerTest = new InstanceManagerTest(adminClient, server.Directory);
var instance = await instanceManagerTest.CreateTestInstance("TgTestInstance", cancellationToken);
var instanceClient = adminClient.Instances.CreateClient(instance);


var ddUpdateTask = instanceClient.DreamDaemon.Update(new DreamDaemonRequest
{
LogOutput = true,
}, cancellationToken);
var dmUpdateTask = instanceClient.DreamMaker.Update(new DreamMakerRequest
{
ApiValidationSecurityLevel = DreamDaemonSecurity.Trusted,
}, cancellationToken);

var ioManager = new Host.IO.DefaultIOManager();
var repoPath = ioManager.ConcatPath(instance.Path, "Repository");
var jobsTest = new JobsRequiredTest(instanceClient.Jobs);
var postWriteHandler = (Host.IO.IPostWriteHandler)(new PlatformIdentifier().IsWindows
? new Host.IO.WindowsPostWriteHandler()
: new Host.IO.PosixPostWriteHandler(loggerFactory.CreateLogger<Host.IO.PosixPostWriteHandler>()));
var localRepoPath = Environment.GetEnvironmentVariable("TGS_LOCAL_TG_REPO");
Task jobWaitTask;
if (!String.IsNullOrWhiteSpace(localRepoPath))
{
await ioManager.CopyDirectory(
Enumerable.Empty<string>(),
(src, dest) =>
{
if (postWriteHandler.NeedsPostWrite(src))
postWriteHandler.HandleWrite(dest);

return Task.CompletedTask;
},
ioManager.ConcatPath(
localRepoPath,
".git"),
ioManager.ConcatPath(
repoPath,
".git"),
null,
cancellationToken);

IProcessExecutor processExecutor = null;
processExecutor = new ProcessExecutor(
new PlatformIdentifier().IsWindows
? new WindowsProcessFeatures(loggerFactory.CreateLogger<WindowsProcessFeatures>())
: new PosixProcessFeatures(new Lazy<IProcessExecutor>(() => processExecutor), ioManager, loggerFactory.CreateLogger<PosixProcessFeatures>()),
ioManager,
loggerFactory.CreateLogger<ProcessExecutor>(),
loggerFactory);

async ValueTask RunGitCommand(string args)
{
await using var gitRemoteOriginFixProc = processExecutor.LaunchProcess(
"git",
repoPath,
args,
null,
true,
true);

int? exitCode;
using (cancellationToken.Register(gitRemoteOriginFixProc.Terminate))
exitCode = await gitRemoteOriginFixProc.Lifetime;

loggerFactory.CreateLogger("TgTest").LogInformation("git {args} output:{newLine}{output}",args, Environment.NewLine, await gitRemoteOriginFixProc.GetCombinedOutput(cancellationToken));
Assert.AreEqual(0, exitCode);
}

await RunGitCommand("remote set-url origin https://github.com/tgstation/tgstation");
await RunGitCommand("checkout -f master");
await RunGitCommand("reset --hard origin/master");

jobWaitTask = Task.CompletedTask;
}
else
{
var repoResponse = await instanceClient.Repository.Clone(new RepositoryCreateRequest
{
Origin = new Uri("https://github.com/tgstation/tgstation"),
}, cancellationToken);
jobWaitTask = jobsTest.WaitForJob(repoResponse.ActiveJob, 300, false, null, cancellationToken);
}

await Task.WhenAll(jobWaitTask, ddUpdateTask, dmUpdateTask);

var depsBytesTask = ioManager.ReadAllBytes(
ioManager.ConcatPath(repoPath, "dependencies.sh"),
cancellationToken);

var scriptsCopyTask = ioManager.CopyDirectory(
Enumerable.Empty<string>(),
(src, dest) =>
{
if (postWriteHandler.NeedsPostWrite(src))
postWriteHandler.HandleWrite(dest);

return Task.CompletedTask;
},
ioManager.ConcatPath(
repoPath,
"tools",
"tgs_scripts"),
ioManager.ConcatPath(
instance.Path,
"Configuration",
"EventScripts"),
null,
cancellationToken);

var dependenciesSh = Encoding.UTF8.GetString(await depsBytesTask);
var lines = dependenciesSh.Split("\n", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
const string MajorPrefix = "export BYOND_MAJOR=";
var major = Int32.Parse(lines.First(x => x.StartsWith(MajorPrefix)).Substring(MajorPrefix.Length));
const string MinorPrefix = "export BYOND_MINOR=";
var minor = Int32.Parse(lines.First(x => x.StartsWith(MinorPrefix)).Substring(MinorPrefix.Length));

var byondJob = await instanceClient.Byond.SetActiveVersion(new ByondVersionRequest
{
Version = new Version(major, minor)
}, null, cancellationToken);

var byondJobTask = jobsTest.WaitForJob(byondJob.InstallJob, 60, false, null, cancellationToken);

await Task.WhenAll(scriptsCopyTask, byondJobTask);

var compileJob = await instanceClient.DreamMaker.Compile(cancellationToken);

await jobsTest.WaitForJob(compileJob, 180, false, null, cancellationToken);

var startJob = await instanceClient.DreamDaemon.Start(cancellationToken);
await jobsTest.WaitForJob(startJob, 30, false, null, cancellationToken);

var compileJob2 = await instanceClient.DreamMaker.Compile(cancellationToken);

await jobsTest.WaitForJob(compileJob2, 360, false, null, cancellationToken);

if (interactive)
{
bool updated = false;
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);

var status = await instanceClient.DreamDaemon.Read(cancellationToken);

if (updated)
{
if (status.Status == WatchdogStatus.Offline)
break;
}
else if (status.StagedCompileJob == null)
{
updated = true;
await instanceClient.DreamDaemon.Update(new DreamDaemonRequest
{
SoftShutdown = true
}, cancellationToken);
}
}
}
}
finally
{
serverCts.Cancel();
await serverTask;
}
}

[TestMethod]
public async Task TestStandardTgsOperation()
{

Check failure on line 1170 in tests/Tgstation.Server.Tests/Live/TestLiveServer.cs

View workflow job for this annotation

GitHub Actions / Windows Live Tests (MySql, System, Debug)

TestStandardTgsOperation

Assert.ThrowsException failed. Threw exception TaskCanceledException, but exception ConflictException was expected. Exception Message: The operation was canceled. Stack Trace: at System.Net.Http.HttpClient.HandleFailure(Exception e, Boolean telemetryStarted, HttpResponseMessage response, CancellationTokenSource cts, CancellationToken cancellationToken, CancellationTokenSource pendingRequestsCts) at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken) at Tgstation.Server.Client.ApiClient.RunRequest[TResult](String route, HttpContent content, HttpMethod method, Nullable`1 instanceId, Boolean tokenRefresh, CancellationToken cancellationToken) in /_/src/Tgstation.Server.Client/ApiClient.cs:line 344 at Tgstation.Server.Tests.Live.RateLimitRetryingApiClient.RunRequest[TResult](String route, HttpContent content, HttpMethod method, Nullable`1 instanceId, Boolean tokenRefresh, CancellationToken cancellationToken) in D:\a\tgstation-server\tgstation-server\tests\Tgstation.Server.Tests\Live\RateLimitRetryingApiClient.cs:line 27 at Tgstation.Server.Client.ApiClient.RunRequest[TBody,TResult](String route, TBody body, HttpMethod method, Nullable`1 instanceId, Boolean tokenRefresh, CancellationToken cancellationToken) in /_/src/Tgstation.Server.Client/ApiClient.cs:line 456 at Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExceptionAsync[T](Func`1 action, String message, Object[] parameters) in /_/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs:line 292
Expand All @@ -969,9 +1180,7 @@ public async Task TestStandardTgsOperation()
}

using (var currentProcess = System.Diagnostics.Process.GetCurrentProcess())
{
Assert.AreEqual(ProcessPriorityClass.Normal, currentProcess.PriorityClass);
}

var maximumTestMinutes = TestingUtils.RunningInGitHubActions ? 90 : 20;
using var hardCancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(maximumTestMinutes));
Expand Down

0 comments on commit d608107

Please sign in to comment.