Răsfoiți Sursa

Add support for checking constraints from engine (#1438)

Marko Lahma 2 ani în urmă
părinte
comite
7e193c64d3

+ 22 - 0
Jint.Tests.PublicInterface/ConstraintUsageTests.cs

@@ -6,6 +6,9 @@ namespace Jint.Tests.PublicInterface;
 [Collection("ConstraintUsageTests")]
 public class ConstraintUsageTests
 {
+// this test case is problematic due to nature of cancellation token source in old framework
+// in NET 6 it's better designed and signals more reliably
+#if NET6_0_OR_GREATER
     [Fact]
     public void CanFindAndResetCancellationConstraint()
     {
@@ -45,4 +48,23 @@ public class ConstraintUsageTests
             return result.AsString();
         }
     }
+#endif
+
+    [Fact]
+    public void CanObserveConstraintsFromCustomCode()
+    {
+        var engine = new Engine(o => o.TimeoutInterval(TimeSpan.FromMilliseconds(100)));
+        engine.SetValue("slowFunction", new Func<string>(() =>
+        {
+            for (var i = 0; i < 100; ++i)
+            {
+                Thread.Sleep(TimeSpan.FromMilliseconds(200));
+                engine.CheckConstraints();
+            }
+
+            return "didn't throw!";
+        }));
+
+        Assert.Throws<TimeoutException>(() => engine.Execute("slowFunction()"));
+    }
 }

+ 1 - 1
Jint.Tests.PublicInterface/PublicInterfaceTests.cs

@@ -73,7 +73,7 @@ var coolingObject = {
             _queue.Enqueue(script);
         }
 
-        protected void Dispose(bool disposing)
+        private void Dispose(bool disposing)
         {
             if (!_disposedValue)
             {

+ 9 - 0
Jint/Constraints/ConstraintsOptionsExtensions.cs

@@ -20,6 +20,9 @@ public static class ConstraintsOptionsExtensions
         return options;
     }
 
+    /// <summary>
+    /// Sets constraint based on memory usage in bytes.
+    /// </summary>
     public static Options LimitMemory(this Options options, long memoryLimit)
     {
         options.WithoutConstraint(x => x is MemoryLimitConstraint);
@@ -31,6 +34,9 @@ public static class ConstraintsOptionsExtensions
         return options;
     }
 
+    /// <summary>
+    /// Sets constraint based on fixed time interval.
+    /// </summary>
     public static Options TimeoutInterval(this Options options, TimeSpan timeoutInterval)
     {
         if (timeoutInterval > TimeSpan.Zero && timeoutInterval < TimeSpan.MaxValue)
@@ -40,6 +46,9 @@ public static class ConstraintsOptionsExtensions
         return options;
     }
 
+    /// <summary>
+    /// Sets cancellation token to be observed. NOTE that this can be unreliable/imprecise on full framework due to timer logic.
+    /// </summary>
     public static Options CancellationToken(this Options options, CancellationToken cancellationToken)
     {
         options.WithoutConstraint(x => x is CancellationConstraint);

+ 11 - 0
Jint/Engine.cs

@@ -226,6 +226,17 @@ namespace Jint
             _executionContexts.Pop();
         }
 
+        /// <summary>
+        /// Checks engine's active constraints. Propagates exceptions from constraints.
+        /// </summary>
+        public void CheckConstraints()
+        {
+            foreach (var constraint in _constraints)
+            {
+                constraint.Check();
+            }
+        }
+
         /// <summary>
         /// Initializes the statements count
         /// </summary>