Files
2026-07-10 10:24:29 +08:00

51 lines
1.9 KiB
C#

using System;
using System.Runtime.CompilerServices;
using Xunit;
using XWorld.Framework;
using XWorld.Server.Host;
namespace XWorld.Server.Host.Tests
{
public class AlcUnloadTests
{
private sealed class NullOutput : IRoomOutput
{
public void Broadcast(NetMessage m) { }
public void SendTo(int playerId, NetMessage m) { }
}
// 在独立方法里加载/运行/卸载,确保局部强引用随方法返回而消失
[MethodImpl(MethodImplOptions.NoInlining)]
private static (WeakReference alc, WeakReference asm) LoadRunAndUnload()
{
var module = new GameModuleLoader().Load(TestGames.Root, "rps", 1);
IGameServerRoom room = module.CreateRoom();
room.OnRoomStart(
new[]
{
new PlayerInfo { PlayerId = 1, Name = "H", IsAI = false },
new PlayerInfo { PlayerId = -1, Name = "AI", IsAI = true },
},
new RoomCtx(new DeterministicRandom(1), new ManualClock(), new ConsoleLogger(),
new InMemoryStorage(), new NullOutput(), _ => { }));
room.OnTick(1f); // dt=1 < 5s,仍在 Choosing,仅广播一次快照
var asmWeak = new WeakReference(room.GetType().Assembly); // 游戏 ALC 内加载的程序集
room = null;
return (module.Unload(), asmWeak);
}
[Fact]
public void GameModule_Unload_ReclaimsMemory()
{
var (alcWeak, asmWeak) = LoadRunAndUnload();
for (int i = 0; i < 12 && (alcWeak.IsAlive || asmWeak.IsAlive); i++)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
Assert.False(alcWeak.IsAlive, "游戏模块 ALC 未被回收 —— 存在泄漏引用");
Assert.False(asmWeak.IsAlive, "游戏程序集未被回收 —— 存在泄漏引用");
}
}
}