Emergency shuttle docking test (#10614)

This commit is contained in:
metalgearsloth
2022-09-14 19:02:59 +10:00
committed by GitHub
parent 68dfec456a
commit c9d3545b39
5 changed files with 136 additions and 9 deletions

View File

@@ -4,12 +4,20 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Client.Shuttles.Systems;
using Content.Server.GameTicking;
using Content.Server.Maps;
using Content.Server.Shuttles.Components;
using Content.Server.Station.Components;
using NUnit.Framework; using NUnit.Framework;
using Robust.Server.Maps; using Robust.Server.Maps;
using Robust.Shared.ContentPack; using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using YamlDotNet.RepresentationModel; using YamlDotNet.RepresentationModel;
using ShuttleSystem = Content.Server.Shuttles.Systems.ShuttleSystem;
namespace Content.IntegrationTests.Tests namespace Content.IntegrationTests.Tests
{ {
@@ -61,7 +69,7 @@ namespace Content.IntegrationTests.Tests
await pairTracker.CleanReturnAsync(); await pairTracker.CleanReturnAsync();
} }
private static string[] GetMapNames() private static string[] GetGameMapNames()
{ {
Task<string[]> task; Task<string[]> task;
using (ExecutionContext.SuppressFlow()) using (ExecutionContext.SuppressFlow())
@@ -73,11 +81,128 @@ namespace Content.IntegrationTests.Tests
new PoolSettings new PoolSettings
{ {
Disconnected = true, Disconnected = true,
TestName = $"{nameof(PostMapInitTest)}.{nameof(GetMapNames)}" TestName = $"{nameof(PostMapInitTest)}.{nameof(GetGameMapNames)}"
} }
); );
var server = pairTracker.Pair.Server; var server = pairTracker.Pair.Server;
var protoManager = server.ResolveDependency<IPrototypeManager>();
var maps = protoManager.EnumeratePrototypes<GameMapPrototype>().ToList();
var mapNames = new List<string>();
var naughty = new HashSet<string>()
{
"empty",
"infiltrator",
"pirate",
};
foreach (var map in maps)
{
// AAAAAAAAAA
// Why are they stations!
if (naughty.Contains(map.ID))
continue;
mapNames.Add(map.ID);
}
await pairTracker.CleanReturnAsync();
return mapNames.ToArray();
});
Task.WaitAll(task);
}
return task.GetAwaiter().GetResult();
}
[Test, TestCaseSource(nameof(GetGameMapNames))]
public async Task GameMapsLoadableTest(string mapProto)
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
var server = pairTracker.Pair.Server;
var mapLoader = server.ResolveDependency<IMapLoader>();
var mapManager = server.ResolveDependency<IMapManager>();
var entManager = server.ResolveDependency<IEntityManager>();
var protoManager = server.ResolveDependency<IPrototypeManager>();
var ticker = entManager.EntitySysManager.GetEntitySystem<GameTicker>();
var shuttleSystem = entManager.EntitySysManager.GetEntitySystem<ShuttleSystem>();
await server.WaitPost(() =>
{
var mapId = mapManager.CreateMap();
try
{
ticker.LoadGameMap(protoManager.Index<GameMapPrototype>(mapProto), mapId, null);
}
catch (Exception ex)
{
throw new Exception($"Failed to load map {mapProto}", ex);
}
var shuttleMap = mapManager.CreateMap();
var largest = 0f;
EntityUid? targetGrid = null;
var memberQuery = entManager.GetEntityQuery<StationMemberComponent>();
var grids = mapManager.GetAllMapGrids(mapId);
foreach (var grid in grids)
{
if (!memberQuery.HasComponent(grid.GridEntityId))
continue;
var area = grid.LocalAABB.Width * grid.LocalAABB.Height;
if (area > largest)
{
largest = area;
targetGrid = grid.GridEntityId;
}
}
// Test shuttle can dock.
// This is done inside gamemap test because loading the map takes ages and we already have it.
var station = entManager.GetComponent<StationMemberComponent>(targetGrid!.Value).Station;
var shuttlePath = entManager.GetComponent<StationDataComponent>(station).EmergencyShuttlePath
.ToString();
var shuttle = mapLoader.LoadGrid(shuttleMap, entManager.GetComponent<StationDataComponent>(station).EmergencyShuttlePath.ToString());
Assert.That(shuttleSystem.TryFTLDock(entManager.GetComponent<ShuttleComponent>(shuttle.gridId!.Value), targetGrid.Value), $"Unable to dock {shuttlePath} to {mapProto}");
mapManager.DeleteMap(shuttleMap);
try
{
mapManager.DeleteMap(mapId);
}
catch (Exception ex)
{
throw new Exception($"Failed to delete map {mapProto}", ex);
}
});
await server.WaitRunTicks(1);
await pairTracker.CleanReturnAsync();
}
/// <summary>
/// Get the non-game map maps.
/// </summary>
private static string[] GetMaps()
{
Task<string[]> task;
using (ExecutionContext.SuppressFlow())
{
task = Task.Run(static async () =>
{
await Task.Yield();
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{Disconnected = true});
var server = pairTracker.Pair.Server;
var resourceManager = server.ResolveDependency<IResourceManager>(); var resourceManager = server.ResolveDependency<IResourceManager>();
var protoManager = server.ResolveDependency<IPrototypeManager>();
var gameMaps = protoManager.EnumeratePrototypes<GameMapPrototype>().Select(o => o.MapPath).ToHashSet();
var mapFolder = new ResourcePath("/Maps"); var mapFolder = new ResourcePath("/Maps");
var maps = resourceManager var maps = resourceManager
.ContentFindFiles(mapFolder) .ContentFindFiles(mapFolder)
@@ -89,7 +214,8 @@ namespace Content.IntegrationTests.Tests
var rootedPath = map.ToRootedPath(); var rootedPath = map.ToRootedPath();
// ReSharper disable once RedundantLogicalConditionalExpressionOperand // ReSharper disable once RedundantLogicalConditionalExpressionOperand
if (SkipTestMaps && rootedPath.ToString().StartsWith(TestMapsPath)) if (SkipTestMaps && rootedPath.ToString().StartsWith(TestMapsPath) ||
gameMaps.Contains(map))
{ {
continue; continue;
} }
@@ -105,7 +231,7 @@ namespace Content.IntegrationTests.Tests
return task.GetAwaiter().GetResult(); return task.GetAwaiter().GetResult();
} }
[Test, TestCaseSource(nameof(GetMapNames))] [Test, TestCaseSource(nameof(GetMaps))]
public async Task MapsLoadableTest(string mapName) public async Task MapsLoadableTest(string mapName)
{ {
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true}); await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});

View File

@@ -1,4 +1,3 @@
#nullable enable
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Server.Shuttles.Components; using Content.Server.Shuttles.Components;
using NUnit.Framework; using NUnit.Framework;
@@ -18,6 +17,7 @@ namespace Content.IntegrationTests.Tests
{ {
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true}); await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true});
var server = pairTracker.Pair.Server; var server = pairTracker.Pair.Server;
await server.WaitIdleAsync();
var mapMan = server.ResolveDependency<IMapManager>(); var mapMan = server.ResolveDependency<IMapManager>();
var sEntities = server.ResolveDependency<IEntityManager>(); var sEntities = server.ResolveDependency<IEntityManager>();
@@ -30,8 +30,8 @@ namespace Content.IntegrationTests.Tests
var grid = mapMan.CreateGrid(mapId); var grid = mapMan.CreateGrid(mapId);
gridEnt = grid.GridEntityId; gridEnt = grid.GridEntityId;
Assert.That(sEntities.TryGetComponent(gridEnt, out ShuttleComponent? shuttleComponent)); Assert.That(sEntities.HasComponent<ShuttleComponent>(gridEnt));
Assert.That(sEntities.TryGetComponent(gridEnt, out PhysicsComponent? physicsComponent)); Assert.That(sEntities.TryGetComponent<PhysicsComponent>(gridEnt, out var physicsComponent));
Assert.That(physicsComponent!.BodyType, Is.EqualTo(BodyType.Dynamic)); Assert.That(physicsComponent!.BodyType, Is.EqualTo(BodyType.Dynamic));
Assert.That(sEntities.GetComponent<TransformComponent>(gridEnt).LocalPosition, Is.EqualTo(Vector2.Zero)); Assert.That(sEntities.GetComponent<TransformComponent>(gridEnt).LocalPosition, Is.EqualTo(Vector2.Zero));
physicsComponent.ApplyLinearImpulse(Vector2.One); physicsComponent.ApplyLinearImpulse(Vector2.One);

View File

@@ -112,7 +112,7 @@ namespace Content.Server.GameTicking
/// <param name="loadOptions">Map loading options, includes offset.</param> /// <param name="loadOptions">Map loading options, includes offset.</param>
/// <param name="stationName">Name to assign to the loaded station.</param> /// <param name="stationName">Name to assign to the loaded station.</param>
/// <returns>All loaded entities and grids.</returns> /// <returns>All loaded entities and grids.</returns>
public (IReadOnlyList<EntityUid>, IReadOnlyList<EntityUid>) LoadGameMap(GameMapPrototype map, MapId targetMapId, MapLoadOptions? loadOptions, string? stationName = null) public (IReadOnlyList<EntityUid> Entities, IReadOnlyList<EntityUid> Grids) LoadGameMap(GameMapPrototype map, MapId targetMapId, MapLoadOptions? loadOptions, string? stationName = null)
{ {
// Okay I specifically didn't set LoadMap here because this is typically called onto a new map. // Okay I specifically didn't set LoadMap here because this is typically called onto a new map.
// whereas the command can also be used on an existing map. // whereas the command can also be used on an existing map.

View File

@@ -14,6 +14,7 @@ using Robust.Shared.Player;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Content.Server.Shuttles.Events; using Content.Server.Shuttles.Events;
using Content.Server.Station.Components;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
namespace Content.Server.Shuttles.Systems; namespace Content.Server.Shuttles.Systems;

View File

@@ -35,6 +35,6 @@ public sealed class StationDataComponent : Component
/// <summary> /// <summary>
/// Emergency shuttle map path for this station. /// Emergency shuttle map path for this station.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), Access(typeof(ShuttleSystem), Friend = AccessPermissions.ReadExecute)] [ViewVariables(VVAccess.ReadWrite), Access(typeof(ShuttleSystem), Other = AccessPermissions.ReadWriteExecute)]
public ResourcePath EmergencyShuttlePath = new("/Maps/Shuttles/emergency_shuttle.yml"); public ResourcePath EmergencyShuttlePath = new("/Maps/Shuttles/emergency_shuttle.yml");
} }