diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs index d6f8c7addf..d614815316 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs @@ -321,7 +321,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void sendFrames(int count = 10) { - AddStep("send frames", () => spectatorClient.SendFrames(streamingUser.Id, count)); + AddStep("send frames", () => spectatorClient.SendFramesFromUser(streamingUser.Id, count)); } private void loadSpectatingScreen() diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs index 488ecdb8af..42bb99de24 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs @@ -68,10 +68,10 @@ namespace osu.Game.Tests.Visual.Multiplayer // For player 2, send frames in sets of 10. for (int i = 0; i < 100; i++) { - SpectatorClient.SendFrames(PLAYER_1_ID, 1); + SpectatorClient.SendFramesFromUser(PLAYER_1_ID, 1); if (i % 10 == 0) - SpectatorClient.SendFrames(PLAYER_2_ID, 10); + SpectatorClient.SendFramesFromUser(PLAYER_2_ID, 10); } }); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index a785301f62..4b89efe858 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -360,7 +360,7 @@ namespace osu.Game.Tests.Visual.Multiplayer // to ensure negative gameplay start time does not affect spectator, send frames exactly after StartGameplay(). // (similar to real spectating sessions in which the first frames get sent between StartGameplay() and player load complete) - AddStep("send frames at gameplay start", () => getInstance(PLAYER_1_ID).OnGameplayStarted += () => SpectatorClient.SendFrames(PLAYER_1_ID, 100)); + AddStep("send frames at gameplay start", () => getInstance(PLAYER_1_ID).OnGameplayStarted += () => SpectatorClient.SendFramesFromUser(PLAYER_1_ID, 100)); AddUntilStep("wait for player load", () => spectatorScreen.AllPlayersLoaded); @@ -424,7 +424,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("send frames", () => { foreach (int id in userIds) - SpectatorClient.SendFrames(id, count); + SpectatorClient.SendFramesFromUser(id, count); }); } diff --git a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs index 741b489d95..ae5d20f4f4 100644 --- a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs +++ b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs @@ -3,6 +3,7 @@ #nullable enable +using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; @@ -20,10 +21,15 @@ namespace osu.Game.Tests.Visual.Spectator public class TestSpectatorClient : SpectatorClient { /// - /// Maximum number of frames sent per bundle via . + /// Maximum number of frames sent per bundle via . /// public const int FRAME_BUNDLE_SIZE = 10; + /// + /// Whether to force send operations to fail (simulating a network issue). + /// + public bool ShouldFailSendingFrames { get; set; } + public override IBindable IsConnected { get; } = new Bindable(true); public IReadOnlyDictionary LastReceivedUserFrames => lastReceivedUserFrames; @@ -75,10 +81,12 @@ namespace osu.Game.Tests.Visual.Spectator /// /// Sends frames for an arbitrary user, in bundles containing 10 frames each. + /// This bypasses the standard queueing mechanism completely and should only be used to test cases where multiple users need to be sending data. + /// Importantly, will have no effect. /// /// The user to send frames for. /// The total number of frames to send. - public void SendFrames(int userId, int count) + public void SendFramesFromUser(int userId, int count) { var frames = new List(); @@ -120,7 +128,13 @@ namespace osu.Game.Tests.Visual.Spectator return ((ISpectatorClient)this).UserBeganPlaying(api.LocalUser.Value.Id, state); } - protected override Task SendFramesInternal(FrameDataBundle data) => ((ISpectatorClient)this).UserSentFrames(api.LocalUser.Value.Id, data); + protected override Task SendFramesInternal(FrameDataBundle bundle) + { + if (ShouldFailSendingFrames) + return Task.FromException(new InvalidOperationException()); + + return ((ISpectatorClient)this).UserSentFrames(api.LocalUser.Value.Id, bundle); + } protected override Task EndPlayingInternal(SpectatorState state) => ((ISpectatorClient)this).UserFinishedPlaying(api.LocalUser.Value.Id, state);