Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swarm Murder University #1461

Merged
merged 51 commits into from
Apr 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
9f3e3a3
Minor cleanups to ServerFactory
Cyberboss Apr 21, 2023
bdcc116
Minor update to Host Watchdog and Program.cs in Host
Cyberboss Apr 21, 2023
2a9a271
Server Update Process Cleanup
Cyberboss Apr 21, 2023
e8c89f4
Set a timeout for TestOneServerSwarmUpdate
Cyberboss Apr 21, 2023
c4f561a
Add missing import
Cyberboss Apr 21, 2023
6aa40ef
Fix documentation file paths
Cyberboss Apr 21, 2023
a1b5dbe
Abstract HttpClient and FileDownloader
Cyberboss Apr 21, 2023
0444eb9
Minor cleanups
Cyberboss Apr 21, 2023
0eb139f
Cleanup SwarmService logging templates
Cyberboss Apr 21, 2023
c52cbce
Add configuration option to set expected number of nodes in swarm
Cyberboss Apr 21, 2023
061ab47
Reorganize server update process to make commit less fail-prone
Cyberboss Apr 21, 2023
1c219eb
Framework for testing Swarm protocol
Cyberboss Apr 21, 2023
e30799d
Code cleanups
Cyberboss Apr 21, 2023
3f91a09
Stop being anal about SemaphoreSlimContext disposal
Cyberboss Apr 22, 2023
b83f382
Tested swarm controller and fixed some edge cases
Cyberboss Apr 22, 2023
02d5e31
Add unit test for new class
Cyberboss Apr 22, 2023
079ab20
Swarm test framework cleanup
Cyberboss Apr 22, 2023
3b8e355
Add missing discard
Cyberboss Apr 22, 2023
8ab819a
Reorganize integration tests
Cyberboss Apr 22, 2023
4ca3c2e
I hate these newline semicolons
Cyberboss Apr 22, 2023
5f27726
Increase swarm protocol test max delays
Cyberboss Apr 22, 2023
86e103b
More integration test reorganization
Cyberboss Apr 22, 2023
b797451
Add better error handling to SwarmRpcMapper
Cyberboss Apr 22, 2023
783b58a
Additional logging attempting to find cause of flaky tests
Cyberboss Apr 22, 2023
e72ebb9
Split the start/stop functionality of ISwarmService into its own inte…
Cyberboss Apr 22, 2023
e823ca7
DI setup cleanup
Cyberboss Apr 22, 2023
c1f68d9
Added error code for swarm integrity check failures
Cyberboss Apr 22, 2023
ec06833
More swarm protocol test logging
Cyberboss Apr 22, 2023
7663296
Test std error and file reading
Cyberboss Apr 22, 2023
28b57a1
Minor stype cleanup
Cyberboss Apr 22, 2023
b301b7f
Clean up a bunch of log template placeholder messages
Cyberboss Apr 22, 2023
d0ac8f5
Got rid of that useless swarm registration abstraction AND fixed race…
Cyberboss Apr 22, 2023
7b01035
Fix build warning
Cyberboss Apr 22, 2023
930c0e6
Workaround for `timeout` not working on CI runners
Cyberboss Apr 22, 2023
80a3dbb
Fix off by one error in swarm node counting
Cyberboss Apr 22, 2023
44d6e0c
Workaround for invalid CA2000 warning
Cyberboss Apr 22, 2023
b5618d9
- Fix test issues.
Cyberboss Apr 22, 2023
b3426ae
Test at commit stage, not prepare stage
Cyberboss Apr 22, 2023
57bacef
I was about to say "Fuck CA2000" but it was actually right this time
Cyberboss Apr 22, 2023
5f2b511
Fuck CA2000
Cyberboss Apr 22, 2023
fe478be
Cleanup this test again
Cyberboss Apr 22, 2023
cafb0e4
Are you kidding me? I have to suppress IDE0079 now
Cyberboss Apr 22, 2023
5195e78
Fixing more race conditions in swarm tests
Cyberboss Apr 22, 2023
a7031de
Update API doc for 424 on POST /Administration
Cyberboss Apr 22, 2023
2195f4c
Fix logging call
Cyberboss Apr 22, 2023
1f7872d
Race condition this, mf'er
Cyberboss Apr 22, 2023
77154c9
I think this is the key solution to the race condition we were missing
Cyberboss Apr 22, 2023
6199e0e
Increase delay in stdout/err reading test
Cyberboss Apr 22, 2023
55ced04
Rename the CI jobs slightly
Cyberboss Apr 22, 2023
6443ca8
Workaround std stream race condition in tests
Cyberboss Apr 23, 2023
38753e4
Note about racyness of process file redirection
Cyberboss Apr 23, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/ci-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ jobs:
run: docker build . -f build/Dockerfile

linux-unit-tests:
name: Linux Unit Tests
name: Linux Tests
strategy:
fail-fast: false
matrix:
Expand All @@ -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
Expand All @@ -182,7 +182,7 @@ jobs:
path: ./TestResults/

windows-unit-tests:
name: Windows Unit Tests
name: Windows Tests
strategy:
fail-fast: false
matrix:
Expand All @@ -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
Expand All @@ -213,7 +213,7 @@ jobs:
path: ./TestResults/

windows-integration-test:
name: Windows Integration Test
name: Windows Live Tests
needs: dmapi-build
env:
TGS_TEST_DATABASE_TYPE: SqlServer
Expand Down Expand Up @@ -285,7 +285,7 @@ jobs:
path: Artifacts/Service/

linux-integration-tests:
name: Linux Integration Test
name: Linux Live Tests
needs: dmapi-build
services: # We start all dbs here so we can just code the stuff once
postgres:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ Create an `appsettings.Production.yml` file next to `appsettings.yml`. This will

- `Swarm:Identifier` should be set uniquely on all swarmed servers. Used to identify the current server. This is also used to select which instances exist on the current machine and should not be changed post-setup.

- `Swarm:UpdateRequiredNodeCount` should be set to the total number of servers in your swarm, minus the controller. Prevents updates from occurring unless the non-controller server count in the swarm is greater than or equal to this value.

- `Security:OAuth:<Provider Name>`: Sets the OAuth client ID and secret for a given `<Provider Name>`. The currently supported providers are `Keycloak`, `GitHub`, `Discord`, `InvisionCommunity` and `TGForums`. Setting these fields to `null` disables logins with the provider, but does not stop users from associating their accounts using the API. Sample Entry:
```yml
Security:
Expand Down
10 changes: 5 additions & 5 deletions build/Version.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
<Import Project="ControlPanelVersion.props" />
<PropertyGroup>
<TgsCoreVersion>5.11.0</TgsCoreVersion>
<TgsConfigVersion>4.5.0</TgsConfigVersion>
<TgsApiVersion>9.9.0</TgsApiVersion>
<TgsApiLibraryVersion>10.3.0</TgsApiLibraryVersion>
<TgsClientVersion>11.3.0</TgsClientVersion>
<TgsConfigVersion>4.6.0</TgsConfigVersion>
<TgsApiVersion>9.10.0</TgsApiVersion>
<TgsApiLibraryVersion>10.4.0</TgsApiLibraryVersion>
<TgsClientVersion>11.4.0</TgsClientVersion>
<TgsDmapiVersion>6.4.2</TgsDmapiVersion>
<TgsInteropVersion>5.6.0</TgsInteropVersion>
<TgsHostWatchdogVersion>1.2.1</TgsHostWatchdogVersion>
<TgsHostWatchdogVersion>1.2.2</TgsHostWatchdogVersion>
<TgsContainerScriptVersion>1.2.1</TgsContainerScriptVersion>
<TgsMigratorVersion>1.0.1</TgsMigratorVersion>
<TgsNetVersion>net6.0</TgsNetVersion>
Expand Down
2 changes: 1 addition & 1 deletion docs/API.dox
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ TGS will only every return the response codes listed here
- 409: Conflict. Documented in the requests that use them
- 410: Gone. Attempted to access/modify a resource that ideally should have been ready, but isn't or no longer is
- 422: Unprocessable Entity: Used specifically when an operation that requires a server restart is unable to be performed due to the @ref Tgstation.Server.Host.Watchdog not being present in the deployment. Should not happen with a proper server configuration. Response body contains an @ref Tgstation.Server.Api.Models.ErrorMessage
- 424: Failed Dependency: When a request that depends on the GitHub API fails for a reason other than rate limiting. Check server logs, usually this indicates a bad access token.
- 424: Failed Dependency: When a request that depends on an external API fails for a reason other than rate limiting. The response body will contain an @ref Tgstation.Server.Api.Models.ErrorMessage model detailing the error.
- 426: Upgrade required: Used when the client's API version is not compatible with the server's. Response body contains an @ref Tgstation.Server.Api.Models.ErrorMessage
- 429: Rate limited. Used with operations that rely on GitHub.com. If a rate limit is hit for an operation this will be returned. Response will contain a Retry-After header
- 500: Server error. Please report the request and response body to the code repository
Expand Down
6 changes: 6 additions & 0 deletions src/Tgstation.Server.Api/Models/ErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -629,5 +629,11 @@ public enum ErrorCode : uint
/// </summary>
[Description("The deployment took longer than the configured timeout!")]
DeploymentTimeout,

/// <summary>
/// The server swarm has less than the expected amount of nodes.
/// </summary>
[Description("The server swarm has less than the expected amount of nodes!")]
SwarmIntegrityCheckFailed,
}
}
4 changes: 2 additions & 2 deletions src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
<RepositoryUrl>https://github.com/tgstation/tgstation-server</RepositoryUrl>
<Copyright>2018-2023</Copyright>
<PackageTags>json web api tgstation-server tgstation ss13 byond</PackageTags>
<PackageReleaseNotes>Added ChannelData field to ChatChannels model.</PackageReleaseNotes>
<PackageReleaseNotes>Added ErrorCode.SwarmIntegrityCheckFailed.</PackageReleaseNotes>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<DocumentationFile>bin\$(Configuration)\netstandard2.1\Tgstation.Server.Api.xml</DocumentationFile>
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Tgstation.Server.Api.xml</DocumentationFile>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<NoWarn>CA1028</NoWarn>
</PropertyGroup>
Expand Down
3 changes: 2 additions & 1 deletion src/Tgstation.Server.Client/ApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Tgstation.Server.Api;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Models.Response;
using Tgstation.Server.Common;

namespace Tgstation.Server.Client
{
Expand Down Expand Up @@ -50,7 +51,7 @@ public TimeSpan Timeout
}

/// <summary>
/// The <see cref="HttpClientImplementation"/> for the <see cref="ApiClient"/>.
/// The <see cref="IHttpClient"/> for the <see cref="ApiClient"/>.
/// </summary>
readonly IHttpClient httpClient;

Expand Down
3 changes: 2 additions & 1 deletion src/Tgstation.Server.Client/ApiClientFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;

using Tgstation.Server.Api;
using Tgstation.Server.Common;

namespace Tgstation.Server.Client
{
Expand All @@ -13,7 +14,7 @@ sealed class ApiClientFactory : IApiClientFactory
ApiHeaders apiHeaders,
ApiHeaders? tokenRefreshHeaders,
bool authless) => new ApiClient(
new HttpClientImplementation(),
new HttpClient(),
url,
apiHeaders,
tokenRefreshHeaders,
Expand Down
37 changes: 0 additions & 37 deletions src/Tgstation.Server.Client/HttpClientImplementation.cs

This file was deleted.

5 changes: 3 additions & 2 deletions src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
<RepositoryUrl>https://github.com/tgstation/tgstation-server</RepositoryUrl>
<Copyright>2018-2023</Copyright>
<PackageTags>json web api tgstation-server tgstation ss13 byond client</PackageTags>
<PackageReleaseNotes>Fix login refreshing not working.</PackageReleaseNotes>
<PackageReleaseNotes>Updated definitions for API version 9.10.0.</PackageReleaseNotes>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<DocumentationFile>bin\$(Configuration)\netstandard2.1\Tgstation.Server.Client.xml</DocumentationFile>
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Tgstation.Server.Client.xml</DocumentationFile>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
</PropertyGroup>

Expand All @@ -41,6 +41,7 @@

<ItemGroup>
<ProjectReference Include="..\Tgstation.Server.Api\Tgstation.Server.Api.csproj" />
<ProjectReference Include="..\Tgstation.Server.Common\Tgstation.Server.Common.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
50 changes: 50 additions & 0 deletions src/Tgstation.Server.Common/HttpClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;

namespace Tgstation.Server.Common
{
/// <inheritdoc />
public sealed class HttpClient : IHttpClient
{
/// <inheritdoc />
public TimeSpan Timeout
{
get => httpClient.Timeout;
set => httpClient.Timeout = value;
}

/// <inheritdoc />
public HttpRequestHeaders DefaultRequestHeaders => httpClient.DefaultRequestHeaders;

/// <summary>
/// The real <see cref="System.Net.Http.HttpClient"/>.
/// </summary>
readonly System.Net.Http.HttpClient httpClient;

/// <summary>
/// Initializes a new instance of the <see cref="HttpClient"/> class.
/// </summary>
/// <param name="implementation">The <see cref="System.Net.Http.HttpClient"/> to wrap.</param>
public HttpClient(System.Net.Http.HttpClient implementation)
{
httpClient = implementation ?? throw new ArgumentNullException(nameof(implementation));
}

/// <summary>
/// Initializes a new instance of the <see cref="HttpClient"/> class.
/// </summary>
public HttpClient()
: this(new System.Net.Http.HttpClient())
{
}

/// <inheritdoc />
public void Dispose() => httpClient.Dispose();

/// <inheritdoc />
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) => httpClient.SendAsync(request, cancellationToken);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;

namespace Tgstation.Server.Client
namespace Tgstation.Server.Common
{
/// <summary>
/// For sending HTTP requests.
/// </summary>
interface IHttpClient : IDisposable
public interface IHttpClient : IDisposable
{
/// <summary>
/// The request timeout.
/// </summary>
TimeSpan Timeout { get; set; }

/// <summary>
/// The <see cref="HttpRequestHeaders"/> used on every request.
/// </summary>
HttpRequestHeaders DefaultRequestHeaders { get; }

/// <summary>
/// Send an HTTP request.
/// </summary>
Expand Down
31 changes: 31 additions & 0 deletions src/Tgstation.Server.Common/Tgstation.Server.Common.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Version.props" />

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<DebugType>Full</DebugType>
<Version>$(TgsCoreVersion)</Version>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Tgstation.Server.Client.xml</DocumentationFile>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>

<ItemGroup>
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="../../build/stylecop.json" />
</ItemGroup>
</Project>
23 changes: 23 additions & 0 deletions src/Tgstation.Server.Host.Common/HostExitCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Tgstation.Server.Host.Common
{
/// <summary>
/// Represents the exit code of the <see cref="Host"/> program.
/// </summary>
public enum HostExitCode
{
/// <summary>
/// The program ran to completion and should not be re-executed.
/// </summary>
CompleteExecution,

/// <summary>
/// The program should be re-executed after applying pending updates.
/// </summary>
RestartRequested,

/// <summary>
/// The program errored and error data was writted to the pending update path as a file.
/// </summary>
Error,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Version.props" />

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<DebugType>Full</DebugType>
<Version>$(TgsCoreVersion)</Version>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<DocumentationFile>bin\$(Configuration)\netstandard2.0\Tgstation.Server.Host.Shared.xml</DocumentationFile>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>

<ItemGroup>
<!-- Usage: Linting -->
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="../../build/stylecop.json" />
</ItemGroup>

</Project>
Loading