test(headless): cover K4 death and cancellation
This commit is contained in:
parent
97c174fbb2
commit
bd236ce553
2 changed files with 115 additions and 17 deletions
|
|
@ -358,6 +358,76 @@ public sealed class HeadlessProcessSchedulerTests
|
||||||
StringComparison.Ordinal);
|
StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ThirtySessionsConvergeAcrossRandomizedCancellationEdges()
|
||||||
|
{
|
||||||
|
const int sessionCount = 30;
|
||||||
|
var random = new Random(0xAC2013);
|
||||||
|
for (int iteration = 0; iteration < 5; iteration++)
|
||||||
|
{
|
||||||
|
var configuration = new HeadlessConfiguration
|
||||||
|
{
|
||||||
|
Version = 1,
|
||||||
|
Sessions = Enumerable.Range(0, sessionCount)
|
||||||
|
.Select(index => Descriptor(
|
||||||
|
$"cancel-{iteration}-{index}",
|
||||||
|
$"cancel-{iteration}-{index}-stdin"))
|
||||||
|
.Cast<HeadlessSessionDescriptor?>()
|
||||||
|
.ToList(),
|
||||||
|
};
|
||||||
|
var operations = new FixtureSessionOperations();
|
||||||
|
using var diagnostics = new StringWriter();
|
||||||
|
using var host = new HeadlessProcessHost(
|
||||||
|
configuration,
|
||||||
|
HeadlessPathSet.Resolve(
|
||||||
|
new HeadlessPathOverrides()),
|
||||||
|
new System.IO.StringReader(string.Concat(
|
||||||
|
Enumerable.Repeat(
|
||||||
|
"random-cancel-password"
|
||||||
|
+ Environment.NewLine,
|
||||||
|
sessionCount))),
|
||||||
|
diagnostics,
|
||||||
|
operations);
|
||||||
|
using var cancellation = new CancellationTokenSource(
|
||||||
|
TimeSpan.FromMilliseconds(random.Next(37, 144)));
|
||||||
|
|
||||||
|
HeadlessExitCode result =
|
||||||
|
await host.RunAsync(cancellation.Token);
|
||||||
|
|
||||||
|
Assert.True(cancellation.IsCancellationRequested);
|
||||||
|
Assert.Equal(HeadlessExitCode.Success, result);
|
||||||
|
Assert.Equal(sessionCount, operations.CreatedSessionCount);
|
||||||
|
Assert.All(
|
||||||
|
host.Sessions,
|
||||||
|
static session =>
|
||||||
|
Assert.False(session.IsFaulted));
|
||||||
|
|
||||||
|
host.Dispose();
|
||||||
|
|
||||||
|
Assert.Equal(sessionCount, operations.DisposedSessionCount);
|
||||||
|
Assert.All(
|
||||||
|
host.Sessions,
|
||||||
|
static session =>
|
||||||
|
Assert.True(
|
||||||
|
session.Runtime
|
||||||
|
.CaptureOwnership()
|
||||||
|
.IsConverged));
|
||||||
|
string output = diagnostics.ToString();
|
||||||
|
Assert.Contains(
|
||||||
|
"\"state\":\"disposed\"",
|
||||||
|
output,
|
||||||
|
StringComparison.Ordinal);
|
||||||
|
Assert.Contains(
|
||||||
|
$"\"convergedRuntimeCount\":{sessionCount}",
|
||||||
|
output,
|
||||||
|
StringComparison.Ordinal);
|
||||||
|
Assert.DoesNotContain(
|
||||||
|
"random-cancel-password",
|
||||||
|
output,
|
||||||
|
StringComparison.Ordinal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ThrowingPolicyQuarantinesOnlyItsOwnSession()
|
public void ThrowingPolicyQuarantinesOnlyItsOwnSession()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ public sealed class HeadlessSessionIsolationTests
|
||||||
.Select(index => CreateHost(index, operations, time))
|
.Select(index => CreateHost(index, operations, time))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
var reconnectCounts = new int[sessionCount];
|
var reconnectCounts = new int[sessionCount];
|
||||||
|
var deathCounts = new int[sessionCount];
|
||||||
var random = new Random(0xAC2013);
|
var random = new Random(0xAC2013);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -197,6 +198,16 @@ public sealed class HeadlessSessionIsolationTests
|
||||||
2 + reconnectCounts[index]
|
2 + reconnectCounts[index]
|
||||||
+ (frame / 211))));
|
+ (frame / 211))));
|
||||||
}
|
}
|
||||||
|
if (frame % 5003 == 0)
|
||||||
|
{
|
||||||
|
int index = (frame / 5003) % sessionCount;
|
||||||
|
Death(
|
||||||
|
operations.ActiveSession(
|
||||||
|
hosts[index].SessionId),
|
||||||
|
sharedPlayerGuid,
|
||||||
|
frame);
|
||||||
|
deathCounts[index]++;
|
||||||
|
}
|
||||||
if (frame % 353 == 0)
|
if (frame % 353 == 0)
|
||||||
{
|
{
|
||||||
int index = random.Next(sessionCount);
|
int index = random.Next(sessionCount);
|
||||||
|
|
@ -289,12 +300,14 @@ public sealed class HeadlessSessionIsolationTests
|
||||||
Assert.All(
|
Assert.All(
|
||||||
reconnectCounts,
|
reconnectCounts,
|
||||||
static count => Assert.True(count > 0));
|
static count => Assert.True(count > 0));
|
||||||
|
Assert.All(
|
||||||
|
deathCounts,
|
||||||
|
static count => Assert.True(count > 0));
|
||||||
var finalRecords = new List<RuntimeEntityRecord>(
|
var finalRecords = new List<RuntimeEntityRecord>(
|
||||||
sessionCount);
|
sessionCount);
|
||||||
Assert.All(
|
for (int index = 0; index < hosts.Length; index++)
|
||||||
hosts,
|
|
||||||
host =>
|
|
||||||
{
|
{
|
||||||
|
HeadlessSessionHost host = hosts[index];
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
(ulong)frameCount,
|
(ulong)frameCount,
|
||||||
host.Runtime.Clock.FrameNumber);
|
host.Runtime.Clock.FrameNumber);
|
||||||
|
|
@ -307,7 +320,10 @@ public sealed class HeadlessSessionIsolationTests
|
||||||
host.Runtime.TransitOwner
|
host.Runtime.TransitOwner
|
||||||
.CaptureOwnership()
|
.CaptureOwnership()
|
||||||
.IsSessionIdle);
|
.IsSessionIdle);
|
||||||
});
|
Assert.True(
|
||||||
|
host.Runtime.CommunicationOwner.View.Count
|
||||||
|
>= deathCounts[index]);
|
||||||
|
}
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
sessionCount,
|
sessionCount,
|
||||||
finalRecords
|
finalRecords
|
||||||
|
|
@ -420,6 +436,18 @@ public sealed class HeadlessSessionIsolationTests
|
||||||
ForcePositionSequence: 0));
|
ForcePositionSequence: 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void Death(
|
||||||
|
WorldSession session,
|
||||||
|
uint victimGuid,
|
||||||
|
int sequence) =>
|
||||||
|
EventDelegate<Action<PlayerKilled.Parsed>>(
|
||||||
|
session,
|
||||||
|
nameof(session.PlayerKilledReceived))(
|
||||||
|
new PlayerKilled.Parsed(
|
||||||
|
$"Headless death {sequence}.",
|
||||||
|
victimGuid,
|
||||||
|
0x5000FFFFu));
|
||||||
|
|
||||||
private static WorldSession.EntitySpawn Spawn(
|
private static WorldSession.EntitySpawn Spawn(
|
||||||
uint guid,
|
uint guid,
|
||||||
float positionX)
|
float positionX)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue