Skip to content

Commit 1dc4782

Browse files
committed
Make the tests more stable
1 parent 41f6e16 commit 1dc4782

File tree

3 files changed

+37
-38
lines changed

3 files changed

+37
-38
lines changed

src/DotNext.Tests/Runtime/CompilerServices/SpawningAsyncTaskMethodBuilderTests.cs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,13 @@ public sealed class SpawningAsyncTaskMethodBuilderTests : Test
88
[Fact]
99
public static async Task ForkAsyncMethodWithResult()
1010
{
11-
using var resetEvent = new ManualResetEventSlim(initialState: false);
12-
var task = Sum(40, 2, Thread.CurrentThread.ManagedThreadId);
13-
True(resetEvent.Wait(DefaultTimeout));
11+
var task = Fork(static () => Sum(40, 2, Thread.CurrentThread.ManagedThreadId));
1412

1513
Equal(42, await task);
1614

1715
[AsyncMethodBuilder(typeof(SpawningAsyncTaskMethodBuilder<>))]
18-
async Task<int> Sum(int x, int y, int callerThreadId)
16+
static async Task<int> Sum(int x, int y, int callerThreadId)
1917
{
20-
resetEvent.Set();
2118
NotEqual(callerThreadId, Thread.CurrentThread.ManagedThreadId);
2219

2320
await Task.CompletedTask;
@@ -26,18 +23,13 @@ async Task<int> Sum(int x, int y, int callerThreadId)
2623
}
2724

2825
[Fact]
29-
public static async Task ForkAsyncMethodWithoutResult()
26+
public static Task ForkAsyncMethodWithoutResult()
3027
{
31-
using var resetEvent = new ManualResetEventSlim(initialState: false);
32-
var task = CheckThreadId(Thread.CurrentThread.ManagedThreadId);
33-
True(resetEvent.Wait(DefaultTimeout));
34-
35-
await task;
28+
return Fork(static () => CheckThreadId(Thread.CurrentThread.ManagedThreadId));
3629

3730
[AsyncMethodBuilder(typeof(SpawningAsyncTaskMethodBuilder))]
38-
async Task CheckThreadId(int callerThreadId)
31+
static async Task CheckThreadId(int callerThreadId)
3932
{
40-
resetEvent.Set();
4133
NotEqual(callerThreadId, Thread.CurrentThread.ManagedThreadId);
4234

4335
await Task.CompletedTask;
@@ -47,17 +39,14 @@ async Task CheckThreadId(int callerThreadId)
4739
[Fact]
4840
public static async Task CancellationOfSpawnedMethod()
4941
{
50-
using var resetEvent = new ManualResetEventSlim(initialState: false);
51-
var task = CheckThreadId(Thread.CurrentThread.ManagedThreadId, new(true));
52-
True(resetEvent.Wait(DefaultTimeout));
42+
var task = Fork(static () => CheckThreadId(Thread.CurrentThread.ManagedThreadId, new(true)));
5343

5444
await task.ConfigureAwait(ConfigureAwaitOptions.ContinueOnCapturedContext | ConfigureAwaitOptions.SuppressThrowing);
5545
True(task.IsCanceled);
5646

5747
[AsyncMethodBuilder(typeof(SpawningAsyncTaskMethodBuilder))]
58-
async Task CheckThreadId(int callerThreadId, CancellationToken token)
48+
static async Task CheckThreadId(int callerThreadId, CancellationToken token)
5949
{
60-
resetEvent.Set();
6150
NotEqual(callerThreadId, Thread.CurrentThread.ManagedThreadId);
6251

6352
await Task.Delay(DefaultTimeout, token);

src/DotNext.Tests/Test.cs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Buffers;
22
using System.Diagnostics.CodeAnalysis;
3+
using System.Runtime.CompilerServices;
34

45
[assembly: DotNext.ReportLongRunningTests(30_000)]
56

@@ -46,17 +47,31 @@ private protected static Action<T> Same<T>(T expected)
4647
where T : class
4748
=> actual => Same(expected, actual);
4849

49-
protected static TResult SuspendContext<TResult>(Func<TResult> func)
50+
protected static TResult Fork<TResult>(Func<TResult> func, [CallerMemberName] string threadName = "")
5051
{
51-
var currentContext = SynchronizationContext.Current;
52-
SynchronizationContext.SetSynchronizationContext(null);
53-
try
52+
var state = new State<TResult>(func);
53+
54+
var thread = new Thread(Start)
5455
{
55-
return func();
56-
}
57-
finally
56+
IsBackground = true,
57+
Name = threadName,
58+
};
59+
60+
thread.UnsafeStart(state);
61+
True(thread.Join(DefaultTimeout));
62+
return state.Result;
63+
64+
static void Start(object state)
5865
{
59-
SynchronizationContext.SetSynchronizationContext(currentContext);
66+
var tuple = (State<TResult>)state;
67+
tuple.Invoke();
6068
}
6169
}
70+
71+
private sealed class State<T>(Func<T> func)
72+
{
73+
internal T Result;
74+
75+
internal void Invoke() => Result = func();
76+
}
6277
}

src/DotNext.Tests/Threading/Leases/LeaseTests.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,15 @@ public static async Task AcquireUsingConsumer()
125125
}
126126

127127
[Fact]
128-
public static Task WorkerProtectedWithLease()
128+
public static async Task WorkerProtectedWithLease()
129129
{
130-
return SuspendContext(TestBody);
131-
132-
static async Task TestBody()
133-
{
134-
var pause = TimeSpan.FromMilliseconds(500);
135-
using var provider = new TestLeaseProvider(pause);
136-
await using var consumer = new TestLeaseConsumer(provider);
137-
True(await consumer.TryAcquireAsync());
130+
var pause = TimeSpan.FromMilliseconds(500);
131+
using var provider = new TestLeaseProvider(pause);
132+
await using var consumer = new TestLeaseConsumer(provider);
133+
True(await consumer.TryAcquireAsync());
138134

139-
var result = await consumer.ExecuteAsync(Worker);
140-
Equal(42, result);
141-
}
135+
var result = await Fork(() => consumer.ExecuteAsync(Worker));
136+
Equal(42, result);
142137

143138
static async Task<int> Worker(CancellationToken token)
144139
{

0 commit comments

Comments
 (0)