test(streaming): expose world reveal lifecycle
This commit is contained in:
parent
b60cb67009
commit
db45b81f75
6 changed files with 532 additions and 11 deletions
|
|
@ -0,0 +1,105 @@
|
|||
using AcDream.App.Streaming;
|
||||
|
||||
namespace AcDream.App.Tests.Streaming;
|
||||
|
||||
public sealed class WorldRevealLifecycleTelemetryTests
|
||||
{
|
||||
private static WorldRevealReadinessSnapshot Ready(uint cell = 0x11340021u) => new(
|
||||
cell,
|
||||
IsIndoor: false,
|
||||
IsUnhydratable: false,
|
||||
RequiredRenderRadius: 1,
|
||||
IsRenderNeighborhoodReady: true,
|
||||
AreCompositeTexturesReady: true,
|
||||
IsCollisionReady: true);
|
||||
|
||||
[Fact]
|
||||
public void Login_RecordsReadyThenFirstVisibleFrameExactlyOnce()
|
||||
{
|
||||
var logs = new List<string>();
|
||||
var telemetry = new WorldRevealLifecycleTelemetry(logs.Add);
|
||||
|
||||
long generation = telemetry.Begin(WorldRevealKind.Login);
|
||||
telemetry.ObserveReadiness(Ready());
|
||||
telemetry.ObserveWorldViewportVisible();
|
||||
telemetry.ObserveWorldViewportVisible();
|
||||
telemetry.Complete();
|
||||
|
||||
Assert.Equal(generation, telemetry.Snapshot.Generation);
|
||||
Assert.True(telemetry.Snapshot.IsReady);
|
||||
Assert.True(telemetry.Snapshot.WorldViewportObserved);
|
||||
Assert.True(telemetry.Snapshot.Completed);
|
||||
Assert.Equal(0, telemetry.Snapshot.InvariantFailureCount);
|
||||
Assert.Single(logs, line => line.Contains("event=world-visible", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EarlyWorldViewport_IsARecordedHardInvariantFailure()
|
||||
{
|
||||
var logs = new List<string>();
|
||||
var telemetry = new WorldRevealLifecycleTelemetry(logs.Add);
|
||||
|
||||
telemetry.Begin(WorldRevealKind.Login);
|
||||
telemetry.ObserveReadiness(Ready() with { AreCompositeTexturesReady = false });
|
||||
telemetry.ObserveWorldViewportVisible();
|
||||
|
||||
Assert.Equal(1, telemetry.Snapshot.InvariantFailureCount);
|
||||
Assert.Contains(logs, line => line.Contains("reason=viewport-before-ready", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NewGeneration_SupersedesOldStateAndRejectsDestinationMutation()
|
||||
{
|
||||
var logs = new List<string>();
|
||||
var telemetry = new WorldRevealLifecycleTelemetry(logs.Add);
|
||||
|
||||
long first = telemetry.Begin(WorldRevealKind.Login);
|
||||
telemetry.ObserveReadiness(Ready(0x11340021u));
|
||||
long second = telemetry.Begin(WorldRevealKind.Portal);
|
||||
telemetry.ObserveReadiness(Ready(0x3032001Cu));
|
||||
telemetry.ObserveReadiness(Ready(0xC95B0001u));
|
||||
|
||||
Assert.True(second > first);
|
||||
Assert.Equal(WorldRevealKind.Portal, telemetry.Snapshot.Kind);
|
||||
Assert.Equal(0xC95B0001u, telemetry.Snapshot.Readiness.DestinationCell);
|
||||
Assert.Equal(1, telemetry.Snapshot.InvariantFailureCount);
|
||||
Assert.Contains(logs, line => line.Contains("event=superseded", StringComparison.Ordinal));
|
||||
Assert.Contains(logs, line => line.Contains("reason=destination-changed", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PortalMaterialization_IsCountedOncePerGeneration()
|
||||
{
|
||||
var telemetry = new WorldRevealLifecycleTelemetry();
|
||||
|
||||
telemetry.Begin(WorldRevealKind.Portal);
|
||||
telemetry.ObserveReadiness(Ready());
|
||||
telemetry.ObserveMaterialized();
|
||||
telemetry.ObserveMaterialized();
|
||||
telemetry.Begin(WorldRevealKind.Portal);
|
||||
telemetry.ObserveReadiness(Ready(0x3032001Cu));
|
||||
telemetry.ObserveMaterialized();
|
||||
|
||||
Assert.Equal(2, telemetry.PortalMaterializationCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CancelledGeneration_IgnoresLateAsyncObservations()
|
||||
{
|
||||
var telemetry = new WorldRevealLifecycleTelemetry();
|
||||
|
||||
telemetry.Begin(WorldRevealKind.Portal);
|
||||
telemetry.Cancel();
|
||||
telemetry.ObserveReadiness(Ready());
|
||||
telemetry.ObserveMaterialized();
|
||||
telemetry.ObserveWorldViewportVisible();
|
||||
telemetry.Complete();
|
||||
|
||||
Assert.True(telemetry.Snapshot.Cancelled);
|
||||
Assert.False(telemetry.Snapshot.IsReady);
|
||||
Assert.False(telemetry.Snapshot.Materialized);
|
||||
Assert.False(telemetry.Snapshot.WorldViewportObserved);
|
||||
Assert.False(telemetry.Snapshot.Completed);
|
||||
Assert.Equal(0, telemetry.PortalMaterializationCount);
|
||||
}
|
||||
}
|
||||
|
|
@ -121,4 +121,46 @@ public sealed class WorldRevealReadinessBarrierTests
|
|||
Assert.Equal(0, state.Preparations);
|
||||
Assert.Equal(-1, state.RenderRadius);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Evaluate_ExposesTheCanonicalOutdoorDecisionWithoutRepeatingDomains()
|
||||
{
|
||||
const uint outdoorCell = 0x11340021u;
|
||||
var state = new State
|
||||
{
|
||||
RenderReady = true,
|
||||
CompositeReady = true,
|
||||
TerrainReady = true,
|
||||
};
|
||||
|
||||
WorldRevealReadinessSnapshot snapshot = state.Build().Evaluate(outdoorCell);
|
||||
|
||||
Assert.Equal(outdoorCell, snapshot.DestinationCell);
|
||||
Assert.False(snapshot.IsIndoor);
|
||||
Assert.Equal(WorldRevealReadinessBarrier.OutdoorNeighborhoodRadius, snapshot.RequiredRenderRadius);
|
||||
Assert.True(snapshot.IsRenderNeighborhoodReady);
|
||||
Assert.True(snapshot.AreCompositeTexturesReady);
|
||||
Assert.True(snapshot.IsCollisionReady);
|
||||
Assert.True(snapshot.IsReady);
|
||||
Assert.Equal(-1, state.PreparedRadius);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Evaluate_ShortCircuitsDownstreamDomainsUntilRenderPublication()
|
||||
{
|
||||
var state = new State
|
||||
{
|
||||
CompositeReady = true,
|
||||
TerrainReady = true,
|
||||
SpawnCellReady = true,
|
||||
};
|
||||
|
||||
WorldRevealReadinessSnapshot snapshot = state.Build().Evaluate(0x11340100u);
|
||||
|
||||
Assert.False(snapshot.IsRenderNeighborhoodReady);
|
||||
Assert.False(snapshot.AreCompositeTexturesReady);
|
||||
Assert.False(snapshot.IsCollisionReady);
|
||||
Assert.False(snapshot.IsReady);
|
||||
Assert.Equal(-1, state.TerrainRadius);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue