/vnext/Mso.UnitTests/future/whenAnyTest.cpp

https://github.com/microsoft/react-native-windows · C++ · 406 lines · 341 code · 62 blank · 3 comment · 30 complexity · 1dba6ac10102658dfb956df9b198cb00 MD5 · raw file

  1. // Copyright (c) Microsoft Corporation.
  2. // Licensed under the MIT license.
  3. #include <thread>
  4. #include "cppExtensions/autoRestore.h"
  5. #include "future/future.h"
  6. #include "future/futureWait.h"
  7. #include "motifCpp/libletAwareMemLeakDetection.h"
  8. #include "testCheck.h"
  9. #include "testExecutor.h"
  10. namespace FutureTests {
  11. TEST_CLASS_EX (WhenAnyTest, LibletAwareMemLeakDetection) {
  12. // MemoryLeakDetectionHook::TrackPerTest m_trackLeakPerTest;
  13. TEST_METHOD(WhenAny_Init_Three) {
  14. std::atomic<int32_t> finishCount{0};
  15. Mso::ManualResetEvent finished13;
  16. auto f1 = Mso::PostFuture([&]() noexcept {
  17. finished13.Wait();
  18. ++finishCount;
  19. return 1;
  20. });
  21. auto f2 = Mso::PostFuture([&]() noexcept {
  22. ++finishCount;
  23. return 3;
  24. });
  25. auto f3 = Mso::PostFuture([&]() noexcept {
  26. finished13.Wait();
  27. ++finishCount;
  28. return 5;
  29. });
  30. auto fr = Mso::WhenAny({f1, f2, f3}).Then([](int r) noexcept->int { return r; });
  31. TestCheckEqual(3, Mso::FutureWaitAndGetValue(fr));
  32. finished13.Set();
  33. while (finishCount != 3) {
  34. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  35. }
  36. }
  37. TESTMETHOD_REQUIRES_SEH(WhenAny_Init_Empty) {
  38. TEST_DISABLE_MEMORY_LEAK_DETECTION();
  39. TestCheckCrash(Mso::WhenAny({}));
  40. }
  41. TEST_METHOD(WhenAny_Init_Three_Error) {
  42. std::atomic<int32_t> finishCount{0};
  43. Mso::ManualResetEvent finished13;
  44. auto f1 = Mso::PostFuture([&]() noexcept {
  45. finished13.Wait();
  46. ++finishCount;
  47. return 1;
  48. });
  49. auto f2 = Mso::MakeFailedFuture<int>(Mso::CancellationErrorProvider().MakeErrorCode(true));
  50. auto f3 = Mso::PostFuture([&]() noexcept {
  51. finished13.Wait();
  52. ++finishCount;
  53. return 5;
  54. });
  55. auto fr = Mso::WhenAny({f1, f2, f3}).Then([](Mso::Maybe<int> && result) noexcept {
  56. TestCheck(result.IsError());
  57. TestCheck(Mso::CancellationErrorProvider().IsOwnedErrorCode(result.GetError()));
  58. return 42;
  59. });
  60. TestCheckEqual(42, Mso::FutureWaitAndGetValue(fr));
  61. finished13.Set();
  62. while (finishCount != 2) {
  63. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  64. }
  65. }
  66. TEST_METHOD(WhenAny_Array_Three) {
  67. std::atomic<int32_t> finishCount{0};
  68. Mso::ManualResetEvent finished13;
  69. Mso::Future<int> futures[] = {Mso::PostFuture([&]() noexcept {
  70. finished13.Wait();
  71. ++finishCount;
  72. return 1;
  73. }),
  74. Mso::PostFuture([&]() noexcept {
  75. ++finishCount;
  76. return 3;
  77. }),
  78. Mso::PostFuture([&]() noexcept {
  79. finished13.Wait();
  80. ++finishCount;
  81. return 5;
  82. })};
  83. auto fr = Mso::WhenAny(futures).Then([](int r) noexcept { return r; });
  84. TestCheckEqual(3, Mso::FutureWaitAndGetValue(fr));
  85. finished13.Set();
  86. while (finishCount != 3) {
  87. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  88. }
  89. }
  90. TEST_METHOD(WhenAny_Array_Three_Error) {
  91. std::atomic<int32_t> finishCount{0};
  92. Mso::ManualResetEvent finished13;
  93. Mso::Future<int> futures[] = {Mso::PostFuture([&]() noexcept {
  94. finished13.Wait();
  95. ++finishCount;
  96. return 1;
  97. }),
  98. Mso::MakeFailedFuture<int>(Mso::CancellationErrorProvider().MakeErrorCode(true)),
  99. Mso::PostFuture([&]() noexcept {
  100. finished13.Wait();
  101. ++finishCount;
  102. return 5;
  103. })};
  104. auto fr = Mso::WhenAny(futures).Then([](Mso::Maybe<int> && result) noexcept {
  105. TestCheck(result.IsError());
  106. TestCheck(Mso::CancellationErrorProvider().IsOwnedErrorCode(result.GetError()));
  107. return 42;
  108. });
  109. TestCheckEqual(42, Mso::FutureWaitAndGetValue(fr));
  110. finished13.Set();
  111. while (finishCount != 2) {
  112. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  113. }
  114. }
  115. TEST_METHOD(WhenAny_Vector_Three) {
  116. std::atomic<int32_t> finishCount{0};
  117. Mso::ManualResetEvent finished13;
  118. auto futures = std::vector<Mso::Future<int>>{Mso::PostFuture([&]() noexcept {
  119. finished13.Wait();
  120. ++finishCount;
  121. return 1;
  122. }),
  123. Mso::PostFuture([&]() noexcept {
  124. ++finishCount;
  125. return 3;
  126. }),
  127. Mso::PostFuture([&]() noexcept {
  128. finished13.Wait();
  129. ++finishCount;
  130. return 5;
  131. })};
  132. auto fr = Mso::WhenAny(futures).Then([](int r) noexcept->int { return r; });
  133. TestCheckEqual(3, Mso::FutureWaitAndGetValue(fr));
  134. finished13.Set();
  135. while (finishCount != 3) {
  136. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  137. }
  138. }
  139. TESTMETHOD_REQUIRES_SEH(WhenAny_Vector_Empty) {
  140. TEST_DISABLE_MEMORY_LEAK_DETECTION();
  141. TestCheckCrash(Mso::WhenAny(std::vector<Mso::Future<int>>()));
  142. }
  143. TEST_METHOD(WhenAny_Vector_Three_Error) {
  144. std::atomic<int32_t> finishCount{0};
  145. Mso::ManualResetEvent finished13;
  146. auto futures =
  147. std::vector<Mso::Future<int>>{Mso::PostFuture([&]() noexcept {
  148. finished13.Wait();
  149. ++finishCount;
  150. return 1;
  151. }),
  152. Mso::MakeFailedFuture<int>(Mso::CancellationErrorProvider().MakeErrorCode(true)),
  153. Mso::PostFuture([&]() noexcept {
  154. finished13.Wait();
  155. ++finishCount;
  156. return 5;
  157. })};
  158. auto fr = Mso::WhenAny(futures).Then([](Mso::Maybe<int> && result) noexcept {
  159. TestCheck(result.IsError());
  160. TestCheck(Mso::CancellationErrorProvider().IsOwnedErrorCode(result.GetError()));
  161. return 42;
  162. });
  163. TestCheckEqual(42, Mso::FutureWaitAndGetValue(fr));
  164. finished13.Set();
  165. while (finishCount != 2) {
  166. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  167. }
  168. }
  169. TEST_METHOD(WhenAny_Init_Void_Three) {
  170. std::atomic<int32_t> finishCount{0};
  171. Mso::ManualResetEvent finished13;
  172. int r1 = 0;
  173. int r2 = 0;
  174. int r3 = 0;
  175. auto f1 = Mso::PostFuture([&]() noexcept {
  176. finished13.Wait();
  177. ++finishCount;
  178. r1 = 1;
  179. });
  180. auto f2 = Mso::PostFuture([&]() noexcept {
  181. ++finishCount;
  182. r2 = 3;
  183. });
  184. auto f3 = Mso::PostFuture([&]() noexcept {
  185. finished13.Wait();
  186. ++finishCount;
  187. r3 = 5;
  188. });
  189. auto fr = Mso::WhenAny({f1, f2, f3}).Then([&]() noexcept { return 42; });
  190. TestCheckEqual(42, Mso::FutureWaitAndGetValue(fr));
  191. TestCheckEqual(3, r2);
  192. finished13.Set();
  193. while (finishCount != 3) {
  194. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  195. }
  196. }
  197. TESTMETHOD_REQUIRES_SEH(WhenAny_Init_Void_Empty) {
  198. TEST_DISABLE_MEMORY_LEAK_DETECTION();
  199. TestCheckCrash(Mso::WhenAny({}));
  200. }
  201. TEST_METHOD(WhenAny_Init_Void_Three_Error) {
  202. std::atomic<int32_t> finishCount{0};
  203. Mso::ManualResetEvent finished13;
  204. int r1 = 0;
  205. int r3 = 0;
  206. auto f1 = Mso::PostFuture([&]() noexcept {
  207. finished13.Wait();
  208. ++finishCount;
  209. r1 = 1;
  210. });
  211. auto f2 = Mso::MakeFailedFuture<void>(Mso::CancellationErrorProvider().MakeErrorCode(true));
  212. auto f3 = Mso::PostFuture([&]() noexcept {
  213. finished13.Wait();
  214. ++finishCount;
  215. r3 = 5;
  216. });
  217. auto fr = Mso::WhenAny({f1, f2, f3}).Then([&](Mso::Maybe<void> && result) noexcept {
  218. TestCheck(result.IsError());
  219. TestCheck(Mso::CancellationErrorProvider().IsOwnedErrorCode(result.GetError()));
  220. return 42;
  221. });
  222. TestCheckEqual(42, Mso::FutureWaitAndGetValue(fr));
  223. finished13.Set();
  224. while (finishCount != 2) {
  225. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  226. }
  227. }
  228. TEST_METHOD(WhenAny_Array_Void_Three) {
  229. std::atomic<int32_t> finishCount{0};
  230. Mso::ManualResetEvent finished13;
  231. int r1 = 0;
  232. int r2 = 0;
  233. int r3 = 0;
  234. Mso::Future<void> futures[] = {Mso::PostFuture([&]() noexcept {
  235. finished13.Wait();
  236. ++finishCount;
  237. r1 = 1;
  238. }),
  239. Mso::PostFuture([&]() noexcept {
  240. ++finishCount;
  241. r2 = 3;
  242. }),
  243. Mso::PostFuture([&]() noexcept {
  244. finished13.Wait();
  245. ++finishCount;
  246. r3 = 5;
  247. })};
  248. auto fr = Mso::WhenAny(futures).Then([&]() noexcept { return 42; });
  249. TestCheckEqual(42, Mso::FutureWaitAndGetValue(fr));
  250. TestCheckEqual(3, r2);
  251. finished13.Set();
  252. while (finishCount != 3) {
  253. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  254. }
  255. }
  256. TEST_METHOD(WhenAny_Array_Void_Three_Error) {
  257. std::atomic<int32_t> finishCount{0};
  258. Mso::ManualResetEvent finished13;
  259. int r1 = 0;
  260. int r3 = 0;
  261. Mso::Future<void> futures[] = {Mso::PostFuture([&]() noexcept {
  262. finished13.Wait();
  263. ++finishCount;
  264. r1 = 1;
  265. }),
  266. Mso::MakeFailedFuture<void>(Mso::CancellationErrorProvider().MakeErrorCode(true)),
  267. Mso::PostFuture([&]() noexcept {
  268. finished13.Wait();
  269. ++finishCount;
  270. r3 = 5;
  271. })};
  272. auto fr = Mso::WhenAny(futures).Then([&](Mso::Maybe<void> && result) noexcept {
  273. TestCheck(result.IsError());
  274. TestCheck(Mso::CancellationErrorProvider().IsOwnedErrorCode(result.GetError()));
  275. return 42;
  276. });
  277. TestCheckEqual(42, Mso::FutureWaitAndGetValue(fr));
  278. finished13.Set();
  279. while (finishCount != 2) {
  280. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  281. }
  282. }
  283. TEST_METHOD(WhenAny_Vector_Void_Three) {
  284. std::atomic<int32_t> finishCount{0};
  285. Mso::ManualResetEvent finished13;
  286. int r1 = 0;
  287. int r2 = 0;
  288. int r3 = 0;
  289. auto futures = std::vector<Mso::Future<void>>{Mso::PostFuture([&]() noexcept {
  290. finished13.Wait();
  291. ++finishCount;
  292. r1 = 1;
  293. }),
  294. Mso::PostFuture([&]() noexcept {
  295. ++finishCount;
  296. r2 = 3;
  297. }),
  298. Mso::PostFuture([&]() noexcept {
  299. finished13.Wait();
  300. ++finishCount;
  301. r3 = 5;
  302. })};
  303. auto fr = Mso::WhenAny(futures).Then([&]() noexcept {});
  304. Mso::FutureWait(fr);
  305. TestCheckEqual(3, r2);
  306. finished13.Set();
  307. while (finishCount != 3) {
  308. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  309. }
  310. }
  311. TESTMETHOD_REQUIRES_SEH(WhenAny_Vector_Void_Empty) {
  312. TEST_DISABLE_MEMORY_LEAK_DETECTION();
  313. TestCheckCrash(Mso::WhenAny(std::vector<Mso::Future<void>>()));
  314. }
  315. TEST_METHOD(WhenAny_Vector_Void_Three_Error) {
  316. std::atomic<int32_t> finishCount{0};
  317. Mso::ManualResetEvent finished13;
  318. int r1 = 0;
  319. int r3 = 0;
  320. auto futures = std::vector<Mso::Future<void>>{
  321. Mso::PostFuture([&]() noexcept {
  322. finished13.Wait();
  323. ++finishCount;
  324. r1 = 1;
  325. }),
  326. Mso::MakeFailedFuture<void>(Mso::CancellationErrorProvider().MakeErrorCode(true)),
  327. Mso::PostFuture([&]() noexcept {
  328. finished13.Wait();
  329. ++finishCount;
  330. r3 = 5;
  331. })};
  332. auto fr = Mso::WhenAny(futures).Then([&](Mso::Maybe<void> && result) noexcept {
  333. TestCheck(result.IsError());
  334. TestCheck(Mso::CancellationErrorProvider().IsOwnedErrorCode(result.GetError()));
  335. return 42;
  336. });
  337. TestCheckEqual(42, Mso::FutureWaitAndGetValue(fr));
  338. finished13.Set();
  339. while (finishCount != 2) {
  340. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  341. }
  342. }
  343. };
  344. } // namespace FutureTests