libmoost
|
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()