Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit b9a22fb

Browse files
committed
Added failing test for #1493.
Unfortunately it will only fail on some runs. Seems that if it gets past the first iteration, it will always pass...
1 parent c5f2376 commit b9a22fb

File tree

1 file changed

+58
-3
lines changed

1 file changed

+58
-3
lines changed

test/UnitTests/GitHub.TeamFoundation/VSGitExtTests.cs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
using NUnit.Framework;
1010
using NSubstitute;
1111
using Microsoft.VisualStudio.TeamFoundation.Git.Extensibility;
12+
using System.Threading.Tasks;
13+
using System.Linq;
14+
using GitHub.TeamFoundation.Services;
1215

1316
public class VSGitExtTests
1417
{
@@ -171,9 +174,32 @@ public void ExceptionRefreshingRepositories_ReturnsEmptyList()
171174
repoFactory.Received(1).Create(repoPath);
172175
Assert.That(activeRepositories.Count, Is.EqualTo(0));
173176
}
177+
178+
[Test]
179+
public async Task ThreadingStressTest()
180+
{
181+
for (var i = 0; i < 100; ++i)
182+
{
183+
var gitExt = new MockGitExt();
184+
var repoFactory = new MockRepositoryFactory();
185+
var target = CreateVSGitExt(gitExt: gitExt, repoFactory: repoFactory);
186+
var activeRepositories1 = CreateActiveRepositories("repo1");
187+
var activeRepositories2 = CreateActiveRepositories("repo2");
188+
var task1 = Task.Run(() => gitExt.ActiveRepositories = activeRepositories1);
189+
await Task.Delay(1);
190+
var task2 = Task.Run(() => gitExt.ActiveRepositories = activeRepositories2);
191+
192+
await Task.WhenAll(task1, task2);
193+
194+
Assert.That(
195+
target.ActiveRepositories.Single().LocalPath,
196+
Is.EqualTo("repo2"),
197+
$"Failed at iteration {i}");
198+
}
199+
}
174200
}
175201

176-
static IReadOnlyList<IGitRepositoryInfo> CreateActiveRepositories(IList<string> repositoryPaths)
202+
static IReadOnlyList<IGitRepositoryInfo> CreateActiveRepositories(params string[] repositoryPaths)
177203
{
178204
var repositories = new List<IGitRepositoryInfo>();
179205
foreach (var repositoryPath in repositoryPaths)
@@ -203,9 +229,8 @@ static VSGitExt CreateVSGitExt(IVSUIContext context = null, IGitExt gitExt = nul
203229
return vsGitExt;
204230
}
205231

206-
static IGitExt CreateGitExt(IList<string> repositoryPaths = null)
232+
static IGitExt CreateGitExt(params string[] repositoryPaths)
207233
{
208-
repositoryPaths = repositoryPaths ?? Array.Empty<string>();
209234
var gitExt = Substitute.For<IGitExt>();
210235
var repoList = CreateActiveRepositories(repositoryPaths);
211236
gitExt.ActiveRepositories.Returns(repoList);
@@ -218,4 +243,34 @@ static IVSUIContext CreateVSUIContext(bool isActive)
218243
context.IsActive.Returns(isActive);
219244
return context;
220245
}
246+
247+
class MockGitExt : IGitExt
248+
{
249+
IReadOnlyList<IGitRepositoryInfo> activeRepositories = new IGitRepositoryInfo[0];
250+
251+
public IReadOnlyList<IGitRepositoryInfo> ActiveRepositories
252+
{
253+
get { return activeRepositories; }
254+
set
255+
{
256+
if (activeRepositories != value)
257+
{
258+
activeRepositories = value;
259+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ActiveRepositories)));
260+
}
261+
}
262+
}
263+
264+
public event PropertyChangedEventHandler PropertyChanged;
265+
}
266+
267+
class MockRepositoryFactory : ILocalRepositoryModelFactory
268+
{
269+
public ILocalRepositoryModel Create(string localPath)
270+
{
271+
var result = Substitute.For<ILocalRepositoryModel>();
272+
result.LocalPath.Returns(localPath);
273+
return result;
274+
}
275+
}
221276
}

0 commit comments

Comments
 (0)