Skip to content

Commit c909569

Browse files
committed
Adding test for race condition when managing groups (#43)
1 parent 11ac4e3 commit c909569

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System;
2+
using System.Linq;
3+
using System.Security.Claims;
4+
using System.Threading.Tasks;
5+
using System.Collections.Generic;
6+
using Microsoft.AspNetCore.Http;
7+
using Microsoft.Extensions.Options;
8+
using Xunit;
9+
using Lib.AspNetCore.ServerSentEvents;
10+
using Lib.AspNetCore.ServerSentEvents.Internals;
11+
12+
namespace Test.AspNetCore.ServerSentEvents
13+
{
14+
public class ServerSentEventsServiceTests
15+
{
16+
#region Prepare SUT
17+
private static async Task<ServerSentEventsClient> PrepareAndAddServerSentEventsClientAsync(ServerSentEventsService serverSentEventsService)
18+
{
19+
HttpContext context = new DefaultHttpContext();
20+
ServerSentEventsClient serverSentEventsClient = new ServerSentEventsClient(Guid.NewGuid(), new ClaimsPrincipal(), context.Response, false);
21+
22+
await serverSentEventsService.OnConnectAsync(context.Request, serverSentEventsClient);
23+
24+
serverSentEventsService.AddClient(serverSentEventsClient);
25+
26+
return serverSentEventsClient;
27+
}
28+
#endregion
29+
30+
#region Tests
31+
[Fact]
32+
public void RemoveClient_ClientsBeingAddedToGroupsInParaller_NoRaceCondition()
33+
{
34+
// ARRANGE
35+
ServerSentEventsService serverSentEventsService = new ServerSentEventsService(Options.Create<ServerSentEventsServiceOptions<ServerSentEventsService>>(new ServerSentEventsServiceOptions<ServerSentEventsService>
36+
{
37+
OnClientConnected = async (service, clientConnectedArgs) =>
38+
{
39+
for (var i = 0; i < 1000; i++)
40+
{
41+
await service.AddToGroupAsync(Guid.NewGuid().ToString(), clientConnectedArgs.Client);
42+
}
43+
}
44+
}));
45+
46+
// ACT
47+
Task[] clientsTasks = new Task[100];
48+
for (int i = 0; i < clientsTasks.Length; i++)
49+
{
50+
clientsTasks[i] = Task.Run(async () =>
51+
{
52+
ServerSentEventsClient serverSentEventsClient = await PrepareAndAddServerSentEventsClientAsync(serverSentEventsService);
53+
54+
await Task.Delay(100);
55+
56+
serverSentEventsService.RemoveClient(serverSentEventsClient);
57+
});
58+
}
59+
Exception recordedException = Record.Exception(() => Task.WaitAll(clientsTasks));
60+
61+
// ASSERT
62+
Assert.False((recordedException as AggregateException)?.InnerExceptions.Any(ex => (ex as InvalidOperationException)?.Message.Contains("Collection was modified") ?? false) ?? false);
63+
}
64+
65+
[Fact]
66+
public async Task GetClients_GroupNameProvidedAndClientInGroup_ReturnsClient()
67+
{
68+
// ARRANGE
69+
const string serverSentEventsClientsGroupName = nameof(GetClients_GroupNameProvidedAndClientInGroup_ReturnsClient);
70+
ServerSentEventsService serverSentEventsService = new ServerSentEventsService(Options.Create<ServerSentEventsServiceOptions<ServerSentEventsService>>(new ServerSentEventsServiceOptions<ServerSentEventsService>
71+
{
72+
OnClientConnected = async (service, clientConnectedArgs) =>
73+
{
74+
await service.AddToGroupAsync(serverSentEventsClientsGroupName, clientConnectedArgs.Client);
75+
}
76+
}));
77+
ServerSentEventsClient serverSentEventsClient = await PrepareAndAddServerSentEventsClientAsync(serverSentEventsService);
78+
79+
// ACT
80+
IReadOnlyCollection<IServerSentEventsClient> serverSentEventsClientsGroup = serverSentEventsService.GetClients(serverSentEventsClientsGroupName);
81+
82+
// ASSERT
83+
Assert.Single(serverSentEventsClientsGroup, serverSentEventsClient);
84+
}
85+
#endregion
86+
}
87+
}

0 commit comments

Comments
 (0)