From 260cf793fefe2e3f862373e2f35c7c1bf18de8ef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Feb 2022 02:18:42 +0900 Subject: [PATCH] Add test coverage of more advanced frame delivery scenarios to `TestSceneSpectatorPlayback` --- .../Gameplay/TestSceneSpectatorPlayback.cs | 57 +++++++++++++++---- .../Visual/Spectator/TestSpectatorClient.cs | 4 ++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs index a4d8460846..4ec46036f6 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs @@ -41,8 +41,12 @@ namespace osu.Game.Tests.Visual.Gameplay private Replay replay; + private TestSpectatorClient spectatorClient; + private ManualClock manualClock; + private TestReplayRecorder recorder; + private OsuSpriteText latencyDisplay; private TestFramedReplayInputHandler replayHandler; @@ -54,7 +58,6 @@ namespace osu.Game.Tests.Visual.Gameplay { replay = new Replay(); manualClock = new ManualClock(); - SpectatorClient spectatorClient; Child = new DependencyProvidingContainer { @@ -76,7 +79,7 @@ namespace osu.Game.Tests.Visual.Gameplay { recordingManager = new TestRulesetInputManager(TestSceneModSettings.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique) { - Recorder = new TestReplayRecorder + Recorder = recorder = new TestReplayRecorder { ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos), }, @@ -143,22 +146,52 @@ namespace osu.Game.Tests.Visual.Gameplay }); } + [Test] + public void TestBasic() + { + AddUntilStep("received frames", () => replay.Frames.Count > 50); + AddStep("stop sending frames", () => recorder.Expire()); + AddUntilStep("wait for all frames received", () => replay.Frames.Count == recorder.SentFrames.Count); + } + + [Test] + public void TestWithSendFailure() + { + AddUntilStep("received frames", () => replay.Frames.Count > 50); + + int framesReceivedSoFar = 0; + int frameSendAttemptsSoFar = 0; + + AddStep("start failing sends", () => + { + spectatorClient.ShouldFailSendingFrames = true; + framesReceivedSoFar = replay.Frames.Count; + frameSendAttemptsSoFar = spectatorClient.FrameSendAttempts; + }); + + AddUntilStep("wait for send attempts", () => spectatorClient.FrameSendAttempts > frameSendAttemptsSoFar + 5); + AddAssert("frames did not increase", () => framesReceivedSoFar == replay.Frames.Count); + + AddStep("stop failing sends", () => spectatorClient.ShouldFailSendingFrames = false); + + AddUntilStep("wait for next frames", () => framesReceivedSoFar < replay.Frames.Count); + + AddStep("stop sending frames", () => recorder.Expire()); + + AddUntilStep("wait for all frames received", () => replay.Frames.Count == recorder.SentFrames.Count); + AddAssert("ensure frames were received in the correct sequence", () => replay.Frames.Select(f => f.Time).SequenceEqual(recorder.SentFrames.Select(f => f.Time))); + } + private void onNewFrames(int userId, FrameDataBundle frames) { - Logger.Log($"Received {frames.Frames.Count} new frames ({string.Join(',', frames.Frames.Select(f => ((int)f.Time).ToString()))})"); - foreach (var legacyFrame in frames.Frames) { var frame = new TestReplayFrame(); frame.FromLegacy(legacyFrame, null); replay.Frames.Add(frame); } - } - [Test] - public void TestBasic() - { - AddStep("Wait for user input", () => { }); + Logger.Log($"Received {frames.Frames.Count} new frames (total {replay.Frames.Count} of {recorder.SentFrames.Count})"); } private double latency = SpectatorClient.TIME_BETWEEN_SENDS; @@ -318,6 +351,8 @@ namespace osu.Game.Tests.Visual.Gameplay internal class TestReplayRecorder : ReplayRecorder { + public List SentFrames = new List(); + public TestReplayRecorder() : base(new Score { @@ -332,7 +367,9 @@ namespace osu.Game.Tests.Visual.Gameplay protected override ReplayFrame HandleFrame(Vector2 mousePosition, List actions, ReplayFrame previousFrame) { - return new TestReplayFrame(Time.Current, mousePosition, actions.ToArray()); + var testReplayFrame = new TestReplayFrame(Time.Current, mousePosition, actions.ToArray()); + SentFrames.Add(testReplayFrame); + return testReplayFrame; } } } diff --git a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs index ae5d20f4f4..f5da95bd7b 100644 --- a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs +++ b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs @@ -30,6 +30,8 @@ namespace osu.Game.Tests.Visual.Spectator /// public bool ShouldFailSendingFrames { get; set; } + public int FrameSendAttempts { get; private set; } + public override IBindable IsConnected { get; } = new Bindable(true); public IReadOnlyDictionary LastReceivedUserFrames => lastReceivedUserFrames; @@ -130,6 +132,8 @@ namespace osu.Game.Tests.Visual.Spectator protected override Task SendFramesInternal(FrameDataBundle bundle) { + FrameSendAttempts++; + if (ShouldFailSendingFrames) return Task.FromException(new InvalidOperationException());