1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-26 18:42:56 +08:00

Add ability to simulate network failures to TestSpectatorClient

This commit is contained in:
Dean Herbert 2022-02-24 02:18:35 +09:00
parent 14c8ce50a0
commit c94e7e2abe
4 changed files with 22 additions and 8 deletions

View File

@ -321,7 +321,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private void sendFrames(int count = 10) 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() private void loadSpectatingScreen()

View File

@ -68,10 +68,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
// For player 2, send frames in sets of 10. // For player 2, send frames in sets of 10.
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {
SpectatorClient.SendFrames(PLAYER_1_ID, 1); SpectatorClient.SendFramesFromUser(PLAYER_1_ID, 1);
if (i % 10 == 0) if (i % 10 == 0)
SpectatorClient.SendFrames(PLAYER_2_ID, 10); SpectatorClient.SendFramesFromUser(PLAYER_2_ID, 10);
} }
}); });

View File

@ -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(). // 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) // (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); AddUntilStep("wait for player load", () => spectatorScreen.AllPlayersLoaded);
@ -424,7 +424,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("send frames", () => AddStep("send frames", () =>
{ {
foreach (int id in userIds) foreach (int id in userIds)
SpectatorClient.SendFrames(id, count); SpectatorClient.SendFramesFromUser(id, count);
}); });
} }

View File

@ -3,6 +3,7 @@
#nullable enable #nullable enable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -20,10 +21,15 @@ namespace osu.Game.Tests.Visual.Spectator
public class TestSpectatorClient : SpectatorClient public class TestSpectatorClient : SpectatorClient
{ {
/// <summary> /// <summary>
/// Maximum number of frames sent per bundle via <see cref="SendFrames"/>. /// Maximum number of frames sent per bundle via <see cref="SendFramesFromUser"/>.
/// </summary> /// </summary>
public const int FRAME_BUNDLE_SIZE = 10; public const int FRAME_BUNDLE_SIZE = 10;
/// <summary>
/// Whether to force send operations to fail (simulating a network issue).
/// </summary>
public bool ShouldFailSendingFrames { get; set; }
public override IBindable<bool> IsConnected { get; } = new Bindable<bool>(true); public override IBindable<bool> IsConnected { get; } = new Bindable<bool>(true);
public IReadOnlyDictionary<int, ReplayFrame> LastReceivedUserFrames => lastReceivedUserFrames; public IReadOnlyDictionary<int, ReplayFrame> LastReceivedUserFrames => lastReceivedUserFrames;
@ -75,10 +81,12 @@ namespace osu.Game.Tests.Visual.Spectator
/// <summary> /// <summary>
/// Sends frames for an arbitrary user, in bundles containing 10 frames each. /// 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, <see cref="ShouldFailSendingFrames"/> will have no effect.
/// </summary> /// </summary>
/// <param name="userId">The user to send frames for.</param> /// <param name="userId">The user to send frames for.</param>
/// <param name="count">The total number of frames to send.</param> /// <param name="count">The total number of frames to send.</param>
public void SendFrames(int userId, int count) public void SendFramesFromUser(int userId, int count)
{ {
var frames = new List<LegacyReplayFrame>(); var frames = new List<LegacyReplayFrame>();
@ -120,7 +128,13 @@ namespace osu.Game.Tests.Visual.Spectator
return ((ISpectatorClient)this).UserBeganPlaying(api.LocalUser.Value.Id, state); 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); protected override Task EndPlayingInternal(SpectatorState state) => ((ISpectatorClient)this).UserFinishedPlaying(api.LocalUser.Value.Id, state);