Skip to content

Commit

Permalink
Made test of cancellation of engine execution more robust (#1984)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomatosalat0 authored Oct 24, 2024
1 parent 1b0d5f8 commit af0845f
Showing 1 changed file with 32 additions and 7 deletions.
39 changes: 32 additions & 7 deletions Jint.Tests/Runtime/ExecutionConstraintTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,38 @@ public void ShouldThrowExecutionCanceled()
Assert.Throws<ExecutionCanceledException>(
() =>
{
using (var tcs = new CancellationTokenSource())
using (var cts = new CancellationTokenSource())
using (var waitHandle = new ManualResetEvent(false))
using (var cancellationTokenSet = new ManualResetEvent(initialState: false))
{
var engine = new Engine(cfg => cfg.CancellationToken(tcs.Token));
ThreadPool.QueueUserWorkItem(state =>
var engine = new Engine(cfg => cfg.CancellationToken(cts.Token));
/*
* To ensure that the action "threadPoolAction" has actually been called by the ThreadPool
* (which can happen very late, depending on the ThreadPool usage, etc.), the
* "cancellationTokenSet" event will be an indicator for that.
*
* 1. The "cancellationTokenSet" will be set after the "cts" has been cancelled.
* 2. Within the JS, the "test" code will only start as soon as the "cancellationTokenSet"
* event will be set.
* 3. The cancellationToken and its source has not been used on purpose for this test to
* not mix "test infrastructure" and "test code".
* 4. To verify that this test still works under heavy load, you can add
* a "Thread.Sleep(10000)" call anywhere within the "threadPoolAction" action.
*/
WaitCallback threadPoolAction = _ =>
{
waitHandle.WaitOne();
tcs.Cancel();
});
cts.Cancel();
cancellationTokenSet.Set();
};
ThreadPool.QueueUserWorkItem(threadPoolAction);
engine.SetValue("waitHandle", waitHandle);
engine.SetValue("waitForTokenToBeSet", new Action(() => cancellationTokenSet.WaitOne()));
engine.SetValue("mustNotBeCalled", new Action(() =>
throw new InvalidOperationException("A cancellation of the script execution has been requested, but the script did continue to run.")));
engine.Evaluate(@"
function sleep(millisecondsTimeout) {
var totalMilliseconds = new Date().getTime() + millisecondsTimeout;
Expand All @@ -56,11 +76,16 @@ function sleep(millisecondsTimeout) {
sleep(100);
waitHandle.Set();
waitForTokenToBeSet();
// Now it is ensured that the cancellationToken has been cancelled.
// The following JS code execution should get aborted by the engine.
sleep(1000);
sleep(1000);
sleep(1000);
sleep(1000);
sleep(1000);
mustNotBeCalled();
");
}
}
Expand Down Expand Up @@ -376,4 +401,4 @@ public void Log(string logMessage)
Console.WriteLine(logMessage);
}
}
}
}

0 comments on commit af0845f

Please sign in to comment.