RetryWhenTest.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System;
  5. using System.Linq;
  6. using System.Reactive.Linq;
  7. using Microsoft.Reactive.Testing;
  8. using ReactiveTests.Dummies;
  9. using Xunit;
  10. namespace ReactiveTests.Tests
  11. {
  12. public class RetryWhenTest : ReactiveTest
  13. {
  14. [Fact]
  15. public void RetryWhen_Observable_ArgumentChecking()
  16. {
  17. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.RetryWhen<int, Exception>(null, v => v));
  18. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.RetryWhen<int, Exception>(Observable.Return(1), null));
  19. ReactiveAssert.Throws<ArgumentNullException>(() => DummyObservable<int>.Instance.RetryWhen(v => v).Subscribe(null));
  20. }
  21. [Fact]
  22. public void RetryWhen_Observable_Basic()
  23. {
  24. var scheduler = new TestScheduler();
  25. var xs = scheduler.CreateColdObservable(
  26. OnNext(100, 1),
  27. OnNext(150, 2),
  28. OnNext(200, 3),
  29. OnCompleted<int>(250)
  30. );
  31. var res = scheduler.Start(() =>
  32. xs.RetryWhen(v => v)
  33. );
  34. res.Messages.AssertEqual(
  35. OnNext(300, 1),
  36. OnNext(350, 2),
  37. OnNext(400, 3),
  38. OnCompleted<int>(450)
  39. );
  40. xs.Subscriptions.AssertEqual(
  41. Subscribe(200, 450)
  42. );
  43. }
  44. [Fact]
  45. public void RetryWhen_Observable_Handler_Completes()
  46. {
  47. var scheduler = new TestScheduler();
  48. var ex = new Exception();
  49. var xs = scheduler.CreateColdObservable(
  50. OnNext(100, 1),
  51. OnNext(150, 2),
  52. OnNext(200, 3),
  53. OnError<int>(250, ex)
  54. );
  55. var res = scheduler.Start(() =>
  56. xs.RetryWhen(v => v.Take(1).Skip(1))
  57. );
  58. res.Messages.AssertEqual(
  59. OnNext(300, 1),
  60. OnNext(350, 2),
  61. OnNext(400, 3),
  62. OnCompleted<int>(450)
  63. );
  64. xs.Subscriptions.AssertEqual(
  65. Subscribe(200, 450)
  66. );
  67. }
  68. [Fact]
  69. public void RetryWhen_Observable_Handler_Throws()
  70. {
  71. var scheduler = new TestScheduler();
  72. var ex = new Exception();
  73. var res = scheduler.Start(() =>
  74. Observable.Return(1).RetryWhen<int, int>(v => { throw ex; })
  75. );
  76. res.Messages.AssertEqual(
  77. OnError<int>(200, ex)
  78. );
  79. }
  80. [Fact]
  81. public void RetryWhen_Observable_Handler_Errors()
  82. {
  83. var scheduler = new TestScheduler();
  84. var ex = new Exception();
  85. var ex2 = new Exception();
  86. var xs = scheduler.CreateColdObservable(
  87. OnNext(100, 1),
  88. OnNext(150, 2),
  89. OnNext(200, 3),
  90. OnError<int>(250, ex)
  91. );
  92. var res = scheduler.Start(() =>
  93. xs.RetryWhen(v => v.SelectMany(w => Observable.Throw<int>(ex2)))
  94. );
  95. res.Messages.AssertEqual(
  96. OnNext(300, 1),
  97. OnNext(350, 2),
  98. OnNext(400, 3),
  99. OnError<int>(450, ex2)
  100. );
  101. xs.Subscriptions.AssertEqual(
  102. Subscribe(200, 450)
  103. );
  104. }
  105. [Fact]
  106. public void RetryWhen_Observable_RetryCount_Basic()
  107. {
  108. var scheduler = new TestScheduler();
  109. var ex = new Exception();
  110. var xs = scheduler.CreateColdObservable(
  111. OnNext(5, 1),
  112. OnNext(10, 2),
  113. OnNext(15, 3),
  114. OnError<int>(20, ex)
  115. );
  116. var res = scheduler.Start(() =>
  117. xs.RetryWhen(v =>
  118. {
  119. int[] count = { 0 };
  120. return v.SelectMany(w =>
  121. {
  122. var c = ++count[0];
  123. if (c == 3)
  124. {
  125. return Observable.Throw<int>(w);
  126. }
  127. return Observable.Return(1);
  128. });
  129. })
  130. );
  131. res.Messages.AssertEqual(
  132. OnNext(205, 1),
  133. OnNext(210, 2),
  134. OnNext(215, 3),
  135. OnNext(225, 1),
  136. OnNext(230, 2),
  137. OnNext(235, 3),
  138. OnNext(245, 1),
  139. OnNext(250, 2),
  140. OnNext(255, 3),
  141. OnError<int>(260, ex)
  142. );
  143. xs.Subscriptions.AssertEqual(
  144. Subscribe(200, 220),
  145. Subscribe(220, 240),
  146. Subscribe(240, 260)
  147. );
  148. }
  149. [Fact]
  150. public void RetryWhen_Observable_RetryCount_Delayed()
  151. {
  152. var scheduler = new TestScheduler();
  153. var ex = new Exception();
  154. var xs = scheduler.CreateColdObservable(
  155. OnNext(5, 1),
  156. OnNext(10, 2),
  157. OnNext(15, 3),
  158. OnError<int>(20, ex)
  159. );
  160. var res = scheduler.Start(() =>
  161. xs.RetryWhen(v =>
  162. {
  163. int[] count = { 0 };
  164. return v.SelectMany(w =>
  165. {
  166. var c = ++count[0];
  167. if (c == 3)
  168. {
  169. return Observable.Throw<int>(w);
  170. }
  171. return Observable.Return(1).Delay(TimeSpan.FromTicks(c * 100), scheduler);
  172. });
  173. })
  174. );
  175. res.Messages.AssertEqual(
  176. OnNext(205, 1),
  177. OnNext(210, 2),
  178. OnNext(215, 3),
  179. OnNext(325, 1),
  180. OnNext(330, 2),
  181. OnNext(335, 3),
  182. OnNext(545, 1),
  183. OnNext(550, 2),
  184. OnNext(555, 3),
  185. OnError<int>(560, ex)
  186. );
  187. xs.Subscriptions.AssertEqual(
  188. Subscribe(200, 220),
  189. Subscribe(320, 340),
  190. Subscribe(540, 560)
  191. );
  192. }
  193. }
  194. }