libmoost
/home/mhx/git/github/libmoost/test/thread/async_worker.cpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #include <boost/test/unit_test.hpp>
00029 #include <boost/test/test_tools.hpp>
00030 
00031 #include <vector>
00032 #include <string>
00033 
00034 #include "../../include/moost/thread/async_worker.hpp"
00035 #include "../../include/moost/thread/xtime_util.hpp"
00036 
00037 #include <boost/thread/thread.hpp>
00038 
00039 using namespace moost::thread;
00040 
00041 BOOST_AUTO_TEST_SUITE( async_worker_test )
00042 
00043 class SimpleAsyncWorker : public async_worker<int>
00044 {
00045 private:
00046 
00047   std::vector<char> & m_set_bytes;
00048 
00049 protected:
00050 
00051   void do_work(int & work)
00052   {
00053     boost::thread::sleep(xtime_util::add_ms(xtime_util::now(), 100));
00054     m_set_bytes[work] = 1;
00055   }
00056 
00057 public:
00058 
00059   SimpleAsyncWorker(std::vector<char> & set_bytes)
00060   : async_worker<int>(4, 4),
00061     m_set_bytes(set_bytes)
00062   {
00063   }
00064 
00065   ~SimpleAsyncWorker()
00066   {
00067     stop();
00068   }
00069 };
00070 
00071 class TimeoutAsyncWorker : public async_worker<int>
00072 {
00073 private:
00074 
00075   std::vector<char> & m_set_bytes;
00076 
00077 protected:
00078 
00079   void do_work(int & work)
00080   {
00081     boost::thread::sleep(xtime_util::add_ms(xtime_util::now(), 100));
00082     m_set_bytes[work] = 1;
00083   }
00084 
00085 public:
00086 
00087   TimeoutAsyncWorker(std::vector<char> & set_bytes)
00088   : async_worker<int>(4, 4, 40),
00089     m_set_bytes(set_bytes)
00090   {
00091   }
00092 
00093   ~TimeoutAsyncWorker()
00094   {
00095     stop();
00096   }
00097 };
00098 
00099 struct Fixture
00100 {
00101   std::vector<char> set_bytes;
00102   SimpleAsyncWorker aw;
00103   TimeoutAsyncWorker taw;
00104 
00105   Fixture()
00106   : set_bytes(16, 0),
00107     aw(set_bytes),
00108     taw(set_bytes)
00109   {
00110   }
00111 
00112   ~Fixture()
00113   {
00114     // force a stop before we destroy set_bytes
00115     aw.stop();
00116     taw.stop();
00117   }
00118 };
00119 
00120 BOOST_FIXTURE_TEST_CASE( test_do_nothing, Fixture )
00121 {
00122   for (size_t i = 0; i != set_bytes.size(); ++i)
00123     BOOST_CHECK_EQUAL(set_bytes[i], 0);
00124 }
00125 
00126 BOOST_FIXTURE_TEST_CASE( test_do_something, Fixture )
00127 {
00128   aw.enqueue(3);
00129 
00130   aw.stop();
00131 
00132   for (size_t i = 0; i != set_bytes.size(); ++i)
00133     BOOST_CHECK_EQUAL(set_bytes[i], (i == 3 ? 1 : 0));
00134 }
00135 
00136 BOOST_FIXTURE_TEST_CASE( test_do_multiple, Fixture )
00137 {
00138   aw.enqueue(1);
00139 
00140   aw.enqueue(3);
00141 
00142   aw.enqueue(5);
00143 
00144   aw.enqueue(7);
00145 
00146   aw.stop();
00147 
00148   for (size_t i = 0; i != 8; ++i)
00149     BOOST_CHECK_EQUAL(set_bytes[i], (i % 2 == 1 ? 1 : 0));
00150 }
00151 
00152 // simple async should wait indefinitely for a spot to open up on the queue
00153 BOOST_FIXTURE_TEST_CASE( test_wait, Fixture )
00154 {
00155   // first 4 get taken instantly
00156   aw.enqueue(1);
00157   aw.enqueue(2);
00158   aw.enqueue(3);
00159   aw.enqueue(4);
00160 
00161   // next 4 get on the queue
00162   aw.enqueue(5);
00163   aw.enqueue(6);
00164   aw.enqueue(7);
00165   aw.enqueue(8);
00166 
00167   // final enqueue should go through
00168   aw.enqueue(9);
00169 
00170   aw.stop();
00171 
00172   for (size_t i = 1; i != 10; ++i)
00173     BOOST_CHECK_EQUAL(set_bytes[i], 1);
00174 }
00175 
00176 BOOST_FIXTURE_TEST_CASE( test_timeout, Fixture )
00177 {
00178   // first 4 get taken instantly
00179   taw.enqueue(1);
00180   taw.enqueue(2);
00181   taw.enqueue(3);
00182   taw.enqueue(4);
00183 
00184   // next 4 get on the queue
00185   taw.enqueue(5);
00186   taw.enqueue(6);
00187   taw.enqueue(7);
00188   taw.enqueue(8);
00189 
00190   // final enqueue should time out
00191   BOOST_CHECK_THROW(taw.enqueue(1), enqueue_timeout);
00192 }
00193 
00194 BOOST_AUTO_TEST_SUITE_END()