mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-06 12:35:00 +03:00
test: strengthen ProfileExManager concurrency regression coverage (#10410)
This commit is contained in:
committed by
GitHub
parent
8b93d35766
commit
4169c12a1f
@@ -58,18 +58,59 @@ public class ProfileExManagerConcurrencyTests
|
|||||||
{
|
{
|
||||||
var manager = CreateManager();
|
var manager = CreateManager();
|
||||||
|
|
||||||
await Parallel.ForEachAsync(Enumerable.Range(0, 500), new ParallelOptions { MaxDegreeOfParallelism = 32 },
|
await RunConcurrentUpdates(8, 10, (_, index) => manager.SetTestDelay($"same{index}", index));
|
||||||
async (i, ct) =>
|
|
||||||
{
|
|
||||||
manager.SetTestDelay($"same{i % 10}", i);
|
|
||||||
await Task.CompletedTask;
|
|
||||||
});
|
|
||||||
|
|
||||||
var items = await manager.GetProfileExs();
|
var items = await manager.GetProfileExs();
|
||||||
await items.Count.Should().BeEqualTo(10);
|
await items.Count.Should().BeEqualTo(10);
|
||||||
await items.Select(t => t.IndexId).Distinct().Count().Should().BeEqualTo(10);
|
await items.Select(t => t.IndexId).Distinct().Count().Should().BeEqualTo(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task SetTestResults_ConcurrentUpdates_ShouldKeepAllValuesOnOneEntry()
|
||||||
|
{
|
||||||
|
var manager = CreateManager();
|
||||||
|
Action<string>[] updates =
|
||||||
|
[
|
||||||
|
indexId => manager.SetTestDelay(indexId, 123),
|
||||||
|
indexId => manager.SetTestSpeed(indexId, 45.6m),
|
||||||
|
indexId => manager.SetTestMessage(indexId, "result"),
|
||||||
|
indexId => manager.SetTestIpInfo(indexId, "203.0.113.1"),
|
||||||
|
indexId => manager.SetSort(indexId, 7)
|
||||||
|
];
|
||||||
|
|
||||||
|
await RunConcurrentUpdates(updates.Length, 100, (worker, index) => updates[worker]($"profile{index}"));
|
||||||
|
|
||||||
|
var items = await manager.GetProfileExs();
|
||||||
|
await items.Count.Should().BeEqualTo(100);
|
||||||
|
await items.Select(item => item.IndexId).Distinct().Count().Should().BeEqualTo(100);
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
await item.Delay.Should().BeEqualTo(123);
|
||||||
|
await item.Speed.Should().BeEqualTo(45.6m);
|
||||||
|
await item.Message.Should().BeEqualTo("result");
|
||||||
|
await item.IpInfo.Should().BeEqualTo("203.0.113.1");
|
||||||
|
await item.Sort.Should().BeEqualTo(7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task RunConcurrentUpdates(int workers, int indexes, Action<int, int> update)
|
||||||
|
{
|
||||||
|
using var barrier = new Barrier(workers);
|
||||||
|
var tasks = Enumerable.Range(0, workers).Select(worker => Task.Factory.StartNew(() =>
|
||||||
|
{
|
||||||
|
for (var index = 0; index < indexes; index++)
|
||||||
|
{
|
||||||
|
if (!barrier.SignalAndWait(TimeSpan.FromSeconds(10)))
|
||||||
|
{
|
||||||
|
throw new TimeoutException("Concurrent update workers did not synchronize.");
|
||||||
|
}
|
||||||
|
update(worker, index);
|
||||||
|
}
|
||||||
|
}, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default)).ToArray();
|
||||||
|
|
||||||
|
await Task.WhenAll(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
private static ProfileExManager CreateManager()
|
private static ProfileExManager CreateManager()
|
||||||
{
|
{
|
||||||
return (ProfileExManager)Activator.CreateInstance(typeof(ProfileExManager), nonPublic: true)!;
|
return (ProfileExManager)Activator.CreateInstance(typeof(ProfileExManager), nonPublic: true)!;
|
||||||
|
|||||||
Reference in New Issue
Block a user