PageRenderTime 16ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/mordor/tests/future.cpp

http://github.com/mozy/mordor
C++ | 250 lines | 217 code | 32 blank | 1 comment | 0 complexity | 8914ff5d9fa31029cfc773442115cf22 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Copyright (c) 2009 - Mozy, Inc.
  2. #include <boost/bind.hpp>
  3. #include "mordor/future.h"
  4. #include "mordor/test/test.h"
  5. #include "mordor/workerpool.h"
  6. using namespace Mordor;
  7. static void setTrue(bool &signalled)
  8. {
  9. signalled = true;
  10. }
  11. static void setResult(int &result, int value)
  12. {
  13. result = value;
  14. }
  15. template <class T>
  16. void signal(T &future)
  17. {
  18. future.signal();
  19. }
  20. template <>
  21. void signal<Future<int> >(Future<int> &future)
  22. {
  23. future.result() = 1;
  24. future.signal();
  25. }
  26. static void setTrueScheduler(bool &signalled, Scheduler *scheduler)
  27. {
  28. signalled = true;
  29. MORDOR_TEST_ASSERT_EQUAL(scheduler, Scheduler::getThis());
  30. }
  31. static void setResultScheduler(int &result, int value, Scheduler *scheduler)
  32. {
  33. result = value;
  34. MORDOR_TEST_ASSERT_EQUAL(scheduler, Scheduler::getThis());
  35. }
  36. MORDOR_UNITTEST(Future, synchronousYield)
  37. {
  38. Future<> future;
  39. future.signal();
  40. future.wait();
  41. }
  42. MORDOR_UNITTEST(Future, asynchronousYield)
  43. {
  44. WorkerPool pool;
  45. Future<> future;
  46. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future)));
  47. future.wait();
  48. }
  49. MORDOR_UNITTEST(Future, synchronousDg)
  50. {
  51. bool signalled = false;
  52. Future<> future(boost::bind(&setTrue, boost::ref(signalled)));
  53. future.signal();
  54. MORDOR_ASSERT(signalled);
  55. }
  56. MORDOR_UNITTEST(Future, asynchronousDg)
  57. {
  58. bool signalled = false;
  59. Future<> future(boost::bind(&setTrue, boost::ref(signalled)));
  60. MORDOR_ASSERT(!signalled);
  61. future.signal();
  62. MORDOR_ASSERT(signalled);
  63. }
  64. MORDOR_UNITTEST(Future, synchronousDgOtherScheduler)
  65. {
  66. WorkerPool pool(1, false);
  67. bool signalled = false;
  68. Future<> future(boost::bind(&setTrueScheduler, boost::ref(signalled), &pool), &pool);
  69. future.signal();
  70. pool.stop();
  71. MORDOR_ASSERT(signalled);
  72. }
  73. MORDOR_UNITTEST(Future, asynchronousDgOtherScheduler)
  74. {
  75. WorkerPool pool(1, false);
  76. bool signalled = false;
  77. Future<> future(boost::bind(&setTrueScheduler, boost::ref(signalled), &pool), &pool);
  78. MORDOR_ASSERT(!signalled);
  79. future.signal();
  80. pool.stop();
  81. MORDOR_ASSERT(signalled);
  82. }
  83. MORDOR_UNITTEST(Future, synchronousYieldInt)
  84. {
  85. Future<int> future;
  86. future.signal();
  87. future.wait();
  88. }
  89. MORDOR_UNITTEST(Future, asynchronousYieldInt)
  90. {
  91. WorkerPool pool;
  92. Future<int> future;
  93. MORDOR_TEST_ASSERT_EQUAL(future.result(), 0);
  94. pool.schedule(boost::bind(&signal<Future<int> >, boost::ref(future)));
  95. MORDOR_TEST_ASSERT_EQUAL(future.wait(), 1);
  96. }
  97. MORDOR_UNITTEST(Future, synchronousDgInt)
  98. {
  99. int result = 0;
  100. Future<int> future(boost::bind(&setResult, boost::ref(result), _1));
  101. future.result() = 1;
  102. future.signal();
  103. MORDOR_TEST_ASSERT_EQUAL(result, 1);
  104. }
  105. MORDOR_UNITTEST(Future, asynchronousDgInt)
  106. {
  107. int result = 0;
  108. Future<int> future(boost::bind(&setResult, boost::ref(result), _1));
  109. MORDOR_TEST_ASSERT_EQUAL(result, 0);
  110. future.result() = 1;
  111. future.signal();
  112. MORDOR_TEST_ASSERT_EQUAL(result, 1);
  113. }
  114. MORDOR_UNITTEST(Future, synchronousDgIntOtherScheduler)
  115. {
  116. WorkerPool pool(1, false);
  117. int result = 0;
  118. Future<int> future(boost::bind(&setResultScheduler, boost::ref(result), _1, &pool), &pool);
  119. future.result() = 1;
  120. future.signal();
  121. pool.stop();
  122. MORDOR_TEST_ASSERT_EQUAL(result, 1);
  123. }
  124. MORDOR_UNITTEST(Future, asynchronousDgIntOtherScheduler)
  125. {
  126. WorkerPool pool(1, false);
  127. int result = 0;
  128. Future<int> future(boost::bind(&setResultScheduler, boost::ref(result), _1, &pool), &pool);
  129. MORDOR_TEST_ASSERT_EQUAL(result, 0);
  130. future.result() = 1;
  131. future.signal();
  132. pool.stop();
  133. MORDOR_TEST_ASSERT_EQUAL(result, 1);
  134. }
  135. MORDOR_UNITTEST(Future, waitAllSynchronous)
  136. {
  137. Future<> future[2];
  138. future[0].signal(); future[1].signal();
  139. waitAll(future, future + 2);
  140. }
  141. MORDOR_UNITTEST(Future, waitAllHalfSynchronous1)
  142. {
  143. WorkerPool pool;
  144. Future<> future[2];
  145. future[0].signal();
  146. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[1])));
  147. waitAll(future, future + 2);
  148. }
  149. MORDOR_UNITTEST(Future, waitAllHalfSynchronous2)
  150. {
  151. WorkerPool pool;
  152. Future<> future[2];
  153. future[1].signal();
  154. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[0])));
  155. waitAll(future, future + 2);
  156. }
  157. MORDOR_UNITTEST(Future, waitAllAsynchronous1)
  158. {
  159. WorkerPool pool;
  160. Future<> future[2];
  161. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[0])));
  162. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[1])));
  163. waitAll(future, future + 2);
  164. }
  165. MORDOR_UNITTEST(Future, waitAllAsynchronous2)
  166. {
  167. WorkerPool pool;
  168. Future<> future[2];
  169. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[1])));
  170. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[0])));
  171. waitAll(future, future + 2);
  172. }
  173. MORDOR_UNITTEST(Future, waitAnySynchronous1)
  174. {
  175. Future<> future[2];
  176. future[0].signal();
  177. MORDOR_TEST_ASSERT_EQUAL(waitAny(future, future + 2), 0u);
  178. future[1].signal();
  179. waitAll(future, future + 2);
  180. }
  181. MORDOR_UNITTEST(Future, waitAnySynchronous2)
  182. {
  183. Future<> future[2];
  184. future[1].signal();
  185. MORDOR_TEST_ASSERT_EQUAL(waitAny(future, future + 2), 1u);
  186. future[0].signal();
  187. waitAll(future, future + 2);
  188. }
  189. MORDOR_UNITTEST(Future, waitAnySynchronousBoth)
  190. {
  191. Future<> future[2];
  192. future[0].signal(); future[1].signal();
  193. MORDOR_TEST_ASSERT_EQUAL(waitAny(future, future + 2), 0u);
  194. waitAll(future, future + 2);
  195. MORDOR_TEST_ASSERT_EQUAL(waitAny(future, future + 2), 0u);
  196. }
  197. MORDOR_UNITTEST(Future, waitAnyAsynchronous1)
  198. {
  199. WorkerPool pool;
  200. Future<> future[2];
  201. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[0])));
  202. MORDOR_TEST_ASSERT_EQUAL(waitAny(future, future + 2), 0u);
  203. }
  204. MORDOR_UNITTEST(Future, waitAnyAsynchronous2)
  205. {
  206. WorkerPool pool;
  207. Future<> future[2];
  208. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[1])));
  209. MORDOR_TEST_ASSERT_EQUAL(waitAny(future, future + 2), 1u);
  210. }
  211. MORDOR_UNITTEST(Future, waitAnyAsynchronousBoth)
  212. {
  213. WorkerPool pool;
  214. Future<> future[2];
  215. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[0])));
  216. pool.schedule(boost::bind(&signal<Future<> >, boost::ref(future[1])));
  217. MORDOR_TEST_ASSERT_EQUAL(waitAny(future, future + 2), 0u);
  218. }