Add new entity spawn test & fix misc bugs (#19953)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Server.Humanoid.Components;
|
||||
using Content.Shared.Coordinates;
|
||||
using Content.Shared.Prototypes;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -183,7 +185,7 @@ namespace Content.IntegrationTests.Tests
|
||||
var query = entityMan.AllEntityQueryEnumerator<TComp>();
|
||||
while (query.MoveNext(out var uid, out var meta))
|
||||
yield return (uid, meta);
|
||||
};
|
||||
}
|
||||
|
||||
var entityMetas = Query<MetaDataComponent>(sEntMan).ToList();
|
||||
foreach (var (uid, meta) in entityMetas)
|
||||
@@ -198,6 +200,100 @@ namespace Content.IntegrationTests.Tests
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This test checks that spawning and deleting an entity doesn't somehow create other unrelated entities.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Unless an entity is intentionally designed to spawn other entities (e.g., mob spawners), they should
|
||||
/// generally not spawn unrelated / detached entities. Any entities that do get spawned should be parented to
|
||||
/// the spawned entity (e.g., in a container). If an entity needs to spawn an entity somewhere in null-space,
|
||||
/// it should delete that entity when it is no longer required. This test mainly exists to prevent "entity leak"
|
||||
/// bugs, where spawning some entity starts spawning unrelated entities in null space.
|
||||
/// </remarks>
|
||||
[Test]
|
||||
public async Task SpawnAndDeleteEntityCountTest()
|
||||
{
|
||||
var settings = new PoolSettings { Connected = true, Dirty = true };
|
||||
await using var pair = await PoolManager.GetServerClient(settings);
|
||||
var server = pair.Server;
|
||||
var client = pair.Client;
|
||||
|
||||
var excluded = new[]
|
||||
{
|
||||
"MapGrid",
|
||||
"StationEvent",
|
||||
"TimedDespawn",
|
||||
|
||||
// Spawner entities
|
||||
"DragonRift",
|
||||
"RandomHumanoidSpawner",
|
||||
"RandomSpawner",
|
||||
"ConditionalSpawner",
|
||||
"GhostRoleMobSpawner",
|
||||
"NukeOperativeSpawner",
|
||||
"TimedSpawner",
|
||||
};
|
||||
|
||||
Assert.That(server.CfgMan.GetCVar(CVars.NetPVS), Is.False);
|
||||
|
||||
var protoIds = server.ProtoMan
|
||||
.EnumeratePrototypes<EntityPrototype>()
|
||||
.Where(p => !p.Abstract)
|
||||
.Where(p => !pair.IsTestPrototype(p))
|
||||
.Where(p => !excluded.Any(p.Components.ContainsKey))
|
||||
.Select(p => p.ID)
|
||||
.ToList();
|
||||
|
||||
MapCoordinates coords = default;
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
var map = server.MapMan.CreateMap();
|
||||
coords = new MapCoordinates(default, map);
|
||||
});
|
||||
|
||||
await pair.RunTicksSync(3);
|
||||
|
||||
List<string> badPrototypes = new();
|
||||
foreach (var protoId in protoIds)
|
||||
{
|
||||
// TODO fix ninja
|
||||
// Currently ninja fails to equip their own loadout.
|
||||
if (protoId == "MobHumanSpaceNinja")
|
||||
continue;
|
||||
|
||||
var count = server.EntMan.EntityCount;
|
||||
var clientCount = client.EntMan.EntityCount;
|
||||
EntityUid uid = default;
|
||||
await server.WaitPost(() => uid = server.EntMan.SpawnEntity(protoId, coords));
|
||||
await pair.RunTicksSync(3);
|
||||
|
||||
// If the entity deleted itself, check that it didn't spawn other entities
|
||||
if (!server.EntMan.EntityExists(uid))
|
||||
{
|
||||
if (server.EntMan.EntityCount != count || client.EntMan.EntityCount != clientCount)
|
||||
badPrototypes.Add(protoId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check that the number of entities has increased.
|
||||
if (server.EntMan.EntityCount <= count || client.EntMan.EntityCount <= clientCount)
|
||||
{
|
||||
badPrototypes.Add(protoId);
|
||||
continue;
|
||||
}
|
||||
|
||||
await server.WaitPost(() => server.EntMan.DeleteEntity(uid));
|
||||
await pair.RunTicksSync(3);
|
||||
|
||||
// Check that the number of entities has gone back to the original value.
|
||||
if (server.EntMan.EntityCount != count || client.EntMan.EntityCount != clientCount)
|
||||
badPrototypes.Add(protoId);
|
||||
}
|
||||
|
||||
Assert.That(badPrototypes, Is.Empty);
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task AllComponentsOneToOneDeleteTest()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user