DefaultConcurrencyAbstractionLayerTest.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT License.
  3. // See the LICENSE file in the project root for more information.
  4. #if HAS_REMOTING
  5. using System;
  6. using System.Reactive.Concurrency;
  7. using System.Reactive.PlatformServices;
  8. using System.Runtime.CompilerServices;
  9. using System.Threading;
  10. using Microsoft.VisualStudio.TestTools.UnitTesting;
  11. using Assert = Xunit.Assert;
  12. namespace ReactiveTests.Tests
  13. {
  14. [TestClass]
  15. [Serializable]
  16. public class DefaultConcurrencyAbstractionLayerTest
  17. {
  18. private AppDomain _domain;
  19. public DefaultConcurrencyAbstractionLayerTest()
  20. {
  21. if (_domain == null)
  22. {
  23. _domain = AppDomain.CreateDomain("Default_CAL", null, new AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.BaseDirectory });
  24. }
  25. }
  26. private void Run(CrossAppDomainDelegate a)
  27. {
  28. _domain.DoCallBack(a);
  29. }
  30. [TestMethod]
  31. public void Sleep()
  32. {
  33. var ran = new MarshalByRefCell<bool>();
  34. _domain.SetData("state", ran);
  35. Run(() =>
  36. {
  37. Scheduler.Immediate.Schedule(TimeSpan.FromMilliseconds(1), () =>
  38. {
  39. var state = (MarshalByRefCell<bool>)_domain.GetData("state");
  40. state.Value = true;
  41. });
  42. });
  43. Assert.True(ran.Value);
  44. }
  45. [TestMethod]
  46. public void QueueUserWorkItem()
  47. {
  48. var e = new MarshalByRefCell<ManualResetEvent> { Value = new ManualResetEvent(false) };
  49. _domain.SetData("state", e);
  50. Run(() =>
  51. {
  52. Scheduler.Default.Schedule(() =>
  53. {
  54. var state = (MarshalByRefCell<ManualResetEvent>)_domain.GetData("state");
  55. state.Value.Set();
  56. });
  57. });
  58. e.Value.WaitOne();
  59. }
  60. [TestMethod]
  61. public void StartTimer()
  62. {
  63. var e = new MarshalByRefCell<ManualResetEvent> { Value = new ManualResetEvent(false) };
  64. _domain.SetData("state", e);
  65. Run(() =>
  66. {
  67. Scheduler.Default.Schedule(TimeSpan.FromMilliseconds(10), () =>
  68. {
  69. var state = (MarshalByRefCell<ManualResetEvent>)_domain.GetData("state");
  70. state.Value.Set();
  71. });
  72. });
  73. e.Value.WaitOne();
  74. }
  75. [TestMethod]
  76. public void StartTimer_Cancel()
  77. {
  78. Run(StartTimer_Cancel_Callback);
  79. }
  80. private static void StartTimer_Cancel_Callback()
  81. {
  82. Scheduler.Default.Schedule(TimeSpan.FromSeconds(60), () =>
  83. {
  84. throw new InvalidOperationException("This shouldn't have happened!");
  85. }).Dispose();
  86. }
  87. [TestMethod]
  88. public void StartPeriodicTimer()
  89. {
  90. var e = new MarshalByRefCell<ManualResetEvent> { Value = new ManualResetEvent(false) };
  91. _domain.SetData("state", e);
  92. Run(() =>
  93. {
  94. var n = 0;
  95. Scheduler.Default.SchedulePeriodic(TimeSpan.FromMilliseconds(10), () =>
  96. {
  97. var state = (MarshalByRefCell<ManualResetEvent>)_domain.GetData("state");
  98. if (n++ == 10)
  99. {
  100. state.Value.Set();
  101. }
  102. });
  103. });
  104. e.Value.WaitOne();
  105. }
  106. [TestMethod]
  107. public void StartPeriodicTimer_Cancel()
  108. {
  109. Run(StartPeriodicTimer_Cancel_Callback);
  110. }
  111. private static void StartPeriodicTimer_Cancel_Callback()
  112. {
  113. Scheduler.Default.SchedulePeriodic(TimeSpan.FromSeconds(60), () =>
  114. {
  115. throw new InvalidOperationException("This shouldn't have happened!");
  116. }).Dispose();
  117. }
  118. [TestMethod]
  119. public void StartPeriodicTimer_Fast()
  120. {
  121. var e = new MarshalByRefCell<ManualResetEvent> { Value = new ManualResetEvent(false) };
  122. _domain.SetData("state", e);
  123. Run(() =>
  124. {
  125. var n = 0;
  126. Scheduler.Default.SchedulePeriodic(TimeSpan.Zero, () =>
  127. {
  128. var state = (MarshalByRefCell<ManualResetEvent>)_domain.GetData("state");
  129. if (n++ == 10)
  130. {
  131. state.Value.Set();
  132. }
  133. });
  134. });
  135. e.Value.WaitOne();
  136. }
  137. [TestMethod]
  138. public void StartPeriodicTimer_Fast_Cancel()
  139. {
  140. var e = new MarshalByRefCell<ManualResetEvent> { Value = new ManualResetEvent(false) };
  141. _domain.SetData("set_cancel", e);
  142. Run(() =>
  143. {
  144. var n = 0;
  145. var hasAtLeastOneValue = new ManualResetEvent(false);
  146. var schedule = Scheduler.Default.SchedulePeriodic(TimeSpan.Zero, () =>
  147. {
  148. _domain.SetData("value", n++);
  149. hasAtLeastOneValue.Set();
  150. });
  151. _domain.SetData("cancel", new MarshalByRefAction(schedule.Dispose));
  152. hasAtLeastOneValue.WaitOne();
  153. var setCancel = (MarshalByRefCell<ManualResetEvent>)_domain.GetData("set_cancel");
  154. setCancel.Value.Set();
  155. });
  156. e.Value.WaitOne();
  157. var value = (int)_domain.GetData("value");
  158. var cancel = (MarshalByRefAction)_domain.GetData("cancel");
  159. cancel.Invoke();
  160. Thread.Sleep(TimeSpan.FromMilliseconds(50));
  161. var newValue = (int)_domain.GetData("value");
  162. Assert.True(newValue >= value);
  163. Thread.Sleep(TimeSpan.FromMilliseconds(50));
  164. value = (int)_domain.GetData("value");
  165. Assert.Equal(newValue, value);
  166. }
  167. [TestMethod]
  168. public void CreateThread()
  169. {
  170. var e = new MarshalByRefCell<ManualResetEvent> { Value = new ManualResetEvent(false) };
  171. _domain.SetData("state", e);
  172. var r = new MarshalByRefCell<string> { Value = "" };
  173. _domain.SetData("res", r);
  174. Run(() =>
  175. {
  176. var state = (MarshalByRefCell<ManualResetEvent>)_domain.GetData("state");
  177. var res = (MarshalByRefCell<string>)_domain.GetData("res");
  178. var svc = (IServiceProvider)Scheduler.Default;
  179. var per = (ISchedulerPeriodic)svc.GetService(typeof(ISchedulerPeriodic));
  180. if (per == null)
  181. {
  182. res.Value = "Failed to get ISchedulerPeriodic.";
  183. state.Value.Set();
  184. return;
  185. }
  186. var slr = (ISchedulerLongRunning)svc.GetService(typeof(ISchedulerLongRunning));
  187. if (slr == null)
  188. {
  189. res.Value = "Failed to get ISchedulerLongRunning.";
  190. state.Value.Set();
  191. return;
  192. }
  193. var success = false;
  194. try
  195. {
  196. slr.ScheduleLongRunning(42, null);
  197. }
  198. catch (ArgumentNullException)
  199. {
  200. success = true;
  201. }
  202. if (!success)
  203. {
  204. res.Value = "Failed null check ScheduleLongRunning.";
  205. state.Value.Set();
  206. return;
  207. }
  208. state.Value.Set();
  209. #if !NO_THREAD
  210. var w = new ManualResetEvent(false);
  211. var d = slr.ScheduleLongRunning(cancel =>
  212. {
  213. while (!cancel.IsDisposed)
  214. {
  215. ;
  216. }
  217. w.Set();
  218. });
  219. Thread.Sleep(50);
  220. d.Dispose();
  221. w.WaitOne();
  222. #else
  223. state.Value.Set();
  224. #endif
  225. });
  226. e.Value.WaitOne();
  227. Assert.True(string.IsNullOrEmpty(r.Value));
  228. }
  229. [TestMethod]
  230. public void Cant_Locate_Scheduler()
  231. {
  232. Cant_Locate_Scheduler_NoPlib();
  233. }
  234. [MethodImpl(MethodImplOptions.NoInlining)]
  235. private void Cant_Locate_Scheduler_NoPlib()
  236. {
  237. var e = new MarshalByRefCell<bool>();
  238. _domain.SetData("state", e);
  239. Run(() =>
  240. {
  241. var state = (MarshalByRefCell<bool>)_domain.GetData("state");
  242. try
  243. {
  244. state.Value = Scheduler.TaskPool != null;
  245. }
  246. catch (Exception)
  247. {
  248. state.Value = false;
  249. }
  250. });
  251. Assert.True(e.Value);
  252. }
  253. #if !NO_PERF
  254. [TestMethod]
  255. public void Stopwatch()
  256. {
  257. var e = new MarshalByRefCell<bool>();
  258. _domain.SetData("state", e);
  259. Run(() =>
  260. {
  261. var state = (MarshalByRefCell<bool>)_domain.GetData("state");
  262. var sw = Scheduler.Default.StartStopwatch();
  263. var fst = sw.Elapsed;
  264. Thread.Sleep(100);
  265. var snd = sw.Elapsed;
  266. state.Value = snd > fst;
  267. });
  268. Assert.True(e.Value);
  269. }
  270. #endif
  271. [TestMethod]
  272. public void EnsureLoaded()
  273. {
  274. Assert.True(EnlightenmentProvider.EnsureLoaded());
  275. }
  276. }
  277. public class MarshalByRefCell<T> : MarshalByRefObject
  278. {
  279. public T Value;
  280. public override object InitializeLifetimeService()
  281. {
  282. return null;
  283. }
  284. }
  285. public class MarshalByRefAction : MarshalByRefObject
  286. {
  287. private readonly Action _action;
  288. public MarshalByRefAction(Action action)
  289. {
  290. _action = action;
  291. }
  292. public void Invoke()
  293. {
  294. _action();
  295. }
  296. public override object InitializeLifetimeService()
  297. {
  298. return null;
  299. }
  300. }
  301. }
  302. #endif