Merge pull request #1625 from tgstation/AndThisWasntLiveTestedWhy [TGSDeploy]

v5.13.7: Fix config listing 500 error
This commit is contained in:
Jordan Dominion
2023-08-14 08:41:33 -04:00
committed by GitHub
6 changed files with 57 additions and 25 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
<!-- Integration tests will ensure they match across the board -->
<Import Project="ControlPanelVersion.props" />
<PropertyGroup>
<TgsCoreVersion>5.13.6</TgsCoreVersion>
<TgsCoreVersion>5.13.7</TgsCoreVersion>
<TgsConfigVersion>4.7.1</TgsConfigVersion>
<TgsApiVersion>9.11.0</TgsApiVersion>
<TgsCommonLibraryVersion>6.0.0</TgsCommonLibraryVersion>
@@ -236,7 +236,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles
}
/// <inheritdoc />
public async Task<IReadOnlyList<ConfigurationFileResponse>> ListDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken)
public async Task<IOrderedQueryable<ConfigurationFileResponse>> ListDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken)
{
await EnsureDirectories(cancellationToken);
var path = ValidateConfigRelativePath(configurationRelativePath);
@@ -252,14 +252,14 @@ namespace Tgstation.Server.Host.Components.StaticFiles
{
IsDirectory = true,
Path = ioManager.ConcatPath(configurationRelativePath, x),
}).OrderBy(file => file.Path));
}));
enumerator = synchronousIOManager.GetFiles(path, cancellationToken);
result.AddRange(enumerator.Select(x => new ConfigurationFileResponse
{
IsDirectory = false,
Path = ioManager.ConcatPath(configurationRelativePath, x),
}).OrderBy(file => file.Path));
}));
}
using (SemaphoreSlimContext.TryLock(semaphore, out var locked))
@@ -276,7 +276,10 @@ namespace Tgstation.Server.Host.Components.StaticFiles
await systemIdentity.RunImpersonated(ListImpl, cancellationToken);
}
return result;
return result
.AsQueryable()
.OrderBy(configFile => !configFile.IsDirectory)
.ThenBy(configFile => configFile.Path);
}
/// <inheritdoc />
@@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -38,8 +38,8 @@ namespace Tgstation.Server.Host.Components.StaticFiles
/// <param name="configurationRelativePath">The relative path in the Configuration directory.</param>
/// <param name="systemIdentity">The <see cref="ISystemIdentity"/> for the operation. If <see langword="null"/>, the operation will be performed as the user of the <see cref="Core.Application"/>.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="ConfigurationFileResponse"/>s for the items in the directory. <see cref="FileTicketResponse.FileTicket"/> and <see cref="IConfigurationFile.LastReadHash"/> will both be <see langword="null"/>. <see langword="null"/> will be returned if the operation failed due to access contention.</returns>
Task<IReadOnlyList<ConfigurationFileResponse>> ListDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken);
/// <returns>A <see cref="Task{TResult}"/> resulting in an <see cref="IOrderedQueryable{T}"/> of the <see cref="ConfigurationFileResponse"/>s for the items in the directory. <see cref="FileTicketResponse.FileTicket"/> and <see cref="IConfigurationFile.LastReadHash"/> will both be <see langword="null"/>. <see langword="null"/> will be returned if the operation failed due to access contention.</returns>
Task<IOrderedQueryable<ConfigurationFileResponse>> ListDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken);
/// <summary>
/// Reads a given <paramref name="configurationRelativePath"/>.
@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -190,10 +189,7 @@ namespace Tgstation.Server.Host.Controllers
return new PaginatableResult<ConfigurationFileResponse>(
Conflict(new ErrorMessageResponse(ErrorCode.ConfigurationContendedAccess)));
return new PaginatableResult<ConfigurationFileResponse>(
result
.AsQueryable()
.OrderBy(x => x)); // ordering performed by IConfiguration
return new PaginatableResult<ConfigurationFileResponse>(result);
}
catch (NotImplementedException ex)
{
@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -57,7 +58,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles.Tests
await configuration.StartAsync(CancellationToken.None);
var listResponse = await configuration.ListDirectory(".", null, CancellationToken.None);
var listResponse = (await configuration.ListDirectory(".", null, CancellationToken.None)).ToList();
Assert.AreEqual(9, listResponse.Count);
Assert.AreEqual("a", listResponse[0].Path[2..]);
Assert.AreEqual("c", listResponse[1].Path[2..]);
@@ -76,7 +77,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles.Tests
await ioManager.WriteAllBytes("GameStaticFiles/config/unbuyableshuttles.txt", Array.Empty<byte>(), CancellationToken.None);
await ioManager.WriteAllBytes("GameStaticFiles/config/spaceruinblacklist.txt", Array.Empty<byte>(), CancellationToken.None);
listResponse = await configuration.ListDirectory("GameStaticFiles/config", null, CancellationToken.None);
listResponse = (await configuration.ListDirectory("GameStaticFiles/config", null, CancellationToken.None)).ToList();
var substringStart = "GameStaticFiles/config".Length + 1;
Assert.AreEqual(6, listResponse.Count);
Assert.AreEqual("title_music", listResponse[0].Path[substringStart..]);
@@ -1,9 +1,6 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Mime;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -14,9 +11,7 @@ using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Models.Request;
using Tgstation.Server.Client;
using Tgstation.Server.Client.Components;
using Tgstation.Server.Common;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.System;
namespace Tgstation.Server.Tests.Live.Instance
{
@@ -139,12 +134,49 @@ namespace Tgstation.Server.Tests.Live.Instance
TaskCreationOptions.LongRunning,
TaskScheduler.Current);
public Task RunPreWatchdog(CancellationToken cancellationToken)
async Task TestListing(CancellationToken cancellationToken)
{
return Task.WhenAll(
TestUploadDownloadAndDeleteDirectory(cancellationToken),
SetupDMApiTests(cancellationToken),
TestPregeneratedFilesExist(cancellationToken));
await using var uploadMs = new MemoryStream(Encoding.UTF8.GetBytes("Hello world!"));
await configurationClient.Write(
new ConfigurationFileRequest
{
Path = "f-TestFile.txt"
},
uploadMs,
cancellationToken);
uploadMs.Seek(0, SeekOrigin.Begin);
await configurationClient.Write(
new ConfigurationFileRequest
{
Path = "f-TestDir/f-TestFile.txt"
},
uploadMs,
cancellationToken);
var baseList = await configurationClient.List(null, ".", cancellationToken);
Assert.AreEqual(5, baseList.Count);
Assert.AreEqual($"/CodeModifications", baseList[0].Path);
Assert.IsTrue(baseList[0].IsDirectory);
Assert.AreEqual($"/EventScripts", baseList[1].Path);
Assert.IsTrue(baseList[1].IsDirectory);
Assert.AreEqual($"/f-TestDir", baseList[2].Path);
Assert.IsTrue(baseList[2].IsDirectory);
Assert.AreEqual($"/GameStaticFiles", baseList[3].Path);
Assert.IsTrue(baseList[3].IsDirectory);
Assert.AreEqual($"/f-TestFile.txt", baseList[4].Path);
Assert.IsFalse(baseList[4].IsDirectory);
}
async Task SequencedApiTests(CancellationToken cancellationToken)
{
await TestUploadDownloadAndDeleteDirectory(cancellationToken);
await TestListing(cancellationToken);
}
public Task RunPreWatchdog(CancellationToken cancellationToken) => Task.WhenAll(
SequencedApiTests(cancellationToken),
SetupDMApiTests(cancellationToken),
TestPregeneratedFilesExist(cancellationToken));
}
}