Merge pull request #1021 from tgstation/965-FixBrokenTests [DMDeploy][NugetDeploy]

Wrapping up v4.3.0
This commit is contained in:
Jordan Brown
2020-05-28 19:18:01 -04:00
committed by GitHub
34 changed files with 163 additions and 98 deletions
+8 -8
View File
@@ -102,6 +102,14 @@ jobs:
name: "Docker Build"
services:
- docker
- env:
- DoxGeneration=true
name: "Dox Generation"
addons:
apt:
packages:
- doxygen
- graphviz
- env:
- DoxGeneration=false
- DockerBuild=false
@@ -118,14 +126,6 @@ jobs:
packages:
- libc6-i386
- libstdc++6:i386
- env:
- DoxGeneration=true
name: "Dox Generation"
addons:
apt:
packages:
- doxygen
- graphviz
install:
- if [ $DoxGeneration = false ] && [ $DockerBuild = false ] && [ $DMAPI = true ]; then build/install_byond.sh; fi
+1 -1
View File
@@ -73,7 +73,7 @@ test_script:
- OpenCover.Console.exe -returntargetcode -register:user -target:"C:/Program Files/dotnet/dotnet.exe" -targetargs:"test -c %CONFIGURATION% --logger:trx;LogFileName=results.trx /p:DebugType=full tests/Tgstation.Server.Host.Watchdog.Tests/Tgstation.Server.Host.Watchdog.Tests.csproj" -filter:"+[Tgstation.Server*]* -[Tgstation.Server.Host.Watchdog.Tests*]*" -output:".\watchdog_coverage.xml" -oldstyle
- ps: $wc = New-Object 'System.Net.WebClient'
- ps: $wc.UploadFile("https://ci.appveyor.com/api/testresults/mstest/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\tests\Tgstation.Server.Host.Watchdog.Tests\TestResults\results.trx))
- OpenCover.Console.exe -returntargetcode -register:user -target:"C:/Program Files/dotnet/dotnet.exe" -targetargs:"test -c %CONFIGURATION% --logger:trx;LogFileName=results.trx /p:DebugType=full tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj" -filter:"+[Tgstation.Server*]* -[Tgstation.Server.Tests*]* -[Tgstation.Server.Host]Tgstation.Server.Host.Database.Migrations..*" -output:".\server_coverage.xml" -oldstyle
- OpenCover.Console.exe -returntargetcode -register:user -target:"C:/Program Files/dotnet/dotnet.exe" -targetargs:"test -c %CONFIGURATION% --logger:trx;LogFileName=results.trx --logger:console;noprogress=true /p:DebugType=full tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj" -filter:"+[Tgstation.Server*]* -[Tgstation.Server.Tests*]* -[Tgstation.Server.Host]Tgstation.Server.Host.Database.Migrations..*" -output:".\server_coverage.xml" -oldstyle
- ps: $wc = New-Object 'System.Net.WebClient'
- ps: $wc.UploadFile("https://ci.appveyor.com/api/testresults/mstest/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\tests\Tgstation.Server.Tests\TestResults\results.trx))
- lint-openapi -p -c build/OpenApiValidationSettings.json C:/swagger.json
+1 -1
View File
@@ -5,7 +5,7 @@
<TgsCoreVersion>4.3.0</TgsCoreVersion>
<TgsApiVersion>6.5.0</TgsApiVersion>
<TgsClientVersion>7.1.0</TgsClientVersion>
<TgsDmapiVersion>5.2.1</TgsDmapiVersion>
<TgsDmapiVersion>5.2.2</TgsDmapiVersion>
<TgsControlPanelVersion>0.4.0</TgsControlPanelVersion>
<TgsHostWatchdogVersion>1.1.0</TgsHostWatchdogVersion>
</PropertyGroup>
+1 -1
View File
@@ -10,7 +10,7 @@ cd tests/Tgstation.Server.Tests
dotnet build -c $CONFIG
$HOME/.dotnet/tools/coverlet bin/$CONFIG/netcoreapp3.1/Tgstation.Server.Tests.dll --target "dotnet" --targetargs "test -c $CONFIG --no-build" --format opencover --output "../../TestResults/integration_test.xml" --include "[Tgstation.Server*]*" --exclude "[Tgstation.Server.Tests*]*" --exclude "[Tgstation.Server.Host]Tgstation.Server.Host.Database.Migrations.*"
$HOME/.dotnet/tools/coverlet bin/$CONFIG/netcoreapp3.1/Tgstation.Server.Tests.dll --target "dotnet" --targetargs "test -c $CONFIG --no-build --logger:\"console;noprogress=true\"" --format opencover --output "../../TestResults/integration_test.xml" --include "[Tgstation.Server*]*" --exclude "[Tgstation.Server.Tests*]*" --exclude "[Tgstation.Server.Host]Tgstation.Server.Host.Database.Migrations.*"
cd ../../TestResults
+2 -1
View File
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
#define TGS_DMAPI_VERSION "5.2.1"
#define TGS_DMAPI_VERSION "5.2.2"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -127,6 +127,7 @@
* Call this when your initializations are complete and your game is ready to play before any player interactions happen.
*
* This may use [/world/var/sleep_offline] to make this happen so ensure no changes are made to it while this call is running.
* Afterwards, consider explicitly setting it to what you want to avoid this BYOND bug: http://www.byond.com/forum/post/2575184
* Before this point, note that any static files or directories may be in use by another server. Your code should account for this.
* This function should not be called before ..() in [/world/proc/New].
*/
+3 -1
View File
@@ -114,12 +114,14 @@
/datum/tgs_api/v4/OnInitializationComplete()
Export(TGS4_COMM_SERVER_PRIMED)
var/tgs4_secret_sleep_offline_sauce = 24051994
var/tgs4_secret_sleep_offline_sauce = 29051994
var/old_sleep_offline = world.sleep_offline
world.sleep_offline = tgs4_secret_sleep_offline_sauce
sleep(1)
if(world.sleep_offline == tgs4_secret_sleep_offline_sauce) //if not someone changed it
world.sleep_offline = old_sleep_offline
else
TGS_WARNING_LOG("world.sleep_offline unexpectedly changed!")
/datum/tgs_api/v4/OnTopic(T)
var/list/params = params2list(T)
+3 -1
View File
@@ -16,7 +16,7 @@
var/list/chat_channels
/datum/tgs_api/v5/ApiVersion()
return new /datum/tgs_version("5.2.1")
return new /datum/tgs_version("5.2.2")
/datum/tgs_api/v5/OnWorldNew(minimum_required_security_level)
server_port = world.params[DMAPI5_PARAM_SERVER_PORT]
@@ -94,6 +94,8 @@
sleep(1)
if(world.sleep_offline == tgs4_secret_sleep_offline_sauce) //if not someone changed it
world.sleep_offline = old_sleep_offline
else
TGS_WARNING_LOG("world.sleep_offline unexpectedly changed!")
/datum/tgs_api/v5/proc/TopicResponse(error_message = null)
var/list/response = list()
@@ -33,7 +33,7 @@ namespace Tgstation.Server.Host.Components.Interop
/// <summary>
/// The DMAPI <see cref="Version"/> being used.
/// </summary>
public static readonly Version Version = new Version(5, 2, 1);
public static readonly Version Version = new Version(5, 2, 2);
/// <summary>
/// <see cref="JsonSerializerSettings"/> for use when communicating with the DMAPI.
@@ -192,7 +192,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
};
/// <inheritdoc />
protected override void DisposeAndNullControllers()
protected override void DisposeAndNullControllersImpl()
{
Server?.Dispose();
Server = null;
@@ -392,10 +392,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
}
#pragma warning restore CA1502
/// <summary>
/// Call <see cref="IDisposable.Dispose"/> on <see cref="alphaServer"/> and <see cref="bravoServer"/> and set them to <see langword="null"/>
/// </summary>
protected override void DisposeAndNullControllers()
/// <inheritdoc />
protected override void DisposeAndNullControllersImpl()
{
alphaServer?.Dispose();
alphaServer = null;
@@ -112,6 +112,11 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// </summary>
readonly IRestartRegistration restartRegistration;
/// <summary>
/// <see langword="lock"/> <see cref="object"/> used for <see cref="DisposeAndNullControllers"/>.
/// </summary>
readonly object controllerDisposeLock;
/// <summary>
/// If the <see cref="WatchdogBase"/> should <see cref="LaunchImplNoLock(bool, bool, DualReattachInformation, CancellationToken)"/> in <see cref="StartAsync(CancellationToken)"/>
/// </summary>
@@ -201,6 +206,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
ActiveLaunchParameters = initialLaunchParameters;
releaseServers = false;
ActiveParametersUpdated = new TaskCompletionSource<object>();
controllerDisposeLock = new object();
restartRegistration = serverControl.RegisterForRestart(this);
try
@@ -463,7 +469,16 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// <summary>
/// Call <see cref="IDisposable.Dispose"/> and null the fields for all <see cref="ISessionController"/>s and set <see cref="Running"/> to <see langword="false"/>.
/// </summary>
protected abstract void DisposeAndNullControllers();
protected abstract void DisposeAndNullControllersImpl();
/// <summary>
/// Wrapper for <see cref="DisposeAndNullControllersImpl"/> under a locked context.
/// </summary>
protected void DisposeAndNullControllers()
{
lock (controllerDisposeLock)
DisposeAndNullControllersImpl();
}
/// <summary>
/// Get the active <see cref="ISessionController"/>.
@@ -101,9 +101,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
}
/// <inheritdoc />
protected override void DisposeAndNullControllers()
protected override void DisposeAndNullControllersImpl()
{
base.DisposeAndNullControllers();
base.DisposeAndNullControllersImpl();
// If we reach this point, we can guarantee PrepServerForLaunch will be called before starting again.
activeSwappable = null;
@@ -4,7 +4,7 @@ using Newtonsoft.Json.Converters;
namespace Tgstation.Server.Host.Configuration
{
/// <summary>
/// Configuration options for the <see cref="Database.DatabaseContext{TParentContext}"/>
/// Configuration options for the <see cref="Database.DatabaseContext"/>
/// </summary>
sealed class DatabaseConfiguration
{
@@ -42,7 +42,7 @@ namespace Tgstation.Server.Host.Configuration
/// <summary>
/// The default value for <see cref="RestartTimeout"/>
/// </summary>
const int DefaultRestartTimeout = 10000;
const int DefaultRestartTimeout = 60000;
/// <summary>
/// The port the TGS API listens on.
@@ -163,7 +163,7 @@ namespace Tgstation.Server.Host.Controllers
if (ApiHeaders != null)
Logger.LogDebug(
"Request made by User ID {0}. Api version: {1}. User-Agent: {2}. Type: {3}. Route {4}{5} to Instance {6}",
"Request details: User ID {0}. Api version: {1}. User-Agent: {2}. Type: {3}. Route {4}{5} to Instance {6}",
AuthenticationContext?.User.Id.Value.ToString(CultureInfo.InvariantCulture),
ApiHeaders.ApiVersion.Semver(),
ApiHeaders.RawUserAgent,
@@ -202,7 +202,7 @@ namespace Tgstation.Server.Host.Core
// CORS conditionally enabled later
services.AddCors();
void AddTypedContext<TContext>() where TContext : DatabaseContext<TContext>
void AddTypedContext<TContext>() where TContext : DatabaseContext
{
services.AddDbContext<TContext>(builder =>
{
@@ -357,6 +357,8 @@ namespace Tgstation.Server.Host.Core
// Final point where we wrap exceptions in a 500 (ErrorMessage) response
applicationBuilder.UseServerErrorHandling();
applicationBuilder.UseRequestCounting();
// 503 requests made while the application is starting
applicationBuilder.UseAsyncInitialization(async (cancellationToken) =>
{
@@ -18,95 +18,94 @@ namespace Tgstation.Server.Host.Database
/// <summary>
/// Backend abstract implementation of <see cref="IDatabaseContext"/>
/// </summary>
/// <typeparam name="TParentContext">The child <see cref="Type"/> used to implement a backend.</typeparam>
#pragma warning disable CA1506 // TODO: Decomplexify
abstract class DatabaseContext<TParentContext> : DbContext, IDatabaseContext where TParentContext : DbContext
abstract class DatabaseContext : DbContext, IDatabaseContext
{
/// <inheritdoc />
public DatabaseType DatabaseType => DatabaseConfiguration.DatabaseType;
/// <summary>
/// The <see cref="User"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="User"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<User> Users { get; set; }
/// <summary>
/// The <see cref="Instance"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="Instance"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<Instance> Instances { get; set; }
/// <summary>
/// The <see cref="CompileJob"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="CompileJob"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<CompileJob> CompileJobs { get; set; }
/// <summary>
/// The <see cref="RevisionInformation"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="RevisionInformation"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<RevisionInformation> RevisionInformations { get; set; }
/// <summary>
/// The <see cref="Models.DreamMakerSettings"/> in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="Models.DreamMakerSettings"/> in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<DreamMakerSettings> DreamMakerSettings { get; set; }
/// <summary>
/// The <see cref="ChatBot"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="ChatBot"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<ChatBot> ChatBots { get; set; }
/// <summary>
/// The <see cref="Models.DreamDaemonSettings"/> in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="Models.DreamDaemonSettings"/> in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<DreamDaemonSettings> DreamDaemonSettings { get; set; }
/// <summary>
/// The <see cref="Models.RepositorySettings"/> in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="Models.RepositorySettings"/> in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<RepositorySettings> RepositorySettings { get; set; }
/// <summary>
/// The <see cref="InstanceUser"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="InstanceUser"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<InstanceUser> InstanceUsers { get; set; }
/// <summary>
/// The <see cref="ChatChannel"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="ChatChannel"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<ChatChannel> ChatChannels { get; set; }
/// <summary>
/// The <see cref="Job"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="Job"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<Job> Jobs { get; set; }
/// <summary>
/// The <see cref="ReattachInformation"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="ReattachInformation"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<ReattachInformation> ReattachInformations { get; set; }
/// <summary>
/// The <see cref="DualReattachInformation"/>s in the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="DualReattachInformation"/>s in the <see cref="DatabaseContext"/>.
/// </summary>
public DbSet<DualReattachInformation> WatchdogReattachInformations { get; set; }
/// <summary>
/// The <see cref="TestMerge"/>s in the <see cref="DatabaseContext{TParentContext}"/>
/// The <see cref="TestMerge"/>s in the <see cref="DatabaseContext"/>
/// </summary>
public DbSet<TestMerge> TestMerges { get; set; }
/// <summary>
/// The <see cref="RevInfoTestMerge"/>s om the <see cref="DatabaseContext{TParentContext}"/>
/// The <see cref="RevInfoTestMerge"/>s om the <see cref="DatabaseContext"/>
/// </summary>
public DbSet<RevInfoTestMerge> RevInfoTestMerges { get; set; }
/// <summary>
/// The <see cref="ILogger"/> for the <see cref="DatabaseContext{TParentContext}"/>
/// The <see cref="ILogger"/> for the <see cref="DatabaseContext"/>
/// </summary>
protected ILogger Logger { get; }
/// <summary>
/// The <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext{TParentContext}"/>
/// The <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext"/>
/// </summary>
protected DatabaseConfiguration DatabaseConfiguration { get; }
@@ -150,7 +149,7 @@ namespace Tgstation.Server.Host.Database
IDatabaseCollection<DualReattachInformation> IDatabaseContext.WatchdogReattachInformations => watchdogReattachInformationsCollection;
/// <summary>
/// The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext{TParentContext}"/>
/// The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext"/>
/// </summary>
readonly IDatabaseSeeder databaseSeeder;
@@ -220,13 +219,13 @@ namespace Tgstation.Server.Host.Database
readonly IDatabaseCollection<DualReattachInformation> watchdogReattachInformationsCollection;
/// <summary>
/// Construct a <see cref="DatabaseContext{TParentContext}"/>
/// Construct a <see cref="DatabaseContext"/>
/// </summary>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TParentContext}"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="dbContextOptions">The <see cref="DbContextOptions"/> for the <see cref="DatabaseContext"/>.</param>
/// <param name="databaseConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="DatabaseConfiguration"/></param>
/// <param name="databaseSeeder">The value of <see cref="databaseSeeder"/></param>
/// <param name="logger">The value of <see cref="Logger"/></param>
public DatabaseContext(DbContextOptions<TParentContext> dbContextOptions, IOptions<DatabaseConfiguration> databaseConfigurationOptions, IDatabaseSeeder databaseSeeder, ILogger logger) : base(dbContextOptions)
public DatabaseContext(DbContextOptions dbContextOptions, IOptions<DatabaseConfiguration> databaseConfigurationOptions, IDatabaseSeeder databaseSeeder, ILogger logger) : base(dbContextOptions)
{
DatabaseConfiguration = databaseConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(databaseConfigurationOptions));
this.databaseSeeder = databaseSeeder ?? throw new ArgumentNullException(nameof(databaseSeeder));
@@ -410,7 +409,7 @@ namespace Tgstation.Server.Host.Database
}
/// <summary>
/// Ensure the <see cref="DatabaseType"/> is correct for the <see cref="DatabaseContext{TParentContext}"/>.
/// Ensure the <see cref="DatabaseType"/> is correct for the <see cref="DatabaseContext"/>.
/// </summary>
protected abstract void ValidateDatabaseType();
}
@@ -14,12 +14,12 @@ namespace Tgstation.Server.Host.Database
sealed class DatabaseSeeder : IDatabaseSeeder
{
/// <summary>
/// The <see cref="ICryptographySuite"/> for the <see cref="DatabaseContext{TParentContext}"/>
/// The <see cref="ICryptographySuite"/> for the <see cref="DatabaseSeeder"/>
/// </summary>
readonly ICryptographySuite cryptographySuite;
/// <summary>
/// The <see cref="IPlatformIdentifier"/> for the <see cref="DatabaseContext{TParentContext}"/>.
/// The <see cref="IPlatformIdentifier"/> for the <see cref="DatabaseSeeder"/>.
/// </summary>
readonly IPlatformIdentifier platformIdentifier;
@@ -4,7 +4,7 @@ using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Host.Database.Design
{
/// <summary>
/// Contains helpers for creating design time <see cref="DatabaseContext{TParentContext}"/>s
/// Contains helpers for creating design time <see cref="DatabaseContext"/>s
/// </summary>
static class DesignTimeDbContextFactoryHelpers
{
@@ -14,7 +14,7 @@ namespace Tgstation.Server.Host.Database.Design
/// <param name="databaseType">The <see cref="DatabaseConfiguration.DatabaseType"/>.</param>
/// <param name="connectionString">The <see cref="DatabaseConfiguration.ConnectionString"/>.</param>
/// <returns>The <see cref="IOptions{TOptions}"/> for the <see cref="DatabaseConfiguration"/></returns>
public static IOptions<DatabaseConfiguration> GetDbContextOptions(DatabaseType databaseType, string connectionString)
public static IOptions<DatabaseConfiguration> GetDatabaseConfiguration(DatabaseType databaseType, string connectionString)
{
var dbConfig = new DatabaseConfiguration
{
@@ -20,7 +20,7 @@ namespace Tgstation.Server.Host.Database.Design
using var loggerFactory = new LoggerFactory();
return new MySqlDatabaseContext(
new DbContextOptions<MySqlDatabaseContext>(),
DesignTimeDbContextFactoryHelpers.GetDbContextOptions(
DesignTimeDbContextFactoryHelpers.GetDatabaseConfiguration(
DatabaseType.MariaDB,
"Server=127.0.0.1;User Id=root;Password=fake;Database=TGS_Design"),
new DatabaseSeeder(
@@ -18,7 +18,7 @@ namespace Tgstation.Server.Host.Database.Design
using var loggerFactory = new LoggerFactory();
return new PostgresSqlDatabaseContext(
new DbContextOptions<PostgresSqlDatabaseContext>(),
DesignTimeDbContextFactoryHelpers.GetDbContextOptions(
DesignTimeDbContextFactoryHelpers.GetDatabaseConfiguration(
DatabaseType.PostgresSql,
"Application Name=tgstation-server;Host=127.0.0.1;Password=qCkWimNgLfWwpr7TnUHs;Username=postgres;Database=TGS_Design"),
new DatabaseSeeder(
@@ -20,7 +20,7 @@ namespace Tgstation.Server.Host.Database.Design
using var loggerFactory = new LoggerFactory();
return new SqlServerDatabaseContext(
new DbContextOptions<SqlServerDatabaseContext>(),
DesignTimeDbContextFactoryHelpers.GetDbContextOptions(
DesignTimeDbContextFactoryHelpers.GetDatabaseConfiguration(
DatabaseType.SqlServer,
"Data Source=fake;Initial Catalog=TGS_Design;Integrated Security=True;Application Name=tgstation-server"),
new DatabaseSeeder(
@@ -20,7 +20,7 @@ namespace Tgstation.Server.Host.Database.Design
using var loggerFactory = new LoggerFactory();
return new SqliteDatabaseContext(
new DbContextOptions<SqliteDatabaseContext>(),
DesignTimeDbContextFactoryHelpers.GetDbContextOptions(
DesignTimeDbContextFactoryHelpers.GetDatabaseConfiguration(
DatabaseType.Sqlite,
"Data Source=tgs_design.sqlite3;Mode=ReadWriteCreate"),
new DatabaseSeeder(
@@ -9,17 +9,17 @@ using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Host.Database
{
/// <summary>
/// <see cref="DatabaseContext{TParentContext}"/> for MySQL
/// <see cref="DatabaseContext"/> for MySQL
/// </summary>
sealed class MySqlDatabaseContext : DatabaseContext<MySqlDatabaseContext>
sealed class MySqlDatabaseContext : DatabaseContext
{
/// <summary>
/// Construct a <see cref="MySqlDatabaseContext"/>
/// </summary>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseConfiguration">The <see cref="IOptions{TOptions}"/> of <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseSeeder">The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext"/></param>
/// <param name="databaseConfiguration">The <see cref="IOptions{TOptions}"/> of <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext"/></param>
/// <param name="databaseSeeder">The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="DatabaseContext"/></param>
public MySqlDatabaseContext(DbContextOptions<MySqlDatabaseContext> dbContextOptions, IOptions<DatabaseConfiguration> databaseConfiguration, IDatabaseSeeder databaseSeeder, ILogger<MySqlDatabaseContext> logger) : base(dbContextOptions, databaseConfiguration, databaseSeeder, logger)
{ }
@@ -8,17 +8,17 @@ using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Host.Database
{
/// <summary>
/// <see cref="DatabaseContext{TParentContext}"/> for PostgresSQL.
/// <see cref="DatabaseContext"/> for PostgresSQL.
/// </summary>
sealed class PostgresSqlDatabaseContext : DatabaseContext<PostgresSqlDatabaseContext>
sealed class PostgresSqlDatabaseContext : DatabaseContext
{
/// <summary>
/// Construct a <see cref="SqlServerDatabaseContext"/>
/// </summary>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseConfiguration">The <see cref="IOptions{TOptions}"/> of <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseSeeder">The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext"/></param>
/// <param name="databaseConfiguration">The <see cref="IOptions{TOptions}"/> of <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext"/></param>
/// <param name="databaseSeeder">The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="DatabaseContext"/></param>
public PostgresSqlDatabaseContext(
DbContextOptions<PostgresSqlDatabaseContext> dbContextOptions,
IOptions<DatabaseConfiguration> databaseConfiguration,
@@ -7,17 +7,17 @@ using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Host.Database
{
/// <summary>
/// <see cref="DatabaseContext{TParentContext}"/> for Sqlserver
/// <see cref="DatabaseContext"/> for Sqlserver
/// </summary>
sealed class SqlServerDatabaseContext : DatabaseContext<SqlServerDatabaseContext>
sealed class SqlServerDatabaseContext : DatabaseContext
{
/// <summary>
/// Construct a <see cref="SqlServerDatabaseContext"/>
/// </summary>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseConfiguration">The <see cref="IOptions{TOptions}"/> of <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseSeeder">The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext"/></param>
/// <param name="databaseConfiguration">The <see cref="IOptions{TOptions}"/> of <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext"/></param>
/// <param name="databaseSeeder">The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="DatabaseContext"/></param>
public SqlServerDatabaseContext(DbContextOptions<SqlServerDatabaseContext> dbContextOptions, IOptions<DatabaseConfiguration> databaseConfiguration, IDatabaseSeeder databaseSeeder, ILogger<SqlServerDatabaseContext> logger) : base(dbContextOptions, databaseConfiguration, databaseSeeder, logger)
{ }
@@ -9,17 +9,17 @@ using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Host.Database
{
/// <summary>
/// <see cref="DatabaseContext{TParentContext}"/> for MySQL
/// <see cref="DatabaseContext"/> for MySQL
/// </summary>
sealed class SqliteDatabaseContext : DatabaseContext<SqliteDatabaseContext>
sealed class SqliteDatabaseContext : DatabaseContext
{
/// <summary>
/// Construct a <see cref="MySqlDatabaseContext"/>
/// </summary>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseConfiguration">The <see cref="IOptions{TOptions}"/> of <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseSeeder">The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext"/></param>
/// <param name="databaseConfiguration">The <see cref="IOptions{TOptions}"/> of <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext"/></param>
/// <param name="databaseSeeder">The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="DatabaseContext"/></param>
public SqliteDatabaseContext(DbContextOptions<SqliteDatabaseContext> dbContextOptions, IOptions<DatabaseConfiguration> databaseConfiguration, IDatabaseSeeder databaseSeeder, ILogger<SqliteDatabaseContext> logger) : base(dbContextOptions, databaseConfiguration, databaseSeeder, logger)
{ }
@@ -107,5 +107,32 @@ namespace Tgstation.Server.Host.Extensions
}
});
}
/// <summary>
/// Add middleware for logging the request number.
/// </summary>
/// <param name="applicationBuilder">The <see cref="IApplicationBuilder"/> to configure.</param>
public static void UseRequestCounting(this IApplicationBuilder applicationBuilder)
{
if (applicationBuilder == null)
throw new ArgumentNullException(nameof(applicationBuilder));
ulong requestCounter = 0;
applicationBuilder.Use(async (context, next) =>
{
var logger = GetLogger(context);
var requestNumber = ++requestCounter;
logger.LogTrace("Starting request #{0}...", requestNumber);
try
{
await next().ConfigureAwait(false);
}
finally
{
logger.LogTrace("Finished request #{0}", requestNumber);
}
});
}
}
}
+4 -1
View File
@@ -299,7 +299,10 @@ namespace Tgstation.Server.Host
{
await eventsTask.ConfigureAwait(false);
}
catch (OperationCanceledException) { }
catch (OperationCanceledException)
{
logger.LogError("Restart timeout hit! Existing DreamDaemon processes will be lost and must be killed manually before being restarted with TGS!");
}
catch (Exception e)
{
logger.LogError("Restart handlers error! Exception: {0}", e);
+1 -1
View File
@@ -5,7 +5,7 @@
"GitHubAccessToken": null,
"SetupWizardMode": "AutoDetect",
"ByondTopicTimeout": 5000,
"RestartTimeout": 10000,
"RestartTimeout": 60000,
"UseExperimentalWatchdog": false,
"UseBasicWatchdogOnWindows": false,
"UserLimit": 100,
+4
View File
@@ -25,6 +25,10 @@
world.log << "You really shouldn't be able to read this"
/world/Export(url)
log << "Export: [url]"
return ..()
/world/Topic(T, Addr, Master, Keys)
world.log << "Topic: [T]"
. = HandleTopic(T)
+13 -5
View File
@@ -1,4 +1,8 @@
/world
sleep_offline = FALSE
/world/New()
log << "Initial value of sleep_offline: [sleep_offline]"
TgsNew(new /datum/tgs_event_handler/impl, TGS_SECURITY_ULTRASAFE)
StartAsync()
@@ -9,17 +13,16 @@
/proc/Run()
sleep(60)
world.TgsChatBroadcast("World Initialized")
world.TgsInitializationComplete()
// world.TgsInitializationComplete()
/world/Topic(T, Addr, Master, Keys)
world.log << "Topic: [T]"
log << "Topic: [T]"
. = HandleTopic(T)
world.log << "Response: [.]"
log << "Response: [.]"
/world/proc/HandleTopic(T)
TGS_TOPIC
world.sleep_offline = FALSE
TgsChatBroadcast("Recieved non-tgs topic: [T]")
var/list/data = params2list(T)
@@ -40,9 +43,14 @@
world.TgsChatBroadcast("Recieved event: [json_encode(args)]")
/world/Export(url)
log << "Export: [url]"
return ..()
/proc/RebootAsync()
set waitfor = FALSE
world.sleep_offline = FALSE
world.TgsChatBroadcast("Rebooting after 3 seconds");
world.log << "About to sleep. sleep_offline: [world.sleep_offline]"
sleep(30)
world.log << "Done sleep, calling Reboot"
world.Reboot()
@@ -29,6 +29,7 @@ namespace Tgstation.Server.Tests.Instance
public async Task Run(CancellationToken cancellationToken)
{
global::System.Console.WriteLine("TEST: START WATCHDOG TESTS");
// Increase startup timeout, disable heartbeats
await instanceClient.DreamDaemon.Update(new DreamDaemon
{
@@ -46,17 +47,18 @@ namespace Tgstation.Server.Tests.Instance
// await RunLongRunningTestThenUpdate(cancellationToken);
// await RunLongRunningTestThenUpdateWithByondVersionSwitch(cancellationToken);
// Remove this deploy when the above tests are reenabled
await DeployTestDme("LongRunning/long_running_test", DreamDaemonSecurity.Trusted, cancellationToken);
await RunHeartbeatTest(cancellationToken);
await StartAndLeaveRunning(cancellationToken);
global::System.Console.WriteLine("TEST: END WATCHDOG TESTS");
}
async Task RunBasicTest(CancellationToken cancellationToken)
{
global::System.Console.WriteLine("TEST: WATCHDOG BASIC TEST");
var daemonStatus = await DeployTestDme("BasicOperation/basic_operation_test", DreamDaemonSecurity.Ultrasafe, cancellationToken);
Assert.IsFalse(daemonStatus.Running.Value);
@@ -84,6 +86,7 @@ namespace Tgstation.Server.Tests.Instance
async Task RunHeartbeatTest(CancellationToken cancellationToken)
{
global::System.Console.WriteLine("TEST: WATCHDOG HEARTBEAT TEST");
// enable heartbeats
await instanceClient.DreamDaemon.Update(new DreamDaemon
{
@@ -144,6 +147,7 @@ namespace Tgstation.Server.Tests.Instance
async Task RunLongRunningTestThenUpdate(CancellationToken cancellationToken)
{
global::System.Console.WriteLine("TEST: WATCHDOG LONG RUNNING TEST");
const string DmeName = "LongRunning/long_running_test";
var daemonStatus = await DeployTestDme(DmeName, DreamDaemonSecurity.Trusted, cancellationToken);
@@ -184,6 +188,7 @@ namespace Tgstation.Server.Tests.Instance
async Task RunLongRunningTestThenUpdateWithByondVersionSwitch(CancellationToken cancellationToken)
{
global::System.Console.WriteLine("TEST: WATCHDOG BYOND VERSION UPDATE TEST");
var versionToInstall = new Version(511, 1384, 0);
var byondInstallJobTask = instanceClient.Byond.SetActiveVersion(
new Api.Models.Byond
@@ -232,6 +237,7 @@ namespace Tgstation.Server.Tests.Instance
public async Task StartAndLeaveRunning(CancellationToken cancellationToken)
{
global::System.Console.WriteLine("TEST: WATCHDOG ENDLESS TEST");
var dd = await instanceClient.DreamDaemon.Read(cancellationToken);
if(dd.ActiveCompileJob == null)
await DeployTestDme("LongRunning/long_running_test", DreamDaemonSecurity.Trusted, cancellationToken);
@@ -253,18 +259,16 @@ namespace Tgstation.Server.Tests.Instance
try
{
global::System.Console.WriteLine("TEST: Sending world reboot topic...");
var result = await bts.SendTopic(IPAddress.Loopback, "tgs_integration_test_special_tactics=1", 1337, cancellationToken);
Assert.AreEqual("ack", result.StringData);
await Task.Delay(7000, cancellationToken);
await Task.Delay(10000, cancellationToken);
}
catch (OperationCanceledException)
{
throw;
}
catch
{
}
}
async Task<DreamDaemon> DeployTestDme(string dmeName, DreamDaemonSecurity deploymentSecurity, CancellationToken cancellationToken)
@@ -118,7 +118,7 @@ namespace Tgstation.Server.Tests
using var hardTimeoutCts = new CancellationTokenSource();
hardTimeoutCts.CancelAfter(new TimeSpan(0, 9, 45));
var hardTimeoutCancellationToken = hardTimeoutCts.Token;
hardTimeoutCancellationToken.Register(() => Console.WriteLine("TEST TIMEOUT HARD!"));
hardTimeoutCancellationToken.Register(() => Console.WriteLine($"[{DateTimeOffset.Now}] TEST TIMEOUT HARD!"));
using var softTimeoutCts = CancellationTokenSource.CreateLinkedTokenSource(hardTimeoutCancellationToken);
softTimeoutCts.CancelAfter(new TimeSpan(0, 9, 15));
@@ -127,7 +127,7 @@ namespace Tgstation.Server.Tests
softTimeoutCancellationToken.Register(() =>
{
if (!tooLateForSoftTimeout)
Console.WriteLine("TEST TIMEOUT SOFT!");
Console.WriteLine($"[{DateTimeOffset.Now}] TEST TIMEOUT SOFT!");
});
using var serverCts = CancellationTokenSource.CreateLinkedTokenSource(softTimeoutCancellationToken);
@@ -297,7 +297,7 @@ namespace Tgstation.Server.Tests
}
catch (Exception ex)
{
Console.WriteLine($"TEST ERROR: {ex.GetType()} in flight!");
Console.WriteLine($"[{DateTimeOffset.Now}] TEST ERROR: {ex}");
throw;
}
finally