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);