TimerTest.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. //
  2. // TimerTest.cs - NUnit test cases for System.Threading.Timer
  3. //
  4. // Author:
  5. // Zoltan Varga ([email protected])
  6. // Rafael Ferreira ([email protected])
  7. //
  8. // (C) 2004 Novell, Inc (http://www.novell.com)
  9. //
  10. using NUnit.Framework;
  11. using System;
  12. using System.Threading;
  13. using System.Collections;
  14. namespace MonoTests.System.Threading {
  15. [TestFixture]
  16. public class TimerTest {
  17. // this bucket is used to avoid non-theadlocal issues
  18. class Bucket {
  19. public int count;
  20. public ManualResetEventSlim mre = new ManualResetEventSlim (false);
  21. }
  22. [SetUp]
  23. public void Setup ()
  24. {
  25. //creating a timer that will never run just to make sure the
  26. // scheduler is warm for the unit tests
  27. // this makes fair for the "DueTime" test since it
  28. // doesn't have to wait for the scheduler thread to be
  29. // created.
  30. new Timer (o => DoNothing (o), null, Timeout.Infinite, 0);
  31. }
  32. void DoNothing (object foo)
  33. {
  34. }
  35. private void Callback2 (object foo)
  36. {
  37. Bucket b = foo as Bucket;
  38. Interlocked.Increment (ref b.count);
  39. b.mre.Set ();
  40. }
  41. [Test]
  42. public void TestDueTime ()
  43. {
  44. Bucket bucket = new Bucket();
  45. using (Timer t = new Timer (o => Callback2 (o), bucket, 200, Timeout.Infinite)) {
  46. Assert.IsTrue (bucket.mre.Wait (5000), "#-1");
  47. Assert.AreEqual (1, bucket.count, "#1");
  48. }
  49. }
  50. [Test]
  51. public void TestDispose ()
  52. {
  53. Bucket bucket = new Bucket();
  54. using (Timer t = new Timer (o => Callback2 (o), bucket, 10, 10)) {
  55. Assert.IsTrue (bucket.mre.Wait (5000), "#-1");
  56. }
  57. //If the callback is called after dispose, it will NRE and be reported
  58. bucket.mre = null;
  59. int c = bucket.count;
  60. Assert.IsTrue (c > 0, "#1");
  61. }
  62. [Test]
  63. public void TestChange ()
  64. {
  65. Bucket bucket = new Bucket();
  66. using (Timer t = new Timer (o => Callback2 (o), bucket, 10, 10)) {
  67. Assert.IsTrue (bucket.mre.Wait (5000), "#-1");
  68. int c = bucket.count;
  69. Assert.IsTrue (c > 0, "#1 " + c);
  70. t.Change (100000, 1000000);
  71. c = bucket.count;
  72. Thread.Sleep (500);
  73. Assert.IsTrue (bucket.count <= c + 1, "#2 " + c);
  74. }
  75. }
  76. [Test]
  77. public void TestZeroDueTime ()
  78. {
  79. Bucket bucket = new Bucket();
  80. using (Timer t = new Timer (o => Callback2 (o), bucket, 0, Timeout.Infinite)) {
  81. Assert.IsTrue (bucket.mre.Wait (5000), "#-1");
  82. bucket.mre.Reset ();
  83. Assert.AreEqual (1, bucket.count, "#1");
  84. t.Change (0, Timeout.Infinite);
  85. Assert.IsTrue (bucket.mre.Wait (5000), "#1.5");
  86. Assert.AreEqual (2, bucket.count, "#2");
  87. }
  88. }
  89. [Test] // bug #320950
  90. public void TestDispose2 ()
  91. {
  92. Timer t = new Timer (o => DoNothing (o), null, 10, 10);
  93. t.Dispose ();
  94. t.Dispose ();
  95. }
  96. [Test]
  97. public void TestHeavyCreationLoad ()
  98. {
  99. Bucket b = new Bucket ();
  100. for (int i = 0; i < 500; ++i)
  101. new Timer (o => Callback (o), b, 10, Timeout.Infinite);
  102. // 1000 * 10 msec = 10,000 msec or 10 sec - if everything goes well
  103. // we add some slack to cope with timing issues caused by system load etc.
  104. for (int i = 0; i < 20; ++i) {
  105. if (b.count == 500)
  106. break;
  107. Thread.Sleep (1000);
  108. }
  109. Assert.AreEqual (500, b.count);
  110. }
  111. [Test]
  112. public void TestQuickDisposeDeadlockBug ()
  113. {
  114. Bucket b = new Bucket ();
  115. ArrayList timers = new ArrayList (500);
  116. for (int i = 0; i < 500; ++i) {
  117. using (Timer t = new Timer (o => Callback (o), b, 10, Timeout.Infinite)) {
  118. timers.Add (t);
  119. }
  120. }
  121. Thread.Sleep (11 * 500);
  122. }
  123. [Test]
  124. public void TestInt32MaxDelay ()
  125. {
  126. Bucket b = new Bucket ();
  127. using (new Timer (o => Callback (o), b, Int32.MaxValue, Timeout.Infinite)) {
  128. Thread.Sleep (50);
  129. Assert.AreEqual (0, b.count);
  130. }
  131. }
  132. [Test]
  133. public void TestInt32MaxPeriod ()
  134. {
  135. Bucket b = new Bucket ();
  136. using (new Timer (o => Callback (o), b, 0, Int32.MaxValue)) {
  137. Thread.Sleep (50);
  138. Assert.AreEqual (1, b.count);
  139. }
  140. }
  141. [Test]
  142. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  143. public void TestNegativeDelay ()
  144. {
  145. Bucket b = new Bucket ();
  146. using (new Timer (o => Callback (o), b, -10, Timeout.Infinite)) {
  147. }
  148. }
  149. [Test]
  150. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  151. public void TestNegativePeriod ()
  152. {
  153. Bucket b = new Bucket ();
  154. using (new Timer (o => Callback (o), b, 0, -10)) {
  155. }
  156. }
  157. [Test]
  158. public void TestDelayZeroPeriodZero()
  159. {
  160. Bucket b = new Bucket();
  161. using (Timer t = new Timer(o => Callback (o),b,0,0)) {
  162. Thread.Sleep(100);
  163. t.Change (int.MaxValue, Timeout.Infinite);
  164. // since period is 0 the callback should happen once (bug #340212)
  165. Assert.AreEqual (1, b.count, "only once");
  166. }
  167. }
  168. [Test]
  169. [Ignore ()]
  170. public void TestDisposeOnCallback ()
  171. {
  172. // this test is bad, as the provided `state` (t1) is null and will throw an NRE inside the callback
  173. // that was ignored before 238785a3e3d510528228fc551625975bc508c2f3 and most unit test runner won't
  174. // report it since the NRE will not happen on the main thread (but Touch.Unit will)
  175. Timer t1 = null;
  176. t1 = new Timer (o => CallbackTestDisposeOnCallback (o), t1, 0, 10);
  177. Thread.Sleep (200);
  178. Assert.IsNotNull (t1);
  179. }
  180. private void CallbackTestDisposeOnCallback (object foo)
  181. {
  182. ((Timer) foo).Dispose ();
  183. }
  184. private void Callback (object foo)
  185. {
  186. Bucket b = foo as Bucket;
  187. Interlocked.Increment (ref b.count);
  188. }
  189. [Test]
  190. [ExpectedException (typeof (ArgumentNullException))]
  191. public void DisposeNullWaitHandle ()
  192. {
  193. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  194. t.Dispose (null);
  195. }
  196. }
  197. [Test]
  198. public void Change_IntInt_Infinite ()
  199. {
  200. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  201. t.Change ((int)Timeout.Infinite, (int)Timeout.Infinite);
  202. }
  203. }
  204. [Test]
  205. public void Change_IntInt_MaxValue ()
  206. {
  207. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  208. t.Change (Int32.MaxValue, Int32.MaxValue);
  209. }
  210. }
  211. [Test]
  212. public void Change_UIntUInt_Infinite ()
  213. {
  214. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  215. t.Change (unchecked ((uint) Timeout.Infinite), unchecked ((uint) Timeout.Infinite));
  216. }
  217. }
  218. [Test]
  219. public void Change_UIntUInt_MaxValue ()
  220. {
  221. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  222. // UInt32.MaxValue == Timeout.Infinite == 0xffffffff
  223. t.Change (UInt32.MaxValue, UInt32.MaxValue);
  224. }
  225. }
  226. [Test]
  227. public void Change_LongLong_Infinite ()
  228. {
  229. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  230. t.Change ((long) Timeout.Infinite, (long) Timeout.Infinite);
  231. }
  232. }
  233. [Test]
  234. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  235. public void Change_LongLong_MaxValue ()
  236. {
  237. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  238. t.Change (Int64.MaxValue, Int64.MaxValue);
  239. }
  240. }
  241. [Test]
  242. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  243. public void Change_LongLong_UInt32MaxValue ()
  244. {
  245. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  246. // not identical to (long)-1
  247. t.Change ((long)UInt32.MaxValue, (long)UInt32.MaxValue);
  248. }
  249. }
  250. [Test]
  251. public void Change_LongLong_UInt32MaxValueMinusOne ()
  252. {
  253. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  254. // not identical to (long)-1
  255. t.Change ((long) UInt32.MaxValue - 1, (long) UInt32.MaxValue -1);
  256. }
  257. }
  258. [Test]
  259. public void Change_TimeSpanTimeSpan_Infinite ()
  260. {
  261. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  262. t.Change (new TimeSpan (-1), new TimeSpan (-1));
  263. }
  264. }
  265. [Test]
  266. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  267. public void Change_TimeSpanTimeSpan_MaxValue ()
  268. {
  269. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  270. t.Change (TimeSpan.MaxValue, TimeSpan.MaxValue);
  271. }
  272. }
  273. [Test]
  274. public void Change_TimeSpanTimeSpan_UInt32MaxValue ()
  275. {
  276. using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
  277. t.Change (new TimeSpan (UInt32.MaxValue), new TimeSpan (UInt32.MaxValue));
  278. }
  279. }
  280. [Test]
  281. [ExpectedException (typeof (ObjectDisposedException))]
  282. public void Change_After_Dispose ()
  283. {
  284. var t = new Timer (o => DoNothing (o), null, 0, 0);
  285. t.Dispose ();
  286. t.Change (1, 1);
  287. }
  288. }
  289. }