00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef WWORKERTHREAD_TEST_H
00026 #define WWORKERTHREAD_TEST_H
00027
00028 #include <string>
00029
00030 #include <cxxtest/TestSuite.h>
00031
00032 #include "../WWorkerThread.h"
00033 #include "../WSharedObject.h"
00034
00035
00036
00037
00038 class WWorkerThreadTest : public CxxTest::TestSuite
00039 {
00040
00041
00042
00043 class FuncType
00044 {
00045 public:
00046
00047
00048
00049
00050
00051 FuncType( int value )
00052 : m_input( new int( value ) )
00053 {
00054
00055 m_result.getWriteTicket()->get() = 0;
00056 m_stopped.getWriteTicket()->get() = false;
00057
00058 if( value < 0 )
00059 {
00060 value = -value;
00061 }
00062 }
00063
00064
00065
00066
00067
00068
00069 void operator() ( std::size_t, std::size_t, WBoolFlag const& shutdown )
00070 {
00071 for( int i = 1; i <= *m_input.get() && !shutdown(); ++i )
00072 {
00073 m_result.getWriteTicket()->get() += i;
00074 }
00075 if( shutdown() )
00076 {
00077 m_stopped.getWriteTicket()->get() = true;
00078 }
00079 sleep( 1 );
00080 }
00081
00082
00083
00084
00085
00086 bool stopped()
00087 {
00088 return m_stopped.getReadTicket()->get();
00089 }
00090
00091
00092
00093
00094
00095
00096 int getResult()
00097 {
00098 return m_result.getReadTicket()->get();
00099 }
00100
00101
00102
00103
00104 void reset()
00105 {
00106 m_result.getWriteTicket()->get() = 0;
00107 }
00108
00109 private:
00110
00111
00112 boost::shared_ptr< int const > m_input;
00113
00114
00115 WSharedObject< int > m_result;
00116
00117
00118 WSharedObject< bool > m_stopped;
00119 };
00120
00121
00122
00123
00124 class ExceptionalFuncType
00125 {
00126 public:
00127
00128
00129
00130 void operator() ( std::size_t, std::size_t, WBoolFlag& )
00131 {
00132 throw WException( std::string( "Test!" ) );
00133 }
00134 };
00135
00136 public:
00137
00138
00139
00140
00141 void testSingleThread( void )
00142 {
00143 m_stopped = false;
00144
00145 boost::shared_ptr< FuncType > func( new FuncType( 6 ) );
00146 WWorkerThread< FuncType > w( func, 0, 1 );
00147 w.subscribeStopSignal( boost::bind( &WWorkerThreadTest::stopTestDone, this ) );
00148
00149 w.run();
00150 w.wait();
00151
00152
00153 TS_ASSERT_EQUALS( func->getResult(), 21 );
00154 TS_ASSERT_EQUALS( m_stopped, true );
00155 }
00156
00157
00158
00159
00160 void testStopThread()
00161 {
00162 m_stopped = false;
00163
00164 boost::shared_ptr< FuncType > func( new FuncType( 100000000 ) );
00165 WWorkerThread< FuncType > w( func, 0, 1 );
00166 w.subscribeStopSignal( boost::bind( &WWorkerThreadTest::stopTestDone, this ) );
00167
00168 w.run();
00169 w.requestStop();
00170 w.wait();
00171
00172 TS_ASSERT( func->stopped() );
00173 TS_ASSERT_EQUALS( m_stopped, true );
00174 }
00175
00176
00177
00178
00179 void testMultipleThreads()
00180 {
00181 boost::shared_ptr< FuncType > func( new FuncType( 5 ) );
00182 WWorkerThread< FuncType > w0( func, 0, 3 );
00183 WWorkerThread< FuncType > w1( func, 1, 3 );
00184 WWorkerThread< FuncType > w2( func, 2, 3 );
00185
00186 w0.run();
00187 w1.run();
00188 w2.run();
00189 w0.wait();
00190 w1.wait();
00191 w2.wait();
00192
00193 TS_ASSERT_EQUALS( func->getResult(), 45 );
00194 }
00195
00196
00197 #ifdef WASSERT_AS_CASSERT
00198 #define WASSERT_FLAG_CHANGED
00199 #undefine WASSERT_AS_CASSERT
00200 #endif
00201
00202
00203
00204 void testNoFunction()
00205 {
00206 boost::shared_ptr< FuncType > func;
00207 TS_ASSERT_THROWS( WWorkerThread< FuncType > w( func, 0, 1 ), WException );
00208 }
00209
00210
00211
00212
00213 void testThreadId()
00214 {
00215 boost::shared_ptr< FuncType > func( new FuncType( 5 ) );
00216 TS_ASSERT_THROWS( WWorkerThread< FuncType > w( func, 1, 0 ), WException );
00217 }
00218
00219 #ifdef WASSERT_FLAG_CHANGED
00220 #define WASSERT_AS_CASSERT
00221 #undefine WASSERT_FLAG_CHANGED
00222 #endif
00223
00224
00225
00226
00227 void testExceptions()
00228 {
00229 m_exceptionHandled = false;
00230
00231 boost::shared_ptr< ExceptionalFuncType > func( new ExceptionalFuncType );
00232 WWorkerThread< ExceptionalFuncType > w( func, 0, 1 );
00233 w.subscribeExceptionSignal( boost::bind( &WWorkerThreadTest::handleException, this, _1 ) );
00234
00235 w.run();
00236 w.wait();
00237
00238 TS_ASSERT_EQUALS( m_exceptionHandled, true );
00239 }
00240
00241 private:
00242
00243
00244
00245 void stopTestDone()
00246 {
00247 m_stopped = true;
00248 }
00249
00250
00251
00252
00253
00254
00255 void handleException( WException const& e )
00256 {
00257 if( strcmp( e.what(), "Test!" ) == 0 )
00258 {
00259 m_exceptionHandled = true;
00260 }
00261 }
00262
00263
00264 bool m_stopped;
00265
00266
00267 bool m_exceptionHandled;
00268 };
00269
00270 #endif // WWORKERTHREAD_TEST_H