2
0

CancellationTest.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. using Lua.Standard;
  2. namespace Lua.Tests;
  3. public class CancellationTest
  4. {
  5. LuaState state = default!;
  6. [SetUp]
  7. public void SetUp()
  8. {
  9. state = LuaState.Create();
  10. state.OpenStandardLibraries();
  11. state.Environment["assert"] = new LuaFunction("assert_with_wait",
  12. async (context, ct) =>
  13. {
  14. await Task.Delay(1, ct);
  15. var arg0 = context.GetArgument(0);
  16. if (!arg0.ToBoolean())
  17. {
  18. var message = "assertion failed!";
  19. if (context.HasArgument(1))
  20. {
  21. message = context.GetArgument<string>(1);
  22. }
  23. throw new LuaAssertionException(context.Thread, message);
  24. }
  25. return (context.Return(context.Arguments));
  26. });
  27. state.Environment["sleep"] = new LuaFunction("sleep",
  28. (context, _) =>
  29. {
  30. Thread.Sleep(context.GetArgument<int>(0));
  31. return new(context.Return());
  32. });
  33. state.Environment["wait"] = new LuaFunction("wait",
  34. async (context, ct) =>
  35. {
  36. await Task.Delay(context.GetArgument<int>(0), ct);
  37. return context.Return();
  38. });
  39. }
  40. [Test]
  41. public async Task PCall_WaitTest()
  42. {
  43. var source = """
  44. local function f(millisec)
  45. wait(millisec)
  46. end
  47. pcall(f, 500)
  48. """;
  49. var cancellationTokenSource = new CancellationTokenSource();
  50. cancellationTokenSource.CancelAfter(200);
  51. try
  52. {
  53. await state.DoStringAsync(source, "@test.lua", cancellationTokenSource.Token);
  54. Assert.Fail("Expected TaskCanceledException was not thrown.");
  55. }
  56. catch (Exception e)
  57. {
  58. Assert.That(e, Is.TypeOf<LuaCanceledException>());
  59. var luaCancelledException = (LuaCanceledException)e;
  60. Assert.That(luaCancelledException.InnerException, Is.TypeOf<TaskCanceledException>());
  61. var luaStackTrace = luaCancelledException.LuaTraceback!.ToString();
  62. Console.WriteLine(luaStackTrace);
  63. Assert.That(luaStackTrace, Contains.Substring("'wait'"));
  64. Assert.That(luaStackTrace, Contains.Substring("'pcall'"));
  65. }
  66. }
  67. [Test]
  68. public async Task PCall_SleepTest()
  69. {
  70. var source = """
  71. local function f(millisec)
  72. sleep(millisec)
  73. end
  74. pcall(f, 500)
  75. """;
  76. var cancellationTokenSource = new CancellationTokenSource();
  77. cancellationTokenSource.CancelAfter(250);
  78. try
  79. {
  80. await state.DoStringAsync(source, "@test.lua", cancellationTokenSource.Token);
  81. Assert.Fail("Expected TaskCanceledException was not thrown.");
  82. }
  83. catch (Exception e)
  84. {
  85. Assert.That(e, Is.TypeOf<LuaCanceledException>());
  86. var luaCancelledException = (LuaCanceledException)e;
  87. Assert.That(luaCancelledException.InnerException, Is.Null);
  88. var luaStackTrace = luaCancelledException.LuaTraceback!.ToString();
  89. Console.WriteLine(luaStackTrace);
  90. Assert.That(luaStackTrace, Contains.Substring("'sleep'"));
  91. Assert.That(luaStackTrace, Contains.Substring("'pcall'"));
  92. }
  93. }
  94. [Test]
  95. public async Task ForLoopTest()
  96. {
  97. var source = """
  98. local ret = 0
  99. for i = 1, 1000000000 do
  100. ret = ret + i
  101. end
  102. return ret
  103. """;
  104. var cancellationTokenSource = new CancellationTokenSource();
  105. cancellationTokenSource.CancelAfter(100);
  106. cancellationTokenSource.Token.Register(() =>
  107. {
  108. Console.WriteLine("Cancellation requested");
  109. });
  110. try
  111. {
  112. var r = await state.DoStringAsync(source, "@test.lua", cancellationTokenSource.Token);
  113. Console.WriteLine(r[0]);
  114. Assert.Fail("Expected TaskCanceledException was not thrown.");
  115. }
  116. catch (Exception e)
  117. {
  118. Assert.That(e, Is.TypeOf<LuaCanceledException>());
  119. Console.WriteLine(e.StackTrace);
  120. var luaCancelledException = (LuaCanceledException)e;
  121. Assert.That(luaCancelledException.InnerException, Is.Null);
  122. var traceback = luaCancelledException.LuaTraceback;
  123. if (traceback != null)
  124. {
  125. var luaStackTrace = traceback.ToString();
  126. Console.WriteLine(luaStackTrace);
  127. }
  128. }
  129. }
  130. [Test]
  131. public async Task GoToLoopTest()
  132. {
  133. var source = """
  134. local ret = 0
  135. ::loop::
  136. ret = ret + 1
  137. goto loop
  138. return ret
  139. """;
  140. var cancellationTokenSource = new CancellationTokenSource();
  141. cancellationTokenSource.CancelAfter(100);
  142. cancellationTokenSource.Token.Register(() =>
  143. {
  144. Console.WriteLine("Cancellation requested");
  145. });
  146. try
  147. {
  148. var r = await state.DoStringAsync(source, "@test.lua", cancellationTokenSource.Token);
  149. Console.WriteLine(r[0]);
  150. Assert.Fail("Expected TaskCanceledException was not thrown.");
  151. }
  152. catch (Exception e)
  153. {
  154. Assert.That(e, Is.TypeOf<LuaCanceledException>());
  155. Console.WriteLine(e.StackTrace);
  156. var luaCancelledException = (LuaCanceledException)e;
  157. Assert.That(luaCancelledException.InnerException, Is.Null);
  158. var traceback = luaCancelledException.LuaTraceback;
  159. if (traceback != null)
  160. {
  161. var luaStackTrace = traceback.ToString();
  162. Console.WriteLine(luaStackTrace);
  163. }
  164. }
  165. }
  166. }