PageRenderTime 233ms CodeModel.GetById 60ms app.highlight 128ms RepoModel.GetById 34ms app.codeStats 1ms

/mordor/tests/future.cpp

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