mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 18:26:39 +02:00
Fixing potential race condition in ListRepository. Now internally implemented as a concurrent dictionary.
This commit is contained in:
@@ -3,7 +3,10 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Media.Capture;
|
||||
using Wox.Infrastructure.Storage;
|
||||
|
||||
namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
@@ -17,8 +20,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
{
|
||||
//Arrange
|
||||
var itemName = "originalItem1";
|
||||
var mockStorage = new Mock<IStorage<IList<string>>>();
|
||||
IRepository<string> repository = new ListRepository<string>(mockStorage.Object) { itemName };
|
||||
IRepository<string> repository = new ListRepository<string>() { itemName };
|
||||
|
||||
//Act
|
||||
var result = repository.Contains(itemName);
|
||||
@@ -31,8 +33,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
public void Contains_ShouldReturnTrue_WhenListIsUpdatedWithAdd()
|
||||
{
|
||||
//Arrange
|
||||
var mockStorage = new Mock<IStorage<IList<string>>>();
|
||||
IRepository<string> repository = new ListRepository<string>(mockStorage.Object);
|
||||
IRepository<string> repository = new ListRepository<string>();
|
||||
|
||||
//Act
|
||||
var itemName = "newItem";
|
||||
@@ -48,8 +49,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
{
|
||||
//Arrange
|
||||
var itemName = "originalItem1";
|
||||
var mockStorage = new Mock<IStorage<IList<string>>>();
|
||||
IRepository<string> repository = new ListRepository<string>(mockStorage.Object) { itemName };
|
||||
IRepository<string> repository = new ListRepository<string>() { itemName };
|
||||
|
||||
//Act
|
||||
repository.Remove(itemName);
|
||||
@@ -58,5 +58,91 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage
|
||||
//Assert
|
||||
Assert.IsFalse(result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Add_ShouldNotThrow_WhenBeingIterated()
|
||||
{
|
||||
//Arrange
|
||||
ListRepository<string> repository = new ListRepository<string>();
|
||||
var numItems = 1000;
|
||||
for(var i=0; i<numItems;++i)
|
||||
{
|
||||
repository.Add($"OriginalItem_{i}");
|
||||
}
|
||||
|
||||
//Act - Begin iterating on one thread
|
||||
var iterationTask = Task.Run(() =>
|
||||
{
|
||||
var remainingIterations = 10000;
|
||||
while (remainingIterations > 0)
|
||||
{
|
||||
foreach (var item in repository)
|
||||
{
|
||||
//keep iterating
|
||||
|
||||
}
|
||||
--remainingIterations;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//Act - Insert on another thread
|
||||
var addTask = Task.Run(() =>
|
||||
{
|
||||
for (var i = 0; i < numItems; ++i)
|
||||
{
|
||||
repository.Add($"NewItem_{i}");
|
||||
}
|
||||
});
|
||||
|
||||
//Assert that this does not throw. Collections that aren't syncronized will throw an invalidoperatioexception if the list is modified while enumerating
|
||||
Assert.DoesNotThrowAsync(async () =>
|
||||
{
|
||||
await Task.WhenAll(new Task[] { iterationTask, addTask });
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Remove_ShouldNotThrow_WhenBeingIterated()
|
||||
{
|
||||
//Arrange
|
||||
ListRepository<string> repository = new ListRepository<string>();
|
||||
var numItems = 1000;
|
||||
for (var i = 0; i < numItems; ++i)
|
||||
{
|
||||
repository.Add($"OriginalItem_{i}");
|
||||
}
|
||||
|
||||
//Act - Begin iterating on one thread
|
||||
var iterationTask = Task.Run(() =>
|
||||
{
|
||||
var remainingIterations = 10000;
|
||||
while (remainingIterations > 0)
|
||||
{
|
||||
foreach (var item in repository)
|
||||
{
|
||||
//keep iterating
|
||||
|
||||
}
|
||||
--remainingIterations;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//Act - Remove on another thread
|
||||
var addTask = Task.Run(() =>
|
||||
{
|
||||
for (var i = 0; i < numItems; ++i)
|
||||
{
|
||||
repository.Remove($"OriginalItem_{i}");
|
||||
}
|
||||
});
|
||||
|
||||
//Assert that this does not throw. Collections that aren't syncronized will throw an invalidoperatioexception if the list is modified while enumerating
|
||||
Assert.DoesNotThrowAsync(async () =>
|
||||
{
|
||||
await Task.WhenAll(new Task[] { iterationTask, addTask });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user