OSDN Git Service

ソースツリー再構成中(ほぼOK?)
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / modtester / .modtester.cpp
1 //
2 //                      module test utility.
3 //
4 //
5 //
6 #include <string>
7 #include <list>
8 #include <map>
9 #include <time.h>
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"
21
22 using namespace std;
23 using namespace boost;
24 using namespace boost::unit_test;
25 using namespace l7vs;
26
27 string  targetdir;
28 string  targetfile;
29
30 unsigned int get_random_value( unsigned int max, unsigned int min ){
31         random_device   dev;
32         unsigned int val = dev();
33         val %= max + 1;
34         if( val < min ) val += min - val;
35         return val;
36 }
37
38 string  string_address_generator( bool ipv6 = false ){
39         if( !ipv6 ){
40                 format  frmt( "%1%.%2%.%3%.%4%" );
41                         frmt
42                         % get_random_value( 255, 10 )
43                         % get_random_value( 255, 10 )
44                         % get_random_value( 255, 10 )
45                         % get_random_value( 255, 10 );
46                 return frmt.str();
47         }
48         else{
49                 format frmt( "%x:%x:%x:%x:%x:%x:%x" );
50                         frmt
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 );
59                 return frmt.str();
60         }
61 }
62
63
64 //
65 // logger functions
66 //
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() );
72 }
73 //
74 // list_iterator_func
75 //
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++(); }
79 void    listlock(){}
80 void    listunlock(){}
81
82 //
83 // module thread func
84 void    module_upthread_func( protocol_module_base* prot ){
85         asio::ip::tcp::endpoint                 point;
86
87         list< realserver >      serverlist;
88         {
89                 unsigned int num = get_random_value( 50 , 2 );
90                 for( unsigned int i = 0; i < num; ++i ){
91                         realserver      server;
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 );
94                 }
95         }
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 ) );
101         data_creater    data;
102         array<char, MAX_BUFFER_SIZE>    buf;
103         size_t                                                  length;
104         string                                                  dataname;
105         data.create_data( buf, length, dataname );
106
107         //parameter created
108         vector<string>  args;
109         prot->check_parameter( args );
110         prot->set_parameter( args );
111
112         protocol_module_base::EVENT_TAG event = protocol_module_base::ACCEPT;
113         while( event != protocol_module_base::FINALIZE ){
114                 switch( event ){
115                         case    protocol_module_base::ACCEPT:
116                                         event = prot->handle_accept( this_thread::get_id() );
117                                 break;
118                         case    protocol_module_base::CLIENT_RECV:
119                                         event = prot->handle_client_recv( this_thread::get_id(), buf, length );
120                                 break;
121                         case    protocol_module_base::REALSERVER_SELECT:
122                                         event = prot->handle_realserver_select( this_thread::get_id(), serverlist.begin()->tcp_endpoint );
123                                 break;
124                         case    protocol_module_base::REALSERVER_CONNECT:
125                                         event = prot->handle_realserver_connect( this_thread::get_id(), buf, length );
126                                 break;
127                         case    protocol_module_base::REALSERVER_SEND:
128                                         event = prot->handle_realserver_send( this_thread::get_id() );
129                                 break;
130                         case    protocol_module_base::SORRYSERVER_SELECT:
131                                         event = prot->handle_sorryserver_select( this_thread::get_id(), point );
132                                 break;
133                         case    protocol_module_base::SORRYSERVER_CONNECT:
134                                         event = prot->handle_sorryserver_connect(this_thread::get_id(),buf, length );
135                                 break;
136                         case    protocol_module_base::SORRYSERVER_SEND:
137                                         event = prot->handle_sorryserver_send( this_thread::get_id() );
138                                 break;
139                         case    protocol_module_base::CLIENT_RESPONSE_SEND:
140                                         event = prot->handle_response_send_inform( this_thread::get_id() );
141                                 break;
142                         case    protocol_module_base::REALSERVER_DISCONNECT:
143                                         event = prot->handle_realserver_disconnect( this_thread::get_id(), asio::ip::tcp::endpoint() );
144                                 break;
145                         case    protocol_module_base::SORRYSERVER_DISCONNECT:
146                                         event = prot->handle_sorryserver_disconnect( this_thread::get_id(), asio::ip::tcp::endpoint() );
147                                 break;
148                         case    protocol_module_base::CLIENT_DISCONNECT:
149                                         event = prot->handle_client_disconnect( this_thread::get_id() );
150                                 break;
151                         default:
152                                 break;
153                 }
154         }
155         prot->finalize();
156 }
157
158 void    module_downthread_func( protocol_module_base* prot ){
159         asio::ip::tcp::endpoint point;
160         array<char,MAX_BUFFER_SIZE>     buf;
161         size_t  length;
162         protocol_module_base::EVENT_TAG event = protocol_module_base::REALSERVER_RECV;
163         while( event != protocol_module_base::FINALIZE ){
164                 switch( event ){
165                         case    protocol_module_base::REALSERVER_RECV:
166                                 event = prot->handle_realserver_recv( this_thread::get_id(), point, buf, length );
167                                 break;
168                         case    protocol_module_base::SORRYSERVER_RECV:
169                                 event = prot->handle_sorryserver_recv( this_thread::get_id(), point, buf, length );
170                                 break;
171                         case    protocol_module_base::CLIENT_CONNECTION_CHECK:
172                                 event = prot->handle_client_connection_check( this_thread::get_id(), buf, length );
173                                 break;
174                         case    protocol_module_base::CLIENT_SEND:
175                                 event = prot->handle_client_send( this_thread::get_id() );
176                                 break;
177                         case    protocol_module_base::REALSERVER_DISCONNECT:
178                                 event = prot->handle_realserver_disconnect( this_thread::get_id(), point );
179                                 break;
180                         case    protocol_module_base::SORRYSERVER_DISCONNECT:
181                                 event = prot->handle_sorryserver_disconnect( this_thread::get_id(), point );
182                                 break;
183                         case    protocol_module_base::CLIENT_DISCONNECT:
184                                 event = prot->handle_client_disconnect( this_thread::get_id() );
185                                 break;
186                 }
187         }
188         prot->finalize();
189 }
190
191
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 );
197         BOOST_CHECK( prot );
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 );
202
203         BOOST_MESSAGE( "PROTOCOL_MODULE TEST : module initialize" );
204
205         unsigned int thread_count = get_random_value( 100, 10 );
206         {
207                 format  frmt( "PROTOCOL_MODULE TEST : create thread num = %1%" );
208                 frmt % thread_count;
209                 BOOST_MESSAGE( frmt.str() );
210         }
211         thread_group    tg;
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 ) );
216         }
217         BOOST_MESSAGE( "PROTOCOL_MODULE TEST : main thread waiting" );
218         tg.join_all();
219         BOOST_MESSAGE( "PROTOCOL_MODULE TEST : all thread is die. test end." );
220 }
221
222
223 // schedule_module_test
224 //
225 //
226 //
227
228 void    schedule_thread_func( schedule_module_base* sched ){
229         //data setting
230         asio::ip::tcp::endpoint accept_point = asio::ip::tcp::endpoint( asio::ip::address::from_string( string_address_generator() ), get_random_value( 65535, 10000 ) );
231
232 //      boost::lambda::placeholder1_type        ph1_type;
233
234         list< realserver >      serverlist;
235         {
236                 unsigned int num = get_random_value( 50 , 2 );
237                 for( unsigned int i = 0; i < num; ++i ){
238                         realserver      server;
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 );
241                 }
242         }
243         // thread loop
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 ),
250                                 point );
251                 struct  timespec        spec;
252                 spec.tv_sec = 0;
253                 spec.tv_nsec = static_cast<long>( get_random_value( 1000, 10 ) );
254                 nanosleep( &spec, NULL );
255         }
256 }
257
258 void    schedule_module_test(){
259         BOOST_MESSAGE( "SCHEDULE_MODULE TEST : controller load" );
260         schedule_module_control& ctl = schedule_module_control::getInstance();
261
262         BOOST_MESSAGE( "SCHEDULE_MODULE TEST : controller initialize" );
263         ctl.initialize( targetdir );
264
265         BOOST_MESSAGE( "SCHEDULE_MODULE TEST : controller module load" );
266         schedule_module_base*   sched = ctl.load_module( targetfile );
267         BOOST_CHECK( sched );
268
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 );
273
274         BOOST_MESSAGE( "SCHEDULE_MODULE TEST : module initialize" );
275         sched->initialize();
276
277         unsigned int thread_count = get_random_value( 100, 10 );
278         {
279                 format  frmt( "SCHEDULE_MODUE TEST : create thread num = %1%" );
280                 frmt % thread_count;
281                 BOOST_MESSAGE( frmt.str() );
282         }
283         thread_group    tg;
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" );
289         tg.join_all();
290         BOOST_MESSAGE( "SCHEDULE_MODULE TEST : all thread is die. test end." );
291 }
292
293 void    usage(){
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;
299 }
300
301
302 test_suite*     init_unit_test_suite( int argc, char* argv[] ){
303         // argc check
304         if( argc != 3 ){
305                 usage();
306                 return 0;
307         }
308
309         // command check
310         if( string( argv[1] ) != string( "-s" ) ||
311                 string( argv[1] ) != string( "-p" ) ){
312                 cout << "\n\n commad not found : " << argv[1] << endl;
313                 usage();
314                 return 0;
315         }
316
317         // module file check
318         filesystem::path modulename( argv[2] );
319         if( !filesystem::exists( modulename ) ){
320                 cout << "\n\n not found shared file : " << modulename.string() << "\n\n" << endl;
321                 usage();
322                 return 0;
323         }
324
325         targetdir  = modulename.branch_path().string();
326         targetfile = modulename.leaf();
327         targetfile = targetfile.substr( 2, targetfile.length() - 3 );
328
329         test_suite*     ts = BOOST_TEST_SUITE( "modtester" );
330
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 ) );
333
334         framework::master_test_suite().add( ts );
335
336         return 0;
337 }