@@ -18,13 +18,14 @@ namespace ManagedCode.Orleans.SignalR.Tests;
1818public class StressTests
1919{
2020 private const string StressGroup = "stress-group" ;
21+ private const int StressConnectionCount = 211 ;
22+ private const int BroadcastsPerConnection = 233 ;
23+ private const int GroupWorkflowIterations = 29 ;
2124 private static readonly TimeSpan WaitInterval = TimeSpan . FromMilliseconds ( 200 ) ;
2225 private static readonly TimeSpan LogInterval = TimeSpan . FromSeconds ( 1 ) ;
2326
24- private readonly TestWebApplication _firstApp ;
27+ private readonly IReadOnlyList < TestWebApplication > _apps ;
2528 private readonly ITestOutputHelper _outputHelper ;
26- private readonly Random _random = new ( 42 ) ;
27- private readonly TestWebApplication _secondApp ;
2829 private readonly LoadClusterFixture _siloCluster ;
2930 private readonly TestOutputHelperAccessor _loggerAccessor = new ( ) ;
3031
@@ -33,25 +34,24 @@ public StressTests(LoadClusterFixture testApp, ITestOutputHelper outputHelper)
3334 _siloCluster = testApp ;
3435 _outputHelper = outputHelper ;
3536 _loggerAccessor . Output = outputHelper ;
36- _firstApp = new TestWebApplication ( _siloCluster , 8081 , loggerAccessor : _loggerAccessor ) ;
37- _secondApp = new TestWebApplication ( _siloCluster , 8082 , loggerAccessor : _loggerAccessor ) ;
37+ _apps = Enumerable . Range ( 0 , 4 )
38+ . Select ( index => new TestWebApplication ( _siloCluster , 8081 + index , loggerAccessor : _loggerAccessor ) )
39+ . ToArray ( ) ;
3840 }
3941
4042 [ Fact ]
4143 public async Task InvokeAsyncSignalRTest ( )
4244 {
43- const int totalConnections = 6 ;
44- const int broadcastsPerSender = 10 ;
45- var expectedMessages = ( long ) totalConnections * broadcastsPerSender ;
45+ var expectedMessages = ( long ) StressConnectionCount * BroadcastsPerConnection ;
4646
47- _outputHelper . WriteLine ( $ "Creating { totalConnections } connections for stress broadcast test.") ;
48- var connections = new List < HubConnection > ( totalConnections ) ;
47+ _outputHelper . WriteLine ( $ "Creating { StressConnectionCount } connections for stress broadcast test.") ;
48+ var connections = new List < HubConnection > ( StressConnectionCount ) ;
4949 var observedMessages = 0L ;
5050 var completionSource = new TaskCompletionSource ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
5151
52- for ( var connectionIndex = 0 ; connectionIndex < totalConnections ; connectionIndex ++ )
52+ async Task < HubConnection > CreateAsync ( int connectionIndex )
5353 {
54- var started = await CreateStressConnectionAsync ( connectionIndex , ( ) =>
54+ return await CreateStressConnectionAsync ( connectionIndex , ( ) =>
5555 {
5656 var total = Interlocked . Increment ( ref observedMessages ) ;
5757 if ( total >= expectedMessages )
@@ -61,21 +61,25 @@ public async Task InvokeAsyncSignalRTest()
6161
6262 return total ;
6363 } ) ;
64- connections . Add ( started ) ;
6564 }
6665
66+ var connectionTasks = Enumerable . Range ( 0 , StressConnectionCount )
67+ . Select ( CreateAsync )
68+ . ToArray ( ) ;
69+ connections . AddRange ( await Task . WhenAll ( connectionTasks ) ) ;
70+
6771 var stopwatch = Stopwatch . StartNew ( ) ;
6872 var sendTasks = connections . Select ( connection => Task . Run ( async ( ) =>
6973 {
70- for ( var iteration = 0 ; iteration < broadcastsPerSender ; iteration ++ )
74+ for ( var iteration = 0 ; iteration < BroadcastsPerConnection ; iteration ++ )
7175 {
7276 await connection . InvokeAsync < int > ( "All" ) ;
7377 }
7478 } ) ) ;
7579
7680 await Task . WhenAll ( sendTasks ) ;
7781
78- var finishedTask = await Task . WhenAny ( completionSource . Task , Task . Delay ( TimeSpan . FromSeconds ( 10 ) ) ) ;
82+ var finishedTask = await Task . WhenAny ( completionSource . Task , Task . Delay ( TimeSpan . FromSeconds ( 45 ) ) ) ;
7983 finishedTask . ShouldBe ( completionSource . Task , $ "Timed out delivering { expectedMessages : N0} broadcast messages; observed { Interlocked . Read ( ref observedMessages ) : N0} .") ;
8084
8185 stopwatch . Stop ( ) ;
@@ -108,19 +112,21 @@ async Task<GrainCounts> FetchCountsAsync()
108112 var before = await FetchCountsAsync ( ) ;
109113 _outputHelper . WriteLine ( $ "Initial grain counts: { before } ") ;
110114
111- var hubConnection = await CreateUserConnectionAsync ( "stress-user" , _firstApp , nameof ( SimpleTestHub ) ) ;
115+ var hubConnection = await CreateUserConnectionAsync ( "stress-user" , _apps [ 0 ] , nameof ( SimpleTestHub ) ) ;
112116 hubConnection . On ( "GetMessage" , ( ) => "connection1" ) ;
113117
114118 await hubConnection . StartAsync ( ) ;
115119 hubConnection . State . ShouldBe ( HubConnectionState . Connected ) ;
116120 _outputHelper . WriteLine ( $ "Stress connection started with id { hubConnection . ConnectionId } .") ;
117121
118- for ( var iteration = 0 ; iteration < 6 ; iteration ++ )
119- {
120- await hubConnection . InvokeAsync < int > ( "DoTest" ) ;
121- await hubConnection . InvokeAsync ( "AddToGroup" , StressGroup ) ;
122- await hubConnection . InvokeAsync ( "GroupSendAsync" , StressGroup , $ "payload-{ iteration } ") ;
123- }
122+ var workflowTasks = Enumerable . Range ( 0 , GroupWorkflowIterations )
123+ . Select ( async iteration =>
124+ {
125+ await hubConnection . InvokeAsync < int > ( "DoTest" ) ;
126+ await hubConnection . InvokeAsync ( "AddToGroup" , StressGroup ) ;
127+ await hubConnection . InvokeAsync ( "GroupSendAsync" , StressGroup , $ "payload-{ iteration } ") ;
128+ } ) ;
129+ await Task . WhenAll ( workflowTasks ) ;
124130
125131 await Task . Delay ( TimeSpan . FromMilliseconds ( 250 ) ) ;
126132
@@ -166,8 +172,8 @@ await _siloCluster.Cluster.Client.GetGrain<IManagementGrain>(0)
166172
167173 private async Task < HubConnection > CreateStressConnectionAsync ( int index , Func < long > onBroadcastReceived )
168174 {
169- var useUser = _random . NextDouble ( ) < 0.5 ;
170- var app = _random . NextDouble ( ) < 0.5 ? _firstApp : _secondApp ;
175+ var useUser = Random . Shared . NextDouble ( ) < 0.5 ;
176+ var app = _apps [ Random . Shared . Next ( _apps . Count ) ] ;
171177 HubConnection connection ;
172178 string ? userId = null ;
173179
@@ -201,7 +207,7 @@ private async Task<HubConnection> CreateStressConnectionAsync(int index, Func<lo
201207 connection . State . ShouldBe ( HubConnectionState . Connected ) ;
202208 _outputHelper . WriteLine ( $ "[stress#{ index } ] connected (ConnectionId={ connection . ConnectionId } , user={ userId ?? "anonymous" } ).") ;
203209
204- if ( _random . NextDouble ( ) < 0.35 )
210+ if ( Random . Shared . NextDouble ( ) < 0.35 )
205211 {
206212 await connection . InvokeAsync ( "AddToGroup" , StressGroup ) ;
207213 _outputHelper . WriteLine ( $ "[stress#{ index } ] joined group { StressGroup } .") ;
0 commit comments