Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit 08dd9bb

Browse files
Resolve IAsyncCommand / IAsyncValueValueCommand Unit Test Race Condition (#1076)
* Add Unit Test Timeouts * Add macOS Unit Tests * Build 'samples/XCT.Sample.sln' on macOS * Restore Unit Test NuGet Packages * Fix YAML formatting * Add xunit.runner.console * Use latest stable version of Microsoft.NET.Test.Sdk * Fix Unit Tests on macos * Update azure-pipelines.yml * Update azure-pipelines.yml * Update azure-pipelines.yml * Add SemaphoreSlim * Add `dotnet restore` * Update azure-pipelines.yml * Update azure-pipelines.yml * Revert "Add SemaphoreSlim" This reverts commit 6875865. * Revert BaseCommand.semaphoreSlim * Update azure-pipelines.yml * Update azure-pipelines.yml * Update azure-pipelines.yml * Add ConfigureAwait(false) to ValueTaskDelay(int) * Change Platform from NetCore to macOS * Passthrough ValueTask * Update azure-pipelines.yml * Revert "Update azure-pipelines.yml" This reverts commit d7b2842. * Use ConfigureAwait(false) * Rename Task * Remove `static` * Remove `static` * Revert p:BuildInParallel=false * Update azure-pipelines.yml * Revert "Update azure-pipelines.yml" This reverts commit bf93f0c. * Revert "Revert "Update azure-pipelines.yml"" This reverts commit 031121a. * Revert "Revert "Revert "Update azure-pipelines.yml""" This reverts commit 458feb2.
1 parent f7e6700 commit 08dd9bb

File tree

12 files changed

+71
-39
lines changed

12 files changed

+71
-39
lines changed

azure-pipelines.yml

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ variables:
1010
NETCORE_TEST_VERSION_3_1: '3.1.x'
1111
NETCORE_TEST_VERSION_2_1: '2.1.x'
1212
RunPoliCheck: 'false'
13-
PathToCsproj: 'src/CommunityToolkit/Xamarin.CommunityToolkit/Xamarin.CommunityToolkit.csproj'
1413
PathToMarkupCsproj: 'src/Markup/Xamarin.CommunityToolkit.Markup/Xamarin.CommunityToolkit.Markup.csproj'
14+
PathToCommunityToolkitCsproj: 'src/CommunityToolkit/Xamarin.CommunityToolkit/Xamarin.CommunityToolkit.csproj'
15+
PathToSamplesSln: 'samples/XCT.Sample.sln'
1516
PathToUnitTestCsproj: 'src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/Xamarin.CommunityToolkit.UnitTests.csproj'
17+
PathToMsBuildOnMacOS: 'mono /Applications/Visual\ studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/MSBuild.dll'
1618
PathToSln: 'samples/XCT.Sample.sln'
1719

1820
resources:
@@ -95,9 +97,9 @@ jobs:
9597
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/')
9698
# restore, build and pack the packages
9799
- task: MSBuild@1
98-
displayName: Build Solution
100+
displayName: Build Xamarin.CommunityToolkit.csproj
99101
inputs:
100-
solution: $(PathToCsproj)
102+
solution: $(PathToCommunityToolkitCsproj)
101103
configuration: Release
102104
msbuildArguments: '/restore /t:Build /p:ContinuousIntegrationBuild=true /p:Deterministic=false'
103105
- task: CopyFiles@2
@@ -107,7 +109,7 @@ jobs:
107109
- task: MSBuild@1
108110
displayName: Pack NuGets
109111
inputs:
110-
solution: $(PathToCsproj)
112+
solution: $(PathToCommunityToolkitCsproj)
111113
configuration: Release
112114
msbuildArguments: '/t:Pack /p:PackageVersion=$(NugetPackageVersion) /p:PackageOutputPath="$(Build.ArtifactStagingDirectory)/nuget"'
113115
- task: MSBuild@1
@@ -191,13 +193,29 @@ jobs:
191193
version: $(NETCORE_TEST_VERSION_2_1)
192194
includePreviewVersions: false
193195
- task: CmdLine@2
194-
displayName: 'Build Solution'
196+
displayName: 'Build Xamarin.CommunityToolkit.csproj'
197+
inputs:
198+
script: '$(PathToMsBuildOnMacOS) $(PathToCommunityToolkitCsproj) /p:Configuration=Release /restore /t:Build /p:ContinuousIntegrationBuild=true /p:Deterministic=false'
199+
- task: CmdLine@2
200+
displayName: 'Run Unit Tests'
195201
inputs:
196-
script: 'mono /Applications/Visual\ studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/MSBuild.dll $(PathToCsproj) /p:Configuration=Release /restore /t:Build /p:ContinuousIntegrationBuild=true /p:Deterministic=false'
202+
script: |
203+
dotnet restore $(PathToUnitTestCsproj) /p:Configuration=Release
204+
$(PathToMsBuildOnMacOS) $(PathToUnitTestCsproj) /p:Configuration=Release /restore /t:Build
205+
206+
echo "********** Running Unit Tests on .NET Framework (xUnit does not support dotnet test for .NET Framework: https://xunit.net/docs/getting-started/netfx/cmdline) **********"
207+
208+
# UnitTestDLL for .NET Framework 4.6.1 Result: `find . -name Xamarin.CommunityToolkit.UnitTests.dll | grep bin | grep 461`
209+
# XUnit Console Runner for .NET Framework 4.6.1 Result: `find ~/.nuget/packages | grep net461 | grep xunit.console.exe | grep -v config`
210+
211+
mono "`find ~/.nuget/packages | grep net461 | grep xunit.console.exe | grep -v config`" "`find . -name Xamarin.CommunityToolkit.UnitTests.dll | grep bin | grep 461`"
212+
213+
echo "***** Running Unit Tests on .NET Core *****"
214+
dotnet test $(PathToUnitTestCsproj) /p:Configuration=Release /p:Platform="macOS"
197215
- task: CmdLine@2
198216
displayName: 'Pack NuGets'
199217
inputs:
200-
script: 'mono /Applications/Visual\ studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/MSBuild.dll $(PathToCsproj) /p:Configuration=Release /t:Pack /p:PackageVersion=$(NugetPackageVersion) /p:PackageOutputPath="$(Build.ArtifactStagingDirectory)/nuget"'
218+
script: '$(PathToMsBuildOnMacOS) $(PathToCommunityToolkitCsproj) /p:Configuration=Release /t:Pack /p:PackageVersion=$(NugetPackageVersion) /p:PackageOutputPath="$(Build.ArtifactStagingDirectory)/nuget"'
201219

202220
- ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
203221
- template: sign-artifacts/jobs/v2.yml@internal-templates

src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/Helpers/LocalizedStringTests/LocalizedStringTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ public void LocalizedStringTests_WeekSubscribe_ValidImplementation()
7777
Assert.True(isTrigered);
7878
}
7979

80+
#if NET461
81+
#warning Test fails on mono x64 Running on macOS
82+
#else
8083
[Fact]
8184
public void LocalizedStringTests_Disposed_IfNoReferences()
8285
{
@@ -97,5 +100,6 @@ void SetLocalizedString()
97100
localizedString = new LocalizedString(localizationManager, () => localizationManager[testString]);
98101
}
99102
}
103+
#endif
100104
}
101105
}

src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/ObjectModel/ICommandTests/AsyncCommandTests/AsyncCommand_Tests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public void AsyncCommand_NoParameter_NoCanExecute_Test()
164164
Assert.True(command.CanExecute(null));
165165
}
166166

167-
[Fact]
167+
[Fact(Timeout = ICommandTestTimeout)]
168168
public async Task AsyncCommand_RaiseCanExecuteChanged_MainThreadCreation_MainThreadExecution_Test()
169169
{
170170
// Arrange
@@ -213,7 +213,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
213213
}
214214
}
215215

216-
[Fact]
216+
[Fact(Timeout = ICommandTestTimeout)]
217217
public Task AsyncCommand_RaiseCanExecuteChanged_BackgroundThreadCreation_BackgroundThreadExecution_Test() => Task.Run(async () =>
218218
{
219219
// Arrange
@@ -267,7 +267,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
267267
}
268268
});
269269

270-
[Fact]
270+
[Fact(Timeout = ICommandTestTimeout)]
271271
public async Task AsyncCommand_RaiseCanExecuteChanged_MainThreadCreation_BackgroundThreadExecution_Test()
272272
{
273273
// Arrange
@@ -322,7 +322,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
322322
}
323323
}
324324

325-
[Fact]
325+
[Fact(Timeout = ICommandTestTimeout)]
326326
public async Task AsyncCommand_RaiseCanExecuteChanged_BackgroundThreadCreation_MainThreadExecution_Test()
327327
{
328328
// Arrange
@@ -380,7 +380,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
380380
}
381381
}
382382

383-
[Fact]
383+
[Fact(Timeout = ICommandTestTimeout)]
384384
public async Task AsyncCommand_ChangeCanExecute_Test()
385385
{
386386
// Arrange
@@ -429,7 +429,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
429429
}
430430
}
431431

432-
[Fact]
432+
[Fact(Timeout = ICommandTestTimeout)]
433433
public async Task AsyncCommand_CanExecuteChanged_AllowsMultipleExecutions_Test()
434434
{
435435
// Arrange
@@ -459,7 +459,7 @@ public async Task AsyncCommand_CanExecuteChanged_AllowsMultipleExecutions_Test()
459459
void handleCanExecuteChanged(object? sender, EventArgs e) => canExecuteChangedCount++;
460460
}
461461

462-
[Fact]
462+
[Fact(Timeout = ICommandTestTimeout)]
463463
public async Task AsyncCommand_CanExecuteChanged_DoesNotAllowMultipleExecutions_Test()
464464
{
465465
// Arrange

src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/ObjectModel/ICommandTests/AsyncCommandTests/IAsyncCommand_Tests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public void IAsyncCommand_NoParameter_CanExecuteFalse_NoParameter_Test()
177177
Assert.False(command.CanExecute(null));
178178
}
179179

180-
[Fact]
180+
[Fact(Timeout = ICommandTestTimeout)]
181181
public async Task IAsyncCommand_CanExecuteChanged_AllowsMultipleExecutions_Test()
182182
{
183183
// Arrange
@@ -207,7 +207,7 @@ public async Task IAsyncCommand_CanExecuteChanged_AllowsMultipleExecutions_Test(
207207
void handleCanExecuteChanged(object? sender, EventArgs e) => canExecuteChangedCount++;
208208
}
209209

210-
[Fact]
210+
[Fact(Timeout = ICommandTestTimeout)]
211211
public async Task IAsyncCommand_CanExecuteChanged_DoesNotAllowMultipleExecutions_Test()
212212
{
213213
// Arrange

src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/ObjectModel/ICommandTests/AsyncCommandTests/ICommand_AsyncCommand_Tests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ public void ICommand_Parameter_CanExecuteChanged_Test()
190190
Assert.False(command.CanExecute(false));
191191
}
192192

193-
[Fact]
193+
[Fact(Timeout = ICommandTestTimeout)]
194194
public async Task ICommand_Parameter_CanExecuteChanged_AllowsMultipleExecutions_Test()
195195
{
196196
// Arrange
@@ -218,7 +218,7 @@ public async Task ICommand_Parameter_CanExecuteChanged_AllowsMultipleExecutions_
218218
command.CanExecuteChanged -= handleCanExecuteChanged;
219219
}
220220

221-
[Fact]
221+
[Fact(Timeout = ICommandTestTimeout)]
222222
public async Task ICommand_Parameter_CanExecuteChanged_DoesNotAllowMultipleExecutions_Test()
223223
{
224224
// Arrange
@@ -263,7 +263,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
263263
}
264264
}
265265

266-
[Fact]
266+
[Fact(Timeout = ICommandTestTimeout)]
267267
public async Task ICommand_NoParameter_CanExecuteChanged_AllowsMultipleExecutions_Test()
268268
{
269269
// Arrange
@@ -291,7 +291,7 @@ public async Task ICommand_NoParameter_CanExecuteChanged_AllowsMultipleExecution
291291
command.CanExecuteChanged -= handleCanExecuteChanged;
292292
}
293293

294-
[Fact]
294+
[Fact(Timeout = ICommandTestTimeout)]
295295
public async Task ICommand_NoParameter_CanExecuteChanged_DoesNotAllowMultipleExecutions_Test()
296296
{
297297
// Arrange

src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/ObjectModel/ICommandTests/AsyncValueCommandTests/AsyncValueCommand_Tests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ public void AsyncValueCommandNoParameter_NoCanExecute_Test()
187187
Assert.True(command.CanExecute(null));
188188
}
189189

190-
[Fact]
190+
[Fact(Timeout = ICommandTestTimeout)]
191191
public async Task AsyncValueCommand_RaiseCanExecuteChanged_Test()
192192
{
193193
// Arrange
@@ -236,7 +236,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
236236
}
237237
}
238238

239-
[Fact]
239+
[Fact(Timeout = ICommandTestTimeout)]
240240
public async Task AsyncValueCommand_ChangeCanExecute_Test()
241241
{
242242
// Arrange
@@ -285,7 +285,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
285285
}
286286
}
287287

288-
[Fact]
288+
[Fact(Timeout = ICommandTestTimeout)]
289289
public async Task AsyncValueCommand_Parameter_CanExecuteChanged_AllowsMultipleExecutions_Test()
290290
{
291291
// Arrange
@@ -315,7 +315,7 @@ public async Task AsyncValueCommand_Parameter_CanExecuteChanged_AllowsMultipleEx
315315
command.CanExecuteChanged -= handleCanExecuteChanged;
316316
}
317317

318-
[Fact]
318+
[Fact(Timeout = ICommandTestTimeout)]
319319
public async Task AsyncValueCommand_Parameter_CanExecuteChanged_DoesNotAllowMultipleExecutions_Test()
320320
{
321321
// Arrange
@@ -363,7 +363,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
363363
Assert.Equal(canExecuteChangedCount, handleCanExecuteChangedResult);
364364
}
365365

366-
[Fact]
366+
[Fact(Timeout = ICommandTestTimeout)]
367367
public async Task AsyncValueCommand_NoParameter_CanExecuteChanged_AllowsMultipleExecutions_Test()
368368
{
369369
// Arrange
@@ -393,7 +393,7 @@ public async Task AsyncValueCommand_NoParameter_CanExecuteChanged_AllowsMultiple
393393
command.CanExecuteChanged -= handleCanExecuteChanged;
394394
}
395395

396-
[Fact]
396+
[Fact(Timeout = ICommandTestTimeout)]
397397
public async Task AsyncValueCommand_NoParameter_CanExecuteChanged_DoesNotAllowMultipleExecutions_Test()
398398
{
399399
// Arrange

src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/ObjectModel/ICommandTests/AsyncValueCommandTests/BaseAsyncValueCommandTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ public abstract class BaseAsyncValueCommandTests : BaseCommandTests
1515

1616
protected new ValueTask ParameterImmediateNullReferenceExceptionTask(int delay) => throw new NullReferenceException();
1717

18-
protected async ValueTask ValueTaskDelay(int delay) => await Task.Delay(delay);
19-
2018
protected new async ValueTask NoParameterDelayedNullReferenceExceptionTask()
2119
{
2220
await Task.Delay(Delay);
@@ -28,5 +26,7 @@ public abstract class BaseAsyncValueCommandTests : BaseCommandTests
2826
await Task.Delay(delay);
2927
throw new NullReferenceException();
3028
}
29+
30+
ValueTask ValueTaskDelay(int delay) => new ValueTask(Task.Delay(delay));
3131
}
3232
}

src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/ObjectModel/ICommandTests/AsyncValueCommandTests/ICommand_AsyncValueCommand_Tests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public void ICommand_Parameter_CanExecuteChanged_Test()
216216
Assert.False(command.CanExecute(false));
217217
}
218218

219-
[Fact]
219+
[Fact(Timeout = ICommandTestTimeout)]
220220
public async Task ICommand_Parameter_CanExecuteChanged_AllowsMultipleExecutions_Test()
221221
{
222222
// Arrange
@@ -243,7 +243,7 @@ public async Task ICommand_Parameter_CanExecuteChanged_AllowsMultipleExecutions_
243243
command.CanExecuteChanged -= handleCanExecuteChanged;
244244
}
245245

246-
[Fact]
246+
[Fact(Timeout = ICommandTestTimeout)]
247247
public async Task ICommand_Parameter_CanExecuteChanged_DoesNotAllowMultipleExecutions_Test()
248248
{
249249
// Arrange
@@ -287,7 +287,7 @@ async void handleCanExecuteChanged(object? sender, EventArgs e)
287287
Assert.Equal(canExecuteChangedCount, handleCanExecuteChangedResult);
288288
}
289289

290-
[Fact]
290+
[Fact(Timeout = ICommandTestTimeout)]
291291
public async Task ICommand_NoParameter_CanExecuteChanged_AllowsMultipleExecutions_Test()
292292
{
293293
// Arrange
@@ -315,7 +315,7 @@ public async Task ICommand_NoParameter_CanExecuteChanged_AllowsMultipleExecution
315315
command.CanExecuteChanged -= handleCanExecuteChanged;
316316
}
317317

318-
[Fact]
318+
[Fact(Timeout = ICommandTestTimeout)]
319319
public async Task ICommand_NoParameter_CanExecuteChanged_DoesNotAllowMultipleExecutions_Test()
320320
{
321321
// Arrange

src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/ObjectModel/ICommandTests/BaseCommandTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Xamarin.CommunityToolkit.UnitTests.ObjectModel.ICommandTests
99
[Collection(nameof(BaseCommandTests))]
1010
public abstract class BaseCommandTests
1111
{
12+
public const int ICommandTestTimeout = Delay * 6;
1213
public const int Delay = 500;
1314

1415
public BaseCommandTests() => Device.PlatformServices = new MockPlatformServices();

src/CommunityToolkit/Xamarin.CommunityToolkit.UnitTests/Xamarin.CommunityToolkit.UnitTests.csproj

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
3+
<PropertyGroup Condition="'$(Platform)'=='macOS'">
4+
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
5+
<IsPackable>false</IsPackable>
6+
</PropertyGroup>
7+
8+
<PropertyGroup Condition="'$(Platform)'!='macOS'">
49
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net461</TargetFrameworks>
510
<IsPackable>false</IsPackable>
611
</PropertyGroup>
712

813
<ItemGroup>
9-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
1015
<PackageReference Include="NSubstitute" Version="4.2.2" />
1116
<PackageReference Include="xunit" Version="2.4.1" />
1217
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
@@ -17,6 +22,10 @@
1722
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1823
<PrivateAssets>all</PrivateAssets>
1924
</PackageReference>
25+
<PackageReference Include="xunit.runner.console" Version="2.4.1">
26+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
27+
<PrivateAssets>all</PrivateAssets>
28+
</PackageReference>
2029
</ItemGroup>
2130

2231
<ItemGroup>

0 commit comments

Comments
 (0)