CountdownEventTest.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. using System;
  2. using System.Threading;
  3. using Microsoft.VisualStudio.TestTools.UnitTesting;
  4. #if !FEATURE_THREAD_COUNTDOWNEVENT
  5. using CountdownEvent = Renci.SshNet.Common.CountdownEvent;
  6. #endif
  7. namespace Renci.SshNet.Tests.Classes.Common
  8. {
  9. [TestClass]
  10. public class CountdownEventTest
  11. {
  12. private Random _random;
  13. [TestInitialize]
  14. public void Init()
  15. {
  16. _random = new Random();
  17. }
  18. [TestMethod]
  19. public void Ctor_InitialCountGreatherThanZero()
  20. {
  21. var initialCount = _random.Next(1, 500);
  22. var countdownEvent = CreateCountdownEvent(initialCount);
  23. Assert.AreEqual(initialCount, countdownEvent.CurrentCount);
  24. Assert.IsFalse(countdownEvent.IsSet);
  25. Assert.IsFalse(countdownEvent.WaitHandle.WaitOne(0));
  26. countdownEvent.Dispose();
  27. }
  28. [TestMethod]
  29. public void Ctor_InitialCountZero()
  30. {
  31. const int initialCount = 0;
  32. var countdownEvent = CreateCountdownEvent(0);
  33. Assert.AreEqual(initialCount, countdownEvent.CurrentCount);
  34. Assert.IsTrue(countdownEvent.IsSet);
  35. Assert.IsTrue(countdownEvent.WaitHandle.WaitOne(0));
  36. countdownEvent.Dispose();
  37. }
  38. [TestMethod]
  39. public void Signal_CurrentCountGreatherThanOne()
  40. {
  41. var initialCount = _random.Next(2, 1000);
  42. var countdownEvent = CreateCountdownEvent(initialCount);
  43. Assert.IsFalse(countdownEvent.Signal());
  44. Assert.AreEqual(--initialCount, countdownEvent.CurrentCount);
  45. Assert.IsFalse(countdownEvent.IsSet);
  46. Assert.IsFalse(countdownEvent.WaitHandle.WaitOne(0));
  47. countdownEvent.Dispose();
  48. }
  49. [TestMethod]
  50. public void Signal_CurrentCountOne()
  51. {
  52. var countdownEvent = CreateCountdownEvent(1);
  53. Assert.IsTrue(countdownEvent.Signal());
  54. Assert.AreEqual(0, countdownEvent.CurrentCount);
  55. Assert.IsTrue(countdownEvent.IsSet);
  56. Assert.IsTrue(countdownEvent.WaitHandle.WaitOne(0));
  57. countdownEvent.Dispose();
  58. }
  59. [TestMethod]
  60. public void Signal_CurrentCountZero()
  61. {
  62. var countdownEvent = CreateCountdownEvent(0);
  63. try
  64. {
  65. countdownEvent.Signal();
  66. Assert.Fail();
  67. }
  68. catch (InvalidOperationException)
  69. {
  70. // Invalid attempt made to decrement the event's count below zero
  71. }
  72. finally
  73. {
  74. countdownEvent.Dispose();
  75. }
  76. }
  77. [TestMethod]
  78. public void Wait_TimeoutInfinite_ShouldBlockUntilCountdownEventIsSet()
  79. {
  80. var sleep = TimeSpan.FromMilliseconds(100);
  81. var timeout = Session.InfiniteTimeSpan;
  82. var countdownEvent = CreateCountdownEvent(1);
  83. var signalCount = 0;
  84. var expectedSignalCount = _random.Next(5, 20);
  85. for (var i = 0; i < (expectedSignalCount - 1); i++)
  86. countdownEvent.AddCount();
  87. var threads = new Thread[expectedSignalCount];
  88. for (var i = 0; i < expectedSignalCount; i++)
  89. {
  90. threads[i] = new Thread(() =>
  91. {
  92. Thread.Sleep(sleep);
  93. Interlocked.Increment(ref signalCount);
  94. countdownEvent.Signal();
  95. });
  96. threads[i].Start();
  97. }
  98. var start = DateTime.Now;
  99. var actual = countdownEvent.Wait(timeout);
  100. var elapsedTime = DateTime.Now - start;
  101. Assert.IsTrue(actual);
  102. Assert.AreEqual(expectedSignalCount, signalCount);
  103. Assert.IsTrue(countdownEvent.IsSet);
  104. Assert.IsTrue(countdownEvent.WaitHandle.WaitOne(0));
  105. Assert.IsTrue(elapsedTime >= sleep);
  106. Assert.IsTrue(elapsedTime <= sleep.Add(TimeSpan.FromMilliseconds(100)));
  107. countdownEvent.Dispose();
  108. }
  109. [TestMethod]
  110. public void Wait_ShouldReturnTrueWhenCountdownEventIsSetBeforeTimeoutExpires()
  111. {
  112. var sleep = TimeSpan.FromMilliseconds(100);
  113. var timeout = sleep.Add(TimeSpan.FromSeconds(2));
  114. var countdownEvent = CreateCountdownEvent(1);
  115. var signalCount = 0;
  116. var expectedSignalCount = _random.Next(5, 20);
  117. for (var i = 0; i < (expectedSignalCount - 1); i++)
  118. countdownEvent.AddCount();
  119. var threads = new Thread[expectedSignalCount];
  120. for (var i = 0; i < expectedSignalCount; i++)
  121. {
  122. threads[i] = new Thread(() =>
  123. {
  124. Thread.Sleep(sleep);
  125. Interlocked.Increment(ref signalCount);
  126. countdownEvent.Signal();
  127. });
  128. threads[i].Start();
  129. }
  130. var start = DateTime.Now;
  131. var actual = countdownEvent.Wait(timeout);
  132. var elapsedTime = DateTime.Now - start;
  133. Assert.IsTrue(actual);
  134. Assert.AreEqual(expectedSignalCount, signalCount);
  135. Assert.IsTrue(countdownEvent.IsSet);
  136. Assert.IsTrue(countdownEvent.WaitHandle.WaitOne(0));
  137. Assert.IsTrue(elapsedTime >= sleep);
  138. Assert.IsTrue(elapsedTime <= timeout);
  139. countdownEvent.Dispose();
  140. }
  141. [TestMethod]
  142. public void Wait_ShouldReturnFalseWhenTimeoutExpiresBeforeCountdownEventIsSet()
  143. {
  144. var sleep = TimeSpan.FromMilliseconds(100);
  145. var timeout = TimeSpan.FromMilliseconds(30);
  146. var countdownEvent = CreateCountdownEvent(1);
  147. var signalCount = 0;
  148. var expectedSignalCount = _random.Next(5, 20);
  149. for (var i = 0; i < (expectedSignalCount - 1); i++)
  150. countdownEvent.AddCount();
  151. var threads = new Thread[expectedSignalCount];
  152. for (var i = 0; i < expectedSignalCount; i++)
  153. {
  154. threads[i] = new Thread(() =>
  155. {
  156. Thread.Sleep(sleep);
  157. countdownEvent.Signal();
  158. Interlocked.Increment(ref signalCount);
  159. });
  160. threads[i].Start();
  161. }
  162. var start = DateTime.Now;
  163. var actual = countdownEvent.Wait(timeout);
  164. var elapsedTime = DateTime.Now - start;
  165. Assert.IsFalse(actual);
  166. Assert.IsFalse(countdownEvent.IsSet);
  167. Assert.IsFalse(countdownEvent.WaitHandle.WaitOne(0));
  168. Assert.IsTrue(elapsedTime >= timeout);
  169. countdownEvent.Wait(Session.InfiniteTimeSpan);
  170. countdownEvent.Dispose();
  171. }
  172. [TestMethod]
  173. public void WaitHandle_ShouldAlwaysReturnSameInstance()
  174. {
  175. var countdownEvent = CreateCountdownEvent(1);
  176. var waitHandleA = countdownEvent.WaitHandle;
  177. Assert.IsNotNull(waitHandleA);
  178. var waitHandleB = countdownEvent.WaitHandle;
  179. Assert.AreSame(waitHandleA, waitHandleB);
  180. }
  181. [TestMethod]
  182. public void WaitHandle_WaitOne_TimeoutInfinite_ShouldBlockUntilCountdownEventIsSet()
  183. {
  184. var sleep = TimeSpan.FromMilliseconds(100);
  185. var timeout = Session.InfiniteTimeSpan;
  186. var countdownEvent = CreateCountdownEvent(1);
  187. var signalCount = 0;
  188. var expectedSignalCount = _random.Next(5, 20);
  189. for (var i = 0; i < (expectedSignalCount - 1); i++)
  190. countdownEvent.AddCount();
  191. var threads = new Thread[expectedSignalCount];
  192. for (var i = 0; i < expectedSignalCount; i++)
  193. {
  194. threads[i] = new Thread(() =>
  195. {
  196. Thread.Sleep(sleep);
  197. Interlocked.Increment(ref signalCount);
  198. countdownEvent.Signal();
  199. });
  200. threads[i].Start();
  201. }
  202. var start = DateTime.Now;
  203. var actual = countdownEvent.WaitHandle.WaitOne(timeout);
  204. var elapsedTime = DateTime.Now - start;
  205. Assert.IsTrue(actual);
  206. Assert.AreEqual(expectedSignalCount, signalCount);
  207. Assert.IsTrue(countdownEvent.IsSet);
  208. Assert.IsTrue(countdownEvent.WaitHandle.WaitOne(0));
  209. Assert.IsTrue(elapsedTime >= sleep);
  210. Assert.IsTrue(elapsedTime <= sleep.Add(TimeSpan.FromMilliseconds(100)));
  211. countdownEvent.Dispose();
  212. }
  213. [TestMethod]
  214. public void WaitHandle_WaitOne_ShouldReturnTrueWhenCountdownEventIsSetBeforeTimeoutExpires()
  215. {
  216. var sleep = TimeSpan.FromMilliseconds(100);
  217. var timeout = sleep.Add(TimeSpan.FromSeconds(2));
  218. var countdownEvent = CreateCountdownEvent(1);
  219. var signalCount = 0;
  220. var expectedSignalCount = _random.Next(5, 20);
  221. for (var i = 0; i < (expectedSignalCount - 1); i++)
  222. countdownEvent.AddCount();
  223. var threads = new Thread[expectedSignalCount];
  224. for (var i = 0; i < expectedSignalCount; i++)
  225. {
  226. threads[i] = new Thread(() =>
  227. {
  228. Thread.Sleep(sleep);
  229. Interlocked.Increment(ref signalCount);
  230. countdownEvent.Signal();
  231. });
  232. threads[i].Start();
  233. }
  234. var start = DateTime.Now;
  235. var actual = countdownEvent.Wait(timeout);
  236. var elapsedTime = DateTime.Now - start;
  237. Assert.IsTrue(actual);
  238. Assert.AreEqual(expectedSignalCount, signalCount);
  239. Assert.IsTrue(countdownEvent.IsSet);
  240. Assert.IsTrue(countdownEvent.WaitHandle.WaitOne(0));
  241. Assert.IsTrue(elapsedTime >= sleep);
  242. Assert.IsTrue(elapsedTime <= timeout);
  243. countdownEvent.Dispose();
  244. }
  245. [TestMethod]
  246. public void WaitHandle_WaitOne_ShouldReturnFalseWhenTimeoutExpiresBeforeCountdownEventIsSet()
  247. {
  248. var sleep = TimeSpan.FromMilliseconds(100);
  249. var timeout = TimeSpan.FromMilliseconds(30);
  250. var countdownEvent = CreateCountdownEvent(1);
  251. var signalCount = 0;
  252. var expectedSignalCount = _random.Next(5, 20);
  253. for (var i = 0; i < (expectedSignalCount - 1); i++)
  254. countdownEvent.AddCount();
  255. var threads = new Thread[expectedSignalCount];
  256. for (var i = 0; i < expectedSignalCount; i++)
  257. {
  258. threads[i] = new Thread(() =>
  259. {
  260. Thread.Sleep(sleep);
  261. countdownEvent.Signal();
  262. Interlocked.Increment(ref signalCount);
  263. });
  264. threads[i].Start();
  265. }
  266. var start = DateTime.Now;
  267. var actual = countdownEvent.WaitHandle.WaitOne(timeout);
  268. var elapsedTime = DateTime.Now - start;
  269. Assert.IsFalse(actual);
  270. Assert.IsFalse(countdownEvent.IsSet);
  271. Assert.IsFalse(countdownEvent.WaitHandle.WaitOne(0));
  272. Assert.IsTrue(elapsedTime >= timeout);
  273. countdownEvent.Wait(Session.InfiniteTimeSpan);
  274. countdownEvent.Dispose();
  275. }
  276. private static CountdownEvent CreateCountdownEvent(int initialCount)
  277. {
  278. return new CountdownEvent(initialCount);
  279. }
  280. }
  281. }