Move TestPair & PoolManager to engine (#36797)
* Move TestPair & PoolManager to engine * Add to global usings * A * Move ITestContextLike to engine * Readd cvars partial class * cleanup diff
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Content.Client.IoC;
|
||||
using Content.Client.Parallax.Managers;
|
||||
using Content.IntegrationTests.Tests.Destructible;
|
||||
using Content.IntegrationTests.Tests.DeviceNetwork;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Players;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.UnitTesting;
|
||||
|
||||
namespace Content.IntegrationTests.Pair;
|
||||
@@ -18,156 +19,99 @@ namespace Content.IntegrationTests.Pair;
|
||||
/// <summary>
|
||||
/// This object wraps a pooled server+client pair.
|
||||
/// </summary>
|
||||
public sealed partial class TestPair
|
||||
public sealed partial class TestPair : RobustIntegrationTest.TestPair
|
||||
{
|
||||
public readonly int Id;
|
||||
private bool _initialized;
|
||||
private TextWriter _testOut = default!;
|
||||
public readonly Stopwatch Watch = new();
|
||||
public readonly List<string> TestHistory = new();
|
||||
public PoolSettings Settings = default!;
|
||||
public TestMapData? TestMap;
|
||||
private List<NetUserId> _modifiedProfiles = new();
|
||||
|
||||
private int _nextServerSeed;
|
||||
private int _nextClientSeed;
|
||||
|
||||
public int ServerSeed;
|
||||
public int ClientSeed;
|
||||
|
||||
public RobustIntegrationTest.ServerIntegrationInstance Server { get; private set; } = default!;
|
||||
public RobustIntegrationTest.ClientIntegrationInstance Client { get; private set; } = default!;
|
||||
|
||||
public void Deconstruct(
|
||||
out RobustIntegrationTest.ServerIntegrationInstance server,
|
||||
out RobustIntegrationTest.ClientIntegrationInstance client)
|
||||
{
|
||||
server = Server;
|
||||
client = Client;
|
||||
}
|
||||
|
||||
public ICommonSession? Player => Server.PlayerMan.SessionsDict.GetValueOrDefault(Client.User!.Value);
|
||||
|
||||
public ContentPlayerData? PlayerData => Player?.Data.ContentData();
|
||||
|
||||
public PoolTestLogHandler ServerLogHandler { get; private set; } = default!;
|
||||
public PoolTestLogHandler ClientLogHandler { get; private set; } = default!;
|
||||
|
||||
public TestPair(int id)
|
||||
protected override async Task Initialize()
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
|
||||
public async Task Initialize(PoolSettings settings, TextWriter testOut, List<string> testPrototypes)
|
||||
{
|
||||
if (_initialized)
|
||||
throw new InvalidOperationException("Already initialized");
|
||||
|
||||
_initialized = true;
|
||||
Settings = settings;
|
||||
(Client, ClientLogHandler) = await PoolManager.GenerateClient(settings, testOut);
|
||||
(Server, ServerLogHandler) = await PoolManager.GenerateServer(settings, testOut);
|
||||
ActivateContext(testOut);
|
||||
|
||||
Client.CfgMan.OnCVarValueChanged += OnClientCvarChanged;
|
||||
Server.CfgMan.OnCVarValueChanged += OnServerCvarChanged;
|
||||
|
||||
if (!settings.NoLoadTestPrototypes)
|
||||
await LoadPrototypes(testPrototypes!);
|
||||
|
||||
if (!settings.UseDummyTicker)
|
||||
var settings = (PoolSettings)Settings;
|
||||
if (!settings.DummyTicker)
|
||||
{
|
||||
var gameTicker = Server.ResolveDependency<IEntityManager>().System<GameTicker>();
|
||||
var gameTicker = Server.System<GameTicker>();
|
||||
await Server.WaitPost(() => gameTicker.RestartRound());
|
||||
}
|
||||
}
|
||||
|
||||
// Always initially connect clients to generate an initial random set of preferences/profiles.
|
||||
// This is to try and prevent issues where if the first test that connects the client is consistently some test
|
||||
// that uses a fixed seed, it would effectively prevent it from beingrandomized.
|
||||
public override async Task RevertModifiedCvars()
|
||||
{
|
||||
// I just love order dependent cvars
|
||||
// I.e., cvars that when changed automatically cause others to also change.
|
||||
var modified = ModifiedServerCvars.TryGetValue(CCVars.PanicBunkerEnabled.Name, out var panik);
|
||||
|
||||
Client.SetConnectTarget(Server);
|
||||
await Client.WaitIdleAsync();
|
||||
var netMgr = Client.ResolveDependency<IClientNetManager>();
|
||||
await Client.WaitPost(() => netMgr.ClientConnect(null!, 0, null!));
|
||||
await ReallyBeIdle(10);
|
||||
await Client.WaitRunTicks(1);
|
||||
await base.RevertModifiedCvars();
|
||||
|
||||
if (!settings.ShouldBeConnected)
|
||||
if (!modified)
|
||||
return;
|
||||
|
||||
await Server.WaitPost(() => Server.CfgMan.SetCVar(CCVars.PanicBunkerEnabled.Name, panik!));
|
||||
ClearModifiedCvars();
|
||||
}
|
||||
|
||||
protected override async Task ApplySettings(IIntegrationInstance instance, PairSettings n)
|
||||
{
|
||||
var next = (PoolSettings)n;
|
||||
await base.ApplySettings(instance, next);
|
||||
var cfg = instance.CfgMan;
|
||||
await instance.WaitPost(() =>
|
||||
{
|
||||
await Client.WaitPost(() => netMgr.ClientDisconnect("Initial disconnect"));
|
||||
await ReallyBeIdle(10);
|
||||
}
|
||||
if (cfg.IsCVarRegistered(CCVars.GameDummyTicker.Name))
|
||||
cfg.SetCVar(CCVars.GameDummyTicker, next.DummyTicker);
|
||||
|
||||
var cRand = Client.ResolveDependency<IRobustRandom>();
|
||||
var sRand = Server.ResolveDependency<IRobustRandom>();
|
||||
_nextClientSeed = cRand.Next();
|
||||
_nextServerSeed = sRand.Next();
|
||||
if (cfg.IsCVarRegistered(CCVars.GameLobbyEnabled.Name))
|
||||
cfg.SetCVar(CCVars.GameLobbyEnabled, next.InLobby);
|
||||
|
||||
if (cfg.IsCVarRegistered(CCVars.GameMap.Name))
|
||||
cfg.SetCVar(CCVars.GameMap, next.Map);
|
||||
|
||||
if (cfg.IsCVarRegistered(CCVars.AdminLogsEnabled.Name))
|
||||
cfg.SetCVar(CCVars.AdminLogsEnabled, next.AdminLogsEnabled);
|
||||
});
|
||||
}
|
||||
|
||||
public void Kill()
|
||||
protected override RobustIntegrationTest.ClientIntegrationOptions ClientOptions()
|
||||
{
|
||||
State = PairState.Dead;
|
||||
ServerLogHandler.ShuttingDown = true;
|
||||
ClientLogHandler.ShuttingDown = true;
|
||||
Server.Dispose();
|
||||
Client.Dispose();
|
||||
}
|
||||
var opts = base.ClientOptions();
|
||||
|
||||
private void ClearContext()
|
||||
{
|
||||
_testOut = default!;
|
||||
ServerLogHandler.ClearContext();
|
||||
ClientLogHandler.ClearContext();
|
||||
}
|
||||
|
||||
public void ActivateContext(TextWriter testOut)
|
||||
{
|
||||
_testOut = testOut;
|
||||
ServerLogHandler.ActivateContext(testOut);
|
||||
ClientLogHandler.ActivateContext(testOut);
|
||||
}
|
||||
|
||||
public void Use()
|
||||
{
|
||||
if (State != PairState.Ready)
|
||||
throw new InvalidOperationException($"Pair is not ready to use. State: {State}");
|
||||
State = PairState.InUse;
|
||||
}
|
||||
|
||||
public enum PairState : byte
|
||||
{
|
||||
Ready = 0,
|
||||
InUse = 1,
|
||||
CleanDisposed = 2,
|
||||
Dead = 3,
|
||||
}
|
||||
|
||||
public void SetupSeed()
|
||||
{
|
||||
var sRand = Server.ResolveDependency<IRobustRandom>();
|
||||
if (Settings.ServerSeed is { } severSeed)
|
||||
opts.LoadTestAssembly = false;
|
||||
opts.ContentStart = true;
|
||||
opts.FailureLogLevel = LogLevel.Warning;
|
||||
opts.Options = new()
|
||||
{
|
||||
ServerSeed = severSeed;
|
||||
sRand.SetSeed(ServerSeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerSeed = _nextServerSeed;
|
||||
sRand.SetSeed(ServerSeed);
|
||||
_nextServerSeed = sRand.Next();
|
||||
}
|
||||
LoadConfigAndUserData = false,
|
||||
};
|
||||
|
||||
var cRand = Client.ResolveDependency<IRobustRandom>();
|
||||
if (Settings.ClientSeed is { } clientSeed)
|
||||
opts.BeforeStart += () =>
|
||||
{
|
||||
ClientSeed = clientSeed;
|
||||
cRand.SetSeed(ClientSeed);
|
||||
}
|
||||
else
|
||||
IoCManager.Resolve<IModLoader>().SetModuleBaseCallbacks(new ClientModuleTestingCallbacks
|
||||
{
|
||||
ClientBeforeIoC = () => IoCManager.Register<IParallaxManager, DummyParallaxManager>(true)
|
||||
});
|
||||
};
|
||||
return opts;
|
||||
}
|
||||
|
||||
protected override RobustIntegrationTest.ServerIntegrationOptions ServerOptions()
|
||||
{
|
||||
var opts = base.ServerOptions();
|
||||
|
||||
opts.LoadTestAssembly = false;
|
||||
opts.ContentStart = true;
|
||||
opts.Options = new()
|
||||
{
|
||||
ClientSeed = _nextClientSeed;
|
||||
cRand.SetSeed(ClientSeed);
|
||||
_nextClientSeed = cRand.Next();
|
||||
}
|
||||
LoadConfigAndUserData = false,
|
||||
};
|
||||
|
||||
opts.BeforeStart += () =>
|
||||
{
|
||||
// Server-only systems (i.e., systems that subscribe to events with server-only components)
|
||||
// There's probably a better way to do this.
|
||||
var entSysMan = IoCManager.Resolve<IEntitySystemManager>();
|
||||
entSysMan.LoadExtraSystemType<DeviceNetworkTestSystem>();
|
||||
entSysMan.LoadExtraSystemType<TestDestructibleListenerSystem>();
|
||||
};
|
||||
return opts;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user