Files
RobustToolbox/Robust.Shared.IntegrationTests/EntitySerialization/BackwardsCompatibilityTest.v7.cs
PJB3005 788e9386fd Split up test project
Robust.UnitTesting was both ALL tests for RT, and also API surface for content tests.

Tests are now split into separate projects as appropriate, and the API side has also been split off.
2025-12-16 01:36:53 +01:00

353 lines
13 KiB
C#

using System.Threading.Tasks;
using NUnit.Framework;
using Robust.Shared.ContentPack;
using Robust.Shared.EntitySerialization;
using Robust.Shared.EntitySerialization.Components;
using Robust.Shared.EntitySerialization.Systems;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Utility;
using static Robust.UnitTesting.Shared.EntitySerialization.EntitySaveTestComponent;
namespace Robust.UnitTesting.Shared.EntitySerialization;
/// <summary>
/// Test that older file formats can still be loaded.
/// </summary>
[TestFixture]
internal sealed partial class BackwardsCompatibilityTest : RobustIntegrationTest
{
/// <summary>
/// Check that v7 maps can be loaded. This just re-uses some map files that are generated by other tests, and then
/// checks that the post-load debug asserts still pass. specifically, it uses the second to last file from
/// <see cref="AutoIncludeSerializationTest"/> and the initial file from
/// <see cref="LifestageSerializationTest.TestMixedLifestageSerialization"/>.
/// </summary>
/// <remarks>
/// At the time of writing, v7 is the current version, but this is here for when the version increases in the future.
/// </remarks>
[Test]
public async Task TestLoadV7()
{
var server = StartServer(new ServerIntegrationOptions { ExtraPrototypes = PrototypeV7 });
await server.WaitIdleAsync();
var entMan = server.EntMan;
var mapSys = server.System<SharedMapSystem>();
var loader = server.System<MapLoaderSystem>();
var tileMan = server.ResolveDependency<ITileDefinitionManager>();
var resourceManager = server.ResolveDependency<IResourceManagerInternal>();
SerializationTestHelper.LoadTileDefs(server.ProtoMan, tileMan, "space");
void AssertCount(int expected) => Assert.That(entMan.Count<EntitySaveTestComponent>(), Is.EqualTo(expected));
Assert.That(entMan.Count<LoadedMapComponent>(), Is.EqualTo(0));
var mapLoadOpts = MapLoadOptions.Default with
{
DeserializationOptions = DeserializationOptions.Default with {LogOrphanedGrids = false}
};
// Test the file from AutoIncludeSerializationTest
{
var path = new ResPath($"{nameof(MapDataV7)}.yml");
resourceManager.MountString(path.ToString(), MapDataV7);
Entity<TransformComponent, EntitySaveTestComponent> grid;
Entity<TransformComponent, EntitySaveTestComponent> onGrid;
Entity<TransformComponent, EntitySaveTestComponent> otherMap;
Entity<TransformComponent, EntitySaveTestComponent> otherEnt;
Entity<TransformComponent, EntitySaveTestComponent> nullSpace;
LoadResult? result = default;
await server.WaitAssertion(() => Assert.That(loader.TryLoadGeneric(path, out result, mapLoadOpts)));
Assert.That(result!.Version, Is.EqualTo(7));
Assert.That(result.Grids, Has.Count.EqualTo(1));
Assert.That(result.Orphans, Is.Empty); // Grid was orphaned, but was adopted after a new map was created
Assert.That(result.Maps, Has.Count.EqualTo(2));
Assert.That(result.NullspaceEntities, Has.Count.EqualTo(1));
Assert.That(entMan.Count<LoadedMapComponent>(), Is.EqualTo(1)); // auto-generated map isn't marked as "loaded"
AssertCount(5);
grid = Find(nameof(grid), entMan);
onGrid = Find(nameof(onGrid), entMan);
otherMap = Find(nameof(otherMap), entMan);
otherEnt = Find(nameof(otherEnt), entMan);
nullSpace = Find(nameof(nullSpace), entMan);
Assert.That(onGrid.Comp1.ParentUid, Is.EqualTo(grid.Owner));
Assert.That(otherEnt.Comp1.ParentUid, Is.EqualTo(otherMap.Owner));
Assert.That(otherMap.Comp1.ParentUid, Is.EqualTo(EntityUid.Invalid));
Assert.That(nullSpace.Comp1.ParentUid, Is.EqualTo(EntityUid.Invalid));
await server.WaitPost(() => entMan.DeleteEntity(otherMap));
await server.WaitPost(() => entMan.DeleteEntity(grid.Comp1.ParentUid));
await server.WaitPost(() => entMan.DeleteEntity(nullSpace));
AssertCount(0);
await server.WaitPost(() => loader.Delete(result));
}
// Test the file from LifestageSerializationTest.TestMixedLifestageSerialization
{
var pathLifestage = new ResPath($"{nameof(MapDataV7Lifestage)}.yml");
resourceManager.MountString(pathLifestage.ToString(), MapDataV7Lifestage);
Entity<TransformComponent, EntitySaveTestComponent> mapA; // preinit Map
Entity<TransformComponent, EntitySaveTestComponent> mapB; // postinit unpaused Map
Entity<TransformComponent, EntitySaveTestComponent> entA; // postinit entity on preinit map
Entity<TransformComponent, EntitySaveTestComponent> entB; // paused entity on postinit unpaused map
Entity<TransformComponent, EntitySaveTestComponent> entC; // preinit entity on postinit map
Entity<TransformComponent, EntitySaveTestComponent> nullA; // postinit nullspace entity
Entity<TransformComponent, EntitySaveTestComponent> nullB; // preinit nullspace entity
Entity<TransformComponent, EntitySaveTestComponent> nullC; // paused postinit nullspace entity
Assert.That(entMan.Count<EntitySaveTestComponent>(), Is.EqualTo(0));
LoadResult? result = default;
await server.WaitAssertion(() => Assert.That(loader.TryLoadGeneric(pathLifestage, out result)));
Assert.That(result!.Version, Is.EqualTo(7));
Assert.That(entMan.Count<EntitySaveTestComponent>(), Is.EqualTo(8));
mapA = Find(nameof(mapA), entMan);
mapB = Find(nameof(mapB), entMan);
entA = Find(nameof(entA), entMan);
entB = Find(nameof(entB), entMan);
entC = Find(nameof(entC), entMan);
nullA = Find(nameof(nullA), entMan);
nullB = Find(nameof(nullB), entMan);
nullC = Find(nameof(nullC), entMan);
AssertPaused(true, mapA, entB, nullC);
AssertPaused(false, mapB, entA, entC, nullA, nullB);
AssertPreInit(true, mapA, entC, nullB);
AssertPreInit(false, mapB, entA, entB, nullA, nullC);
void AssertPaused(bool expected, params EntityUid[] uids)
{
foreach (var uid in uids)
{
Assert.That(entMan.GetComponent<MetaDataComponent>(uid).EntityPaused, Is.EqualTo(expected));
}
}
void AssertPreInit(bool expected, params EntityUid[] uids)
{
foreach (var uid in uids)
{
Assert.That(entMan!.GetComponent<MetaDataComponent>(uid).EntityLifeStage,
expected
? Is.LessThan(EntityLifeStage.MapInitialized)
: Is.EqualTo(EntityLifeStage.MapInitialized));
}
}
await server.WaitPost(() => loader.Delete(result));
}
Assert.That(entMan.Count<EntitySaveTestComponent>(), Is.EqualTo(0));
Assert.That(entMan.Count<LoadedMapComponent>(), Is.EqualTo(0));
Assert.That(entMan.Count<MapComponent>(), Is.EqualTo(0));
}
private const string MapDataV7 = @"
meta:
format: 7
category: Unknown
engineVersion: 238.0.0
forkId: """"
forkVersion: """"
time: 12/25/2024 00:40:09
entityCount: 5
maps:
- 3
grids:
- 1
orphans:
- 1
nullspace:
- 5
tilemap:
1: space
0: a
entities:
- proto: """"
entities:
- uid: 1
paused: false
components:
- type: MetaData
name: grid
- type: Transform
parent: invalid
- type: MapGrid
chunks:
0,0:
ind: 0,0
tiles: AAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAA
version: 6
- type: Broadphase
- type: Physics
- type: Fixtures
fixtures: {}
- type: OccluderTree
- type: EntitySaveTest
list: []
id: grid
- uid: 2
mapInit: true
components:
- type: MetaData
- type: Transform
pos: 0.5,0.5
parent: 1
- type: EntitySaveTest
list: []
entity: 3
id: onGrid
- uid: 3
mapInit: true
components:
- type: MetaData
name: Map Entity
- type: Transform
- type: Map
mapInitialized: True
- type: GridTree
- type: Broadphase
- type: OccluderTree
- type: EntitySaveTest
list: []
id: otherMap
- uid: 4
mapInit: true
components:
- type: MetaData
- type: Transform
parent: 3
- type: EntitySaveTest
list: []
entity: 5
id: otherEnt
- uid: 5
mapInit: true
components:
- type: MetaData
- type: Transform
- type: EntitySaveTest
list: []
id: nullSpace
";
private const string MapDataV7Lifestage = @"
meta:
format: 7
category: Unknown
engineVersion: 238.0.0
forkId: """"
forkVersion: """"
time: 12/25/2024 00:50:59
entityCount: 8
maps:
- 1
- 3
grids: []
orphans: []
nullspace:
- 6
- 7
- 8
tilemap: {}
entities:
- proto: """"
entities:
- uid: 1
components:
- type: MetaData
name: Map Entity
- type: Transform
- type: Map
mapPaused: True
- type: GridTree
- type: Broadphase
- type: OccluderTree
- type: EntitySaveTest
list: []
id: mapA
- uid: 2
mapInit: true
components:
- type: MetaData
- type: Transform
parent: 1
- type: EntitySaveTest
list: []
id: entA
- uid: 3
mapInit: true
components:
- type: MetaData
name: Map Entity
- type: Transform
- type: Map
mapInitialized: True
- type: GridTree
- type: Broadphase
- type: OccluderTree
- type: EntitySaveTest
list: []
id: mapB
- uid: 4
mapInit: true
paused: true
components:
- type: MetaData
- type: Transform
parent: 3
- type: EntitySaveTest
list: []
id: entB
- uid: 5
paused: false
components:
- type: MetaData
- type: Transform
parent: 3
- type: EntitySaveTest
list: []
id: entC
- uid: 6
mapInit: true
components:
- type: MetaData
- type: Transform
- type: EntitySaveTest
list: []
id: nullA
- uid: 7
paused: false
components:
- type: MetaData
- type: Transform
- type: EntitySaveTest
list: []
id: nullB
- uid: 8
mapInit: true
paused: true
components:
- type: MetaData
- type: Transform
- type: EntitySaveTest
list: []
id: nullC
";
private const string PrototypeV7 = @"
- type: testTileDef
id: space
- type: testTileDef
id: a
";
}