1
0

HistoricalSchedulerTest.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reactive;
  6. using System.Reactive.Concurrency;
  7. using Microsoft.Reactive.Testing;
  8. using Microsoft.VisualStudio.TestTools.UnitTesting;
  9. namespace ReactiveTests.Tests
  10. {
  11. [TestClass]
  12. public class HistoricalSchedulerTest
  13. {
  14. public DateTimeOffset Time(int i)
  15. {
  16. return new DateTimeOffset(1979, 10, 31, 4, 30, 15, TimeSpan.Zero).AddDays(i);
  17. }
  18. [TestMethod]
  19. public void Ctor()
  20. {
  21. var s = new HistoricalScheduler();
  22. Assert.AreEqual(DateTimeOffset.MinValue, s.Clock);
  23. Assert.AreEqual(DateTimeOffset.MinValue, s.Now);
  24. Assert.AreEqual(false, s.IsEnabled);
  25. }
  26. [TestMethod]
  27. public void Start_Stop()
  28. {
  29. var s = new HistoricalScheduler();
  30. var list = new List<Timestamped<int>>();
  31. var ts = TimeSpan.FromHours(1);
  32. s.Schedule(Time(0), () => list.Add(new Timestamped<int>(1, s.Now)));
  33. s.Schedule(Time(1), () => list.Add(new Timestamped<int>(2, s.Now)));
  34. s.Schedule(Time(2), () => s.Stop());
  35. s.Schedule(Time(3), () => list.Add(new Timestamped<int>(3, s.Now)));
  36. s.Schedule(Time(4), () => s.Stop());
  37. s.Schedule(Time(5), () => s.Start());
  38. s.Schedule(Time(6), () => list.Add(new Timestamped<int>(4, s.Now)));
  39. s.Start();
  40. Assert.AreEqual(Time(2), s.Now);
  41. Assert.AreEqual(Time(2), s.Clock);
  42. s.Start();
  43. Assert.AreEqual(Time(4), s.Now);
  44. Assert.AreEqual(Time(4), s.Clock);
  45. s.Start();
  46. Assert.AreEqual(Time(6), s.Now);
  47. Assert.AreEqual(Time(6), s.Clock);
  48. s.Start();
  49. Assert.AreEqual(Time(6), s.Now);
  50. Assert.AreEqual(Time(6), s.Clock);
  51. list.AssertEqual(
  52. new Timestamped<int>(1, Time(0)),
  53. new Timestamped<int>(2, Time(1)),
  54. new Timestamped<int>(3, Time(3)),
  55. new Timestamped<int>(4, Time(6))
  56. );
  57. }
  58. [TestMethod]
  59. public void Order()
  60. {
  61. var s = new HistoricalScheduler();
  62. var list = new List<Timestamped<int>>();
  63. s.Schedule(Time(2), () => list.Add(new Timestamped<int>(2, s.Now)));
  64. s.Schedule(Time(3), () => list.Add(new Timestamped<int>(3, s.Now)));
  65. s.Schedule(Time(1), () => list.Add(new Timestamped<int>(0, s.Now)));
  66. s.Schedule(Time(1), () => list.Add(new Timestamped<int>(1, s.Now)));
  67. s.Start();
  68. list.AssertEqual(
  69. new Timestamped<int>(0, Time(1)),
  70. new Timestamped<int>(1, Time(1)),
  71. new Timestamped<int>(2, Time(2)),
  72. new Timestamped<int>(3, Time(3))
  73. );
  74. }
  75. [TestMethod]
  76. public void Cancellation()
  77. {
  78. var s = new HistoricalScheduler();
  79. var list = new List<Timestamped<int>>();
  80. var d = s.Schedule(Time(2), () => list.Add(new Timestamped<int>(2, s.Now)));
  81. s.Schedule(Time(1), () =>
  82. {
  83. list.Add(new Timestamped<int>(0, s.Now));
  84. d.Dispose();
  85. });
  86. s.Start();
  87. list.AssertEqual(
  88. new Timestamped<int>(0, Time(1))
  89. );
  90. }
  91. [TestMethod]
  92. public void AdvanceTo_ArgumentChecking()
  93. {
  94. var now = DateTimeOffset.Now;
  95. var s = new HistoricalScheduler(now);
  96. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => s.AdvanceTo(now.Subtract(TimeSpan.FromSeconds(1))));
  97. }
  98. [TestMethod]
  99. public void AdvanceTo()
  100. {
  101. var s = new HistoricalScheduler();
  102. var list = new List<Timestamped<int>>();
  103. s.Schedule(Time(0), () => list.Add(new Timestamped<int>(0, s.Now)));
  104. s.Schedule(Time(1), () => list.Add(new Timestamped<int>(1, s.Now)));
  105. s.Schedule(Time(2), () => list.Add(new Timestamped<int>(2, s.Now)));
  106. s.Schedule(Time(10), () => list.Add(new Timestamped<int>(10, s.Now)));
  107. s.Schedule(Time(11), () => list.Add(new Timestamped<int>(11, s.Now)));
  108. s.AdvanceTo(Time(8));
  109. Assert.AreEqual(Time(8), s.Now);
  110. Assert.AreEqual(Time(8), s.Clock);
  111. list.AssertEqual(
  112. new Timestamped<int>(0, Time(0)),
  113. new Timestamped<int>(1, Time(1)),
  114. new Timestamped<int>(2, Time(2))
  115. );
  116. s.AdvanceTo(Time(8));
  117. Assert.AreEqual(Time(8), s.Now);
  118. Assert.AreEqual(Time(8), s.Clock);
  119. list.AssertEqual(
  120. new Timestamped<int>(0, Time(0)),
  121. new Timestamped<int>(1, Time(1)),
  122. new Timestamped<int>(2, Time(2))
  123. );
  124. s.Schedule(Time(7), () => list.Add(new Timestamped<int>(7, s.Now)));
  125. s.Schedule(Time(8), () => list.Add(new Timestamped<int>(8, s.Now)));
  126. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => s.AdvanceTo(Time(4)));
  127. Assert.AreEqual(Time(8), s.Now);
  128. Assert.AreEqual(Time(8), s.Clock);
  129. list.AssertEqual(
  130. new Timestamped<int>(0, Time(0)),
  131. new Timestamped<int>(1, Time(1)),
  132. new Timestamped<int>(2, Time(2))
  133. );
  134. s.AdvanceTo(Time(10));
  135. Assert.AreEqual(Time(10), s.Now);
  136. Assert.AreEqual(Time(10), s.Clock);
  137. list.AssertEqual(
  138. new Timestamped<int>(0, Time(0)),
  139. new Timestamped<int>(1, Time(1)),
  140. new Timestamped<int>(2, Time(2)),
  141. new Timestamped<int>(7, Time(8)),
  142. new Timestamped<int>(8, Time(8)),
  143. new Timestamped<int>(10, Time(10))
  144. );
  145. s.AdvanceTo(Time(100));
  146. Assert.AreEqual(Time(100), s.Now);
  147. Assert.AreEqual(Time(100), s.Clock);
  148. list.AssertEqual(
  149. new Timestamped<int>(0, Time(0)),
  150. new Timestamped<int>(1, Time(1)),
  151. new Timestamped<int>(2, Time(2)),
  152. new Timestamped<int>(7, Time(8)),
  153. new Timestamped<int>(8, Time(8)),
  154. new Timestamped<int>(10, Time(10)),
  155. new Timestamped<int>(11, Time(11))
  156. );
  157. }
  158. [TestMethod]
  159. public void AdvanceBy_ArgumentChecking()
  160. {
  161. var s = new HistoricalScheduler();
  162. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => s.AdvanceBy(TimeSpan.FromSeconds(-1)));
  163. }
  164. [TestMethod]
  165. public void AdvanceBy()
  166. {
  167. var s = new HistoricalScheduler();
  168. var list = new List<Timestamped<int>>();
  169. s.Schedule(Time(0), () => list.Add(new Timestamped<int>(0, s.Now)));
  170. s.Schedule(Time(1), () => list.Add(new Timestamped<int>(1, s.Now)));
  171. s.Schedule(Time(2), () => list.Add(new Timestamped<int>(2, s.Now)));
  172. s.Schedule(Time(10), () => list.Add(new Timestamped<int>(10, s.Now)));
  173. s.Schedule(Time(11), () => list.Add(new Timestamped<int>(11, s.Now)));
  174. s.AdvanceBy(Time(8) - s.Now);
  175. Assert.AreEqual(Time(8), s.Now);
  176. Assert.AreEqual(Time(8), s.Clock);
  177. list.AssertEqual(
  178. new Timestamped<int>(0, Time(0)),
  179. new Timestamped<int>(1, Time(1)),
  180. new Timestamped<int>(2, Time(2))
  181. );
  182. s.Schedule(Time(7), () => list.Add(new Timestamped<int>(7, s.Now)));
  183. s.Schedule(Time(8), () => list.Add(new Timestamped<int>(8, s.Now)));
  184. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => s.AdvanceBy(TimeSpan.FromDays(-4)));
  185. Assert.AreEqual(Time(8), s.Now);
  186. Assert.AreEqual(Time(8), s.Clock);
  187. list.AssertEqual(
  188. new Timestamped<int>(0, Time(0)),
  189. new Timestamped<int>(1, Time(1)),
  190. new Timestamped<int>(2, Time(2))
  191. );
  192. s.AdvanceBy(TimeSpan.Zero);
  193. Assert.AreEqual(Time(8), s.Now);
  194. Assert.AreEqual(Time(8), s.Clock);
  195. list.AssertEqual(
  196. new Timestamped<int>(0, Time(0)),
  197. new Timestamped<int>(1, Time(1)),
  198. new Timestamped<int>(2, Time(2))
  199. );
  200. s.AdvanceBy(TimeSpan.FromDays(2));
  201. Assert.AreEqual(Time(10), s.Now);
  202. Assert.AreEqual(Time(10), s.Clock);
  203. list.AssertEqual(
  204. new Timestamped<int>(0, Time(0)),
  205. new Timestamped<int>(1, Time(1)),
  206. new Timestamped<int>(2, Time(2)),
  207. new Timestamped<int>(7, Time(8)),
  208. new Timestamped<int>(8, Time(8)),
  209. new Timestamped<int>(10, Time(10))
  210. );
  211. s.AdvanceBy(TimeSpan.FromDays(90));
  212. Assert.AreEqual(Time(100), s.Now);
  213. Assert.AreEqual(Time(100), s.Clock);
  214. list.AssertEqual(
  215. new Timestamped<int>(0, Time(0)),
  216. new Timestamped<int>(1, Time(1)),
  217. new Timestamped<int>(2, Time(2)),
  218. new Timestamped<int>(7, Time(8)),
  219. new Timestamped<int>(8, Time(8)),
  220. new Timestamped<int>(10, Time(10)),
  221. new Timestamped<int>(11, Time(11))
  222. );
  223. }
  224. [TestMethod]
  225. public void IsEnabled()
  226. {
  227. var s = new HistoricalScheduler();
  228. Assert.AreEqual(false, s.IsEnabled);
  229. s.Schedule(() =>
  230. {
  231. Assert.AreEqual(true, s.IsEnabled);
  232. s.Stop();
  233. Assert.AreEqual(false, s.IsEnabled);
  234. });
  235. Assert.AreEqual(false, s.IsEnabled);
  236. s.Start();
  237. Assert.AreEqual(false, s.IsEnabled);
  238. }
  239. [TestMethod]
  240. public void No_Nested_AdvanceBy()
  241. {
  242. var s = new HistoricalScheduler();
  243. s.Schedule(() => s.AdvanceBy(TimeSpan.FromSeconds(1)));
  244. ReactiveAssert.Throws<InvalidOperationException>(() => s.Start());
  245. }
  246. [TestMethod]
  247. public void No_Nested_AdvanceTo()
  248. {
  249. var s = new HistoricalScheduler();
  250. s.Schedule(() => s.AdvanceTo(DateTimeOffset.Now.AddDays(1)));
  251. ReactiveAssert.Throws<InvalidOperationException>(() => s.Start());
  252. }
  253. [TestMethod]
  254. public void Sleep_ArgumentChecking()
  255. {
  256. var s = new HistoricalScheduler(DateTimeOffset.Now);
  257. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => s.Sleep(TimeSpan.FromSeconds(-1)));
  258. }
  259. [TestMethod]
  260. public void Sleep1()
  261. {
  262. var now = new DateTimeOffset(1983, 2, 11, 12, 0, 0, TimeSpan.Zero);
  263. var s = new HistoricalScheduler(now);
  264. s.Sleep(TimeSpan.FromDays(1));
  265. Assert.AreEqual(now + TimeSpan.FromDays(1), s.Clock);
  266. }
  267. [TestMethod]
  268. public void Sleep2()
  269. {
  270. var s = new HistoricalScheduler();
  271. var n = 0;
  272. s.Schedule(s.Now.AddMinutes(1), rec =>
  273. {
  274. s.Sleep(TimeSpan.FromMinutes(3));
  275. n++;
  276. rec(s.Now.AddMinutes(1));
  277. });
  278. s.AdvanceTo(s.Now + TimeSpan.FromMinutes(5));
  279. Assert.AreEqual(2, n);
  280. }
  281. [TestMethod]
  282. public void WithComparer_ArgumentChecking()
  283. {
  284. ReactiveAssert.Throws<ArgumentNullException>(() => new HistoricalScheduler(DateTimeOffset.Now, null));
  285. }
  286. [TestMethod]
  287. public void WithComparer()
  288. {
  289. var now = DateTimeOffset.Now;
  290. var s = new HistoricalScheduler(now, new ReverseComparer<DateTimeOffset>(Comparer<DateTimeOffset>.Default));
  291. var res = new List<int>();
  292. s.Schedule(now - TimeSpan.FromSeconds(1), () => res.Add(1));
  293. s.Schedule(now - TimeSpan.FromSeconds(2), () => res.Add(2));
  294. s.Start();
  295. Assert.IsTrue(new[] { 1, 2 }.SequenceEqual(res));
  296. }
  297. class ReverseComparer<T> : IComparer<T>
  298. {
  299. private readonly IComparer<T> _comparer;
  300. public ReverseComparer(IComparer<T> comparer)
  301. {
  302. _comparer = comparer;
  303. }
  304. public int Compare(T x, T y)
  305. {
  306. return -_comparer.Compare(x, y);
  307. }
  308. }
  309. }
  310. }