2 // module test utility.
10 #include <boost/format.hpp>
11 #include <boost/algorithm/string.hpp>
12 #include <boost/nondet_random.hpp>
13 #include <boost/bind.hpp>
14 // #include <boost/lambda/lambda.hpp>
15 #include <boost/thread.hpp>
16 #include <boost/test/included/unit_test.hpp>
17 #include <boost/filesystem.hpp>
18 #include "protocol_module_control.h"
19 #include "schedule_module_control.h"
20 #include "data_creater.h"
23 using namespace boost;
24 using namespace boost::unit_test;
30 unsigned int get_random_value( unsigned int max, unsigned int min ){
32 unsigned int val = dev();
34 if( val < min ) val += min - val;
38 string string_address_generator( bool ipv6 = false ){
40 format frmt( "%1%.%2%.%3%.%4%" );
42 % get_random_value( 255, 10 )
43 % get_random_value( 255, 10 )
44 % get_random_value( 255, 10 )
45 % get_random_value( 255, 10 );
49 format frmt( "%x:%x:%x:%x:%x:%x:%x" );
51 % get_random_value( 0xffff, 0x1 )
52 % get_random_value( 0xffff, 0x1 )
53 % get_random_value( 0xffff, 0x1 )
54 % get_random_value( 0xffff, 0x1 )
55 % get_random_value( 0xffff, 0x1 )
56 % get_random_value( 0xffff, 0x1 )
57 % get_random_value( 0xffff, 0x1 )
58 % get_random_value( 0xffff, 0x1 );
67 LOG_LEVEL_TAG get_loglevel_func(){ return LOG_LV_DEBUG; }
68 void log_put_func( const unsigned int no, const string& mes, const char* file, int line ){
69 format frmt( "%1% : %2% [%3%] %4%" );
70 frmt % file % line % no % mes;
71 BOOST_MESSAGE( frmt.str() );
76 list<realserver>::iterator begin_func( list<realserver>& inlist ){ return inlist.begin(); }
77 list<realserver>::iterator end_func( list<realserver>& inlist ){ return inlist.end(); }
78 list<realserver>::iterator next_func( list<realserver>::iterator& itr ){ return itr.operator++(); }
84 void module_upthread_func( protocol_module_base* prot ){
85 asio::ip::tcp::endpoint point;
87 list< realserver > serverlist;
89 unsigned int num = get_random_value( 50 , 2 );
90 for( unsigned int i = 0; i < num; ++i ){
92 server.tcp_endpoint = asio::ip::tcp::endpoint( asio::ip::address::from_string( string_address_generator() ), get_random_value( 65535, 10000 ) );
93 serverlist.push_back( server );
96 prot->initialize( bind( &begin_func, serverlist ),
97 bind( &end_func, serverlist ),
98 bind( &next_func, _1 ),
99 function< void ( void ) >( &listlock ),
100 function< void ( void ) >( &listunlock ) );
102 array<char, MAX_BUFFER_SIZE> buf;
105 data.create_data( buf, length, dataname );
109 prot->check_parameter( args );
110 prot->set_parameter( args );
112 protocol_module_base::EVENT_TAG event = protocol_module_base::ACCEPT;
113 while( event != protocol_module_base::FINALIZE ){
115 case protocol_module_base::ACCEPT:
116 event = prot->handle_accept( this_thread::get_id() );
118 case protocol_module_base::CLIENT_RECV:
119 event = prot->handle_client_recv( this_thread::get_id(), buf, length );
121 case protocol_module_base::REALSERVER_SELECT:
122 event = prot->handle_realserver_select( this_thread::get_id(), serverlist.begin()->tcp_endpoint );
124 case protocol_module_base::REALSERVER_CONNECT:
125 event = prot->handle_realserver_connect( this_thread::get_id(), buf, length );
127 case protocol_module_base::REALSERVER_SEND:
128 event = prot->handle_realserver_send( this_thread::get_id() );
130 case protocol_module_base::SORRYSERVER_SELECT:
131 event = prot->handle_sorryserver_select( this_thread::get_id(), point );
133 case protocol_module_base::SORRYSERVER_CONNECT:
134 event = prot->handle_sorryserver_connect(this_thread::get_id(),buf, length );
136 case protocol_module_base::SORRYSERVER_SEND:
137 event = prot->handle_sorryserver_send( this_thread::get_id() );
139 case protocol_module_base::CLIENT_RESPONSE_SEND:
140 event = prot->handle_response_send_inform( this_thread::get_id() );
142 case protocol_module_base::REALSERVER_DISCONNECT:
143 event = prot->handle_realserver_disconnect( this_thread::get_id(), asio::ip::tcp::endpoint() );
145 case protocol_module_base::SORRYSERVER_DISCONNECT:
146 event = prot->handle_sorryserver_disconnect( this_thread::get_id(), asio::ip::tcp::endpoint() );
148 case protocol_module_base::CLIENT_DISCONNECT:
149 event = prot->handle_client_disconnect( this_thread::get_id() );
158 void module_downthread_func( protocol_module_base* prot ){
159 asio::ip::tcp::endpoint point;
160 array<char,MAX_BUFFER_SIZE> buf;
162 protocol_module_base::EVENT_TAG event = protocol_module_base::REALSERVER_RECV;
163 while( event != protocol_module_base::FINALIZE ){
165 case protocol_module_base::REALSERVER_RECV:
166 event = prot->handle_realserver_recv( this_thread::get_id(), point, buf, length );
168 case protocol_module_base::SORRYSERVER_RECV:
169 event = prot->handle_sorryserver_recv( this_thread::get_id(), point, buf, length );
171 case protocol_module_base::CLIENT_CONNECTION_CHECK:
172 event = prot->handle_client_connection_check( this_thread::get_id(), buf, length );
174 case protocol_module_base::CLIENT_SEND:
175 event = prot->handle_client_send( this_thread::get_id() );
177 case protocol_module_base::REALSERVER_DISCONNECT:
178 event = prot->handle_realserver_disconnect( this_thread::get_id(), point );
180 case protocol_module_base::SORRYSERVER_DISCONNECT:
181 event = prot->handle_sorryserver_disconnect( this_thread::get_id(), point );
183 case protocol_module_base::CLIENT_DISCONNECT:
184 event = prot->handle_client_disconnect( this_thread::get_id() );
192 // protocol_module_test
193 void protocol_module_test(){
194 protocol_module_control& ctl = protocol_module_control::getInstance();
195 ctl.initialize( targetdir );
196 protocol_module_base* prot = ctl.load_module( targetfile );
198 BOOST_MESSAGE( "PROTOCOL_MODULE TEST : init logger function" );
199 module_base::logger_func_type logfunc = &log_put_func;
200 module_base::getloglevel_func_type getlevelfunc = &get_loglevel_func;
201 prot->init_logger_functions( get_loglevel_func, logfunc, logfunc, logfunc, logfunc, logfunc );
203 BOOST_MESSAGE( "PROTOCOL_MODULE TEST : module initialize" );
205 unsigned int thread_count = get_random_value( 100, 10 );
207 format frmt( "PROTOCOL_MODULE TEST : create thread num = %1%" );
209 BOOST_MESSAGE( frmt.str() );
212 BOOST_MESSAGE( "PROTOCOL_MODULE TEST : create threads" );
213 for( unsigned int i = 0 ; i < thread_count; ++i ){
214 tg.create_thread( bind( &module_upthread_func, prot ) );
215 tg.create_thread( bind( &module_downthread_func, prot ) );
217 BOOST_MESSAGE( "PROTOCOL_MODULE TEST : main thread waiting" );
219 BOOST_MESSAGE( "PROTOCOL_MODULE TEST : all thread is die. test end." );
223 // schedule_module_test
228 void schedule_thread_func( schedule_module_base* sched ){
230 asio::ip::tcp::endpoint accept_point = asio::ip::tcp::endpoint( asio::ip::address::from_string( string_address_generator() ), get_random_value( 65535, 10000 ) );
232 // boost::lambda::placeholder1_type ph1_type;
234 list< realserver > serverlist;
236 unsigned int num = get_random_value( 50 , 2 );
237 for( unsigned int i = 0; i < num; ++i ){
239 server.tcp_endpoint = asio::ip::tcp::endpoint( asio::ip::address::from_string( string_address_generator() ), get_random_value( 65535, 10000 ) );
240 serverlist.push_back( server );
244 for( unsigned int i = 0; i < 1024; ++i ){
245 asio::ip::tcp::endpoint point;
246 sched->handle_schedule( this_thread::get_id(),
247 bind( &begin_func, serverlist ),
248 bind( &end_func, serverlist ),
249 bind( &next_func, _1 ),
251 struct timespec spec;
253 spec.tv_nsec = static_cast<long>( get_random_value( 1000, 10 ) );
254 nanosleep( &spec, NULL );
258 void schedule_module_test(){
259 BOOST_MESSAGE( "SCHEDULE_MODULE TEST : controller load" );
260 schedule_module_control& ctl = schedule_module_control::getInstance();
262 BOOST_MESSAGE( "SCHEDULE_MODULE TEST : controller initialize" );
263 ctl.initialize( targetdir );
265 BOOST_MESSAGE( "SCHEDULE_MODULE TEST : controller module load" );
266 schedule_module_base* sched = ctl.load_module( targetfile );
267 BOOST_CHECK( sched );
269 BOOST_MESSAGE( "SCHEDULE_MODULE TEST : init logger function" );
270 module_base::logger_func_type logfunc = &log_put_func;
271 module_base::getloglevel_func_type getlevelfunc = &get_loglevel_func;
272 sched->init_logger_functions( get_loglevel_func, logfunc, logfunc, logfunc, logfunc, logfunc );
274 BOOST_MESSAGE( "SCHEDULE_MODULE TEST : module initialize" );
277 unsigned int thread_count = get_random_value( 100, 10 );
279 format frmt( "SCHEDULE_MODUE TEST : create thread num = %1%" );
281 BOOST_MESSAGE( frmt.str() );
284 BOOST_MESSAGE( "SCHEDULE_MODULE TEST : create threads" );
285 for( unsigned int i = 0 ; i < thread_count; ++i )
286 tg.create_thread( bind( &schedule_thread_func, sched ) );
287 // tg.create_thread( &schedule_thread_func );
288 BOOST_MESSAGE( "SCHEDULE_MODULE TEST : main thread waiting" );
290 BOOST_MESSAGE( "SCHEDULE_MODULE TEST : all thread is die. test end." );
294 cout << " modtester [-s|-p] modulename \n"
295 " -s is shcedule module test.\n"
296 " -p is schedule module test.\n"
297 " modulename is loading schedule module file \n"
298 " copyright NTTComware corporation. 2009- " << endl;
302 test_suite* init_unit_test_suite( int argc, char* argv[] ){
310 if( string( argv[1] ) != string( "-s" ) ||
311 string( argv[1] ) != string( "-p" ) ){
312 cout << "\n\n commad not found : " << argv[1] << endl;
318 filesystem::path modulename( argv[2] );
319 if( !filesystem::exists( modulename ) ){
320 cout << "\n\n not found shared file : " << modulename.string() << "\n\n" << endl;
325 targetdir = modulename.branch_path().string();
326 targetfile = modulename.leaf();
327 targetfile = targetfile.substr( 2, targetfile.length() - 3 );
329 test_suite* ts = BOOST_TEST_SUITE( "modtester" );
331 if( string( argv[1] ) == string( "-s" ) ) ts->add( BOOST_TEST_CASE( &schedule_module_test ) );
332 if( string( argv[2] ) == string( "-p" ) ) ts->add( BOOST_TEST_CASE( &protocol_module_test ) );
334 framework::master_test_suite().add( ts );