Skip to content

Commit c4e8ade

Browse files
authored
multi-target unit tests (#342)
* multi-test * try gate * debug * reorder * multi-version * unique cov id * rename ---------
1 parent 8b62b7b commit c4e8ade

File tree

9 files changed

+102
-44
lines changed

9 files changed

+102
-44
lines changed

.github/workflows/gate.yml

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,69 @@ jobs:
1919
- name: Setup .NET Core
2020
uses: actions/setup-dotnet@v2
2121
with:
22-
dotnet-version: 6.0.x
22+
dotnet-version: |
23+
3.1.x
24+
6.0.x
2325
- name: Install dependencies
2426
run: dotnet restore
2527
- name: Build
2628
run: dotnet build --configuration Release --no-restore
27-
- name: Test
28-
run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutput=TestResults/ /p:CoverletOutputFormat=lcov --logger "trx;LogFileName=results.trx"
29-
- name: Publish NuGet artifacts
30-
uses: actions/upload-artifact@v3
29+
30+
- name: Test (4.8)
31+
run: dotnet test --no-restore --verbosity normal -f net48 --logger "trx;LogFileName=results4.trx"
32+
- name: Generate unit test report (4.8)
33+
uses: phoenix-actions/test-reporting@v8
34+
id: unit-test-report-win48
35+
if: success() || failure()
3136
with:
32-
name: NuGet package
33-
path: BitFaster.Caching/bin/Release/
34-
- name: Publish coverage report to coveralls.io
37+
name: test results (win net4.8)
38+
path: BitFaster.Caching.UnitTests/TestResults/results4.trx
39+
reporter: dotnet-trx
40+
only-summary: 'true'
41+
42+
- name: Test (3.1)
43+
run: dotnet test --no-restore --verbosity normal -f netcoreapp3.1 /p:CollectCoverage=true /p:CoverletOutput=TestResults/ /p:CoverletOutputFormat=lcov --logger "trx;LogFileName=results3.trx"
44+
- name: Generate unit test report (3.1)
45+
uses: phoenix-actions/test-reporting@v8
46+
id: unit-test-report-win3
47+
if: success() || failure()
48+
with:
49+
name: test results (win net3.1)
50+
path: BitFaster.Caching.UnitTests/TestResults/results3.trx
51+
reporter: dotnet-trx
52+
only-summary: 'true'
53+
- name: Publish coverage report to coveralls.io (3.1)
3554
uses: coverallsapp/github-action@master
3655
with:
3756
github-token: ${{ secrets.GITHUB_TOKEN }}
38-
path-to-lcov: BitFaster.Caching.UnitTests/TestResults/coverage.info
39-
flag-name: win
57+
path-to-lcov: BitFaster.Caching.UnitTests/TestResults/coverage.netcoreapp3.1.info
58+
flag-name: win3
4059
parallel: true
41-
- name: Generate unit test report
60+
61+
- name: Test (6.0)
62+
run: dotnet test --no-restore --verbosity normal -f net6.0 /p:CollectCoverage=true /p:CoverletOutput=TestResults/ /p:CoverletOutputFormat=lcov --logger "trx;LogFileName=results6.trx"
63+
- name: Generate unit test report (6.0)
4264
uses: phoenix-actions/test-reporting@v8
43-
id: unit-test-report-win
65+
id: unit-test-report-win6
4466
if: success() || failure()
4567
with:
46-
name: test results (win)
47-
path: BitFaster.Caching.UnitTests/TestResults/results.trx
68+
name: test results (win net6.0)
69+
path: BitFaster.Caching.UnitTests/TestResults/results6.trx
4870
reporter: dotnet-trx
4971
only-summary: 'true'
72+
- name: Publish coverage report to coveralls.io (6.0)
73+
uses: coverallsapp/github-action@master
74+
with:
75+
github-token: ${{ secrets.GITHUB_TOKEN }}
76+
path-to-lcov: BitFaster.Caching.UnitTests/TestResults/coverage.net6.0.info
77+
flag-name: win6
78+
parallel: true
79+
80+
- name: Publish NuGet artifacts
81+
uses: actions/upload-artifact@v3
82+
with:
83+
name: NuGet package
84+
path: BitFaster.Caching/bin/Release/
5085

5186
mac:
5287

@@ -66,20 +101,20 @@ jobs:
66101
- name: Build
67102
run: dotnet build --configuration Release --no-restore
68103
- name: Test
69-
run: dotnet test --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutput=TestResults/ /p:CoverletOutputFormat=lcov --logger "trx;LogFileName=results.trx"
104+
run: dotnet test --no-restore --verbosity normal -f net6.0 /p:CollectCoverage=true /p:CoverletOutput=TestResults/ /p:CoverletOutputFormat=lcov --logger "trx;LogFileName=results.trx"
70105
- name: Publish coverage report to coveralls.io
71106
uses: coverallsapp/github-action@master
72107
with:
73108
github-token: ${{ secrets.GITHUB_TOKEN }}
74-
path-to-lcov: BitFaster.Caching.UnitTests/TestResults/coverage.info
109+
path-to-lcov: BitFaster.Caching.UnitTests/TestResults/coverage.net6.0.info
75110
flag-name: mac
76111
parallel: true
77112
- name: Generate unit test report
78113
uses: phoenix-actions/test-reporting@v8
79114
id: unit-test-report-mac
80115
if: success() || failure()
81116
with:
82-
name: test results (mac)
117+
name: test results (mac net6.0)
83118
path: BitFaster.Caching.UnitTests/TestResults/results.trx
84119
reporter: dotnet-trx
85120
only-summary: 'true'

BitFaster.Caching.UnitTests/BitFaster.Caching.UnitTests.csproj

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFrameworks>net48;netcoreapp3.1;net6.0</TargetFrameworks>
5+
<LangVersion>9.0</LangVersion>
56
</PropertyGroup>
67

78
<ItemGroup>
@@ -19,6 +20,10 @@
1920
</PackageReference>
2021
<PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
2122
</ItemGroup>
23+
24+
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
25+
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
26+
</ItemGroup>
2227

2328
<ItemGroup>
2429
<ProjectReference Include="..\BitFaster.Caching\BitFaster.Caching.csproj" />
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-

1+
#if NETCOREAPP3_1_OR_GREATER
22
using System.Runtime.Intrinsics.X86;
3+
#endif
34
using Xunit;
45

56
namespace BitFaster.Caching.UnitTests
@@ -8,8 +9,14 @@ public static class Intrinsics
89
{
910
public static void SkipAvxIfNotSupported<I>()
1011
{
12+
#if NETCOREAPP3_1_OR_GREATER
1113
// when we are trying to test Avx2, skip the test if it's not supported
1214
Skip.If(typeof(I) == typeof(DetectIsa) && !Avx2.IsSupported);
15+
#else
16+
Skip.If(true);
17+
#endif
1318
}
1419
}
1520
}
21+
22+

BitFaster.Caching.UnitTests/Lru/ConcurrentTLruTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public async Task WhenItemIsExpiredItIsRemoved()
5858
{
5959
lru.GetOrAdd(1, valueFactory.Create);
6060

61-
await Task.Delay(timeToLive * ttlWaitMlutiplier);
61+
await Task.Delay(timeToLive.MultiplyBy(ttlWaitMlutiplier));
6262

6363
lru.TryGet(1, out var value).Should().BeFalse();
6464
}
@@ -68,7 +68,7 @@ public async Task WhenItemIsUpdatedTtlIsExtended()
6868
{
6969
lru.GetOrAdd(1, valueFactory.Create);
7070

71-
await Task.Delay(timeToLive * ttlWaitMlutiplier);
71+
await Task.Delay(timeToLive.MultiplyBy(ttlWaitMlutiplier));
7272

7373
lru.TryUpdate(1, "3");
7474

@@ -134,7 +134,7 @@ public async Task WhenItemsAreExpiredExpireRemovesExpiredItems()
134134
lru.AddOrUpdate(8, "8");
135135
lru.AddOrUpdate(9, "9");
136136

137-
await Task.Delay(timeToLive * ttlWaitMlutiplier);
137+
await Task.Delay(timeToLive.MultiplyBy(ttlWaitMlutiplier));
138138

139139
lru.Policy.ExpireAfterWrite.Value.TrimExpired();
140140

@@ -152,7 +152,7 @@ public async Task WhenCacheHasExpiredAndFreshItemsExpireRemovesOnlyExpiredItems(
152152
lru.AddOrUpdate(5, "5");
153153
lru.AddOrUpdate(6, "6");
154154

155-
await Task.Delay(timeToLive * ttlWaitMlutiplier);
155+
await Task.Delay(timeToLive.MultiplyBy(ttlWaitMlutiplier));
156156

157157
lru.GetOrAdd(1, valueFactory.Create);
158158
lru.GetOrAdd(2, valueFactory.Create);
@@ -170,7 +170,7 @@ public async Task WhenItemsAreExpiredTrimRemovesExpiredItems()
170170
lru.AddOrUpdate(2, "2");
171171
lru.AddOrUpdate(3, "3");
172172

173-
await Task.Delay(timeToLive * ttlWaitMlutiplier);
173+
await Task.Delay(timeToLive.MultiplyBy(ttlWaitMlutiplier));
174174

175175
lru.Policy.Eviction.Value.Trim(1);
176176

BitFaster.Caching.UnitTests/Lru/FastConcurrentTLruTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public async Task WhenItemsAreExpiredExpireRemovesExpiredItems()
4747
lru.AddOrUpdate(2, "2");
4848
lru.AddOrUpdate(3, "3");
4949

50-
await Task.Delay(ttl * 2);
50+
await Task.Delay(ttl.MultiplyBy(2));
5151

5252
lru.Policy.ExpireAfterWrite.Value.TrimExpired();
5353

BitFaster.Caching.UnitTests/Lru/TLruTickCount64PolicyTests .cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using FluentAssertions;
1+
#if NETCOREAPP3_1_OR_GREATER
2+
3+
using FluentAssertions;
24
using FluentAssertions.Extensions;
35
using BitFaster.Caching.Lru;
46
using System;
@@ -157,3 +159,5 @@ private LongTickCountLruItem<int, int> CreateItem(bool wasAccessed, bool isExpir
157159
}
158160
}
159161
}
162+
163+
#endif

BitFaster.Caching.UnitTests/Scheduler/BackgroundSchedulerTests.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
52
using System.Threading;
63
using System.Threading.Tasks;
74
using BitFaster.Caching.Scheduler;
@@ -36,8 +33,8 @@ public async Task WhenWorkIsScheduledItIsRun()
3633
{
3734
bool run = false;
3835

39-
TaskCompletionSource tcs = new TaskCompletionSource();
40-
scheduler.Run(() => { Volatile.Write(ref run, true); tcs.SetResult(); });
36+
var tcs = new TaskCompletionSource<bool>();
37+
scheduler.Run(() => { Volatile.Write(ref run, true); tcs.SetResult(true); });
4138
await tcs.Task;
4239

4340
Volatile.Read(ref run).Should().BeTrue();
@@ -58,8 +55,8 @@ public async Task WhenWorkDoesNotThrowLastExceptionIsEmpty()
5855
[Fact]
5956
public async Task WhenWorkThrowsLastExceptionIsPopulated()
6057
{
61-
TaskCompletionSource tcs = new TaskCompletionSource();
62-
scheduler.Run(() => { tcs.SetResult(); throw new InvalidCastException(); });
58+
var tcs = new TaskCompletionSource<bool>();
59+
scheduler.Run(() => { tcs.SetResult(true); throw new InvalidCastException(); });
6360

6461
await tcs.Task;
6562
await scheduler.WaitForExceptionAsync();
@@ -71,14 +68,14 @@ public async Task WhenWorkThrowsLastExceptionIsPopulated()
7168
[Fact]
7269
public void WhenBacklogExceededTasksAreDropped()
7370
{
74-
TaskCompletionSource tcs = new TaskCompletionSource();
71+
var tcs = new TaskCompletionSource<bool>();
7572

7673
for (int i = 0; i < BackgroundThreadScheduler.MaxBacklog * 2; i++)
7774
{
7875
scheduler.Run(() => { tcs.Task.Wait(); });
7976
}
8077

81-
tcs.SetResult();
78+
tcs.SetResult(true);
8279

8380
scheduler.RunCount.Should().BeCloseTo(BackgroundThreadScheduler.MaxBacklog, 1);
8481
}

BitFaster.Caching.UnitTests/Scheduler/ThreadPoolSchedulerTests.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
52
using System.Threading;
63
using System.Threading.Tasks;
74
using BitFaster.Caching.Scheduler;
@@ -30,8 +27,8 @@ public async Task WhenWorkIsScheduledItIsRun()
3027
{
3128
bool run = false;
3229

33-
TaskCompletionSource tcs = new TaskCompletionSource();
34-
scheduler.Run(() => { Volatile.Write(ref run, true); tcs.SetResult(); });
30+
var tcs = new TaskCompletionSource<bool>();
31+
scheduler.Run(() => { Volatile.Write(ref run, true); tcs.SetResult(true); });
3532

3633
await tcs.Task;
3734

@@ -41,10 +38,10 @@ public async Task WhenWorkIsScheduledItIsRun()
4138
[Fact]
4239
public async Task WhenWorkDoesNotThrowLastExceptionIsEmpty()
4340
{
44-
TaskCompletionSource tcs = new TaskCompletionSource();
41+
var tcs = new TaskCompletionSource<bool>();
4542
scheduler.RunCount.Should().Be(0);
4643

47-
scheduler.Run(() => { tcs.SetResult(); });
44+
scheduler.Run(() => { tcs.SetResult(true); });
4845

4946
await tcs.Task;
5047

@@ -54,9 +51,9 @@ public async Task WhenWorkDoesNotThrowLastExceptionIsEmpty()
5451
[Fact]
5552
public async Task WhenWorkThrowsLastExceptionIsPopulated()
5653
{
57-
TaskCompletionSource tcs = new TaskCompletionSource();
54+
var tcs = new TaskCompletionSource<bool>();
5855
scheduler.Run(() => { throw new InvalidCastException(); });
59-
scheduler.Run(() => { tcs.SetResult(); });
56+
scheduler.Run(() => { tcs.SetResult(true); });
6057

6158
await tcs.Task;
6259
await scheduler.WaitForExceptionAsync();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
3+
namespace BitFaster.Caching.UnitTests
4+
{
5+
internal static class TimeSpanExtensions
6+
{
7+
// .NET Framework has no TimeSpan operator*
8+
public static TimeSpan MultiplyBy(this TimeSpan multiplicand, int multiplier)
9+
{
10+
return TimeSpan.FromTicks(multiplicand.Ticks * multiplier);
11+
}
12+
}
13+
}

0 commit comments

Comments
 (0)