2005-06-05 06:53:07 +00:00
/*
Unix SMB / CIFS implementation .
local test for irpc code
Copyright ( C ) Andrew Tridgell 2004
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2005-06-05 06:53:07 +00:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-06-05 06:53:07 +00:00
*/
# include "includes.h"
# include "lib/events/events.h"
# include "lib/messaging/irpc.h"
# include "librpc/gen_ndr/ndr_echo.h"
2006-03-25 16:01:28 +00:00
# include "torture/torture.h"
2007-01-10 13:22:09 +00:00
# include "cluster/cluster.h"
2007-09-08 12:42:09 +00:00
# include "param/param.h"
2005-06-05 06:53:07 +00:00
2005-06-07 11:35:23 +00:00
const uint32_t MSG_ID1 = 1 , MSG_ID2 = 2 ;
2005-06-05 06:53:07 +00:00
2007-10-06 22:28:14 +00:00
static bool test_debug ;
2005-07-31 23:49:44 +00:00
2006-06-16 22:06:09 +00:00
struct irpc_test_data
{
struct messaging_context * msg_ctx1 , * msg_ctx2 ;
2008-12-29 20:24:57 +01:00
struct tevent_context * ev ;
2006-06-16 22:06:09 +00:00
} ;
2005-06-05 06:53:07 +00:00
/*
serve up AddOne over the irpc system
*/
static NTSTATUS irpc_AddOne ( struct irpc_message * irpc , struct echo_AddOne * r )
{
* r - > out . out_data = r - > in . in_data + 1 ;
2005-07-31 23:49:44 +00:00
if ( test_debug ) {
printf ( " irpc_AddOne: in=%u in+1=%u out=%u \n " ,
r - > in . in_data , r - > in . in_data + 1 , * r - > out . out_data ) ;
}
2005-06-05 06:53:07 +00:00
return NT_STATUS_OK ;
}
2005-09-25 13:17:03 +00:00
/*
a deferred reply to echodata
*/
2008-12-29 20:24:57 +01:00
static void deferred_echodata ( struct tevent_context * ev , struct tevent_timer * te ,
2009-01-31 23:57:02 +01:00
struct timeval t , void * private_data )
2005-09-25 13:17:03 +00:00
{
2009-01-31 23:57:02 +01:00
struct irpc_message * irpc = talloc_get_type ( private_data , struct irpc_message ) ;
2005-09-25 13:17:03 +00:00
struct echo_EchoData * r = irpc - > data ;
r - > out . out_data = talloc_memdup ( r , r - > in . in_data , r - > in . len ) ;
if ( r - > out . out_data = = NULL ) {
irpc_send_reply ( irpc , NT_STATUS_NO_MEMORY ) ;
}
printf ( " sending deferred reply \n " ) ;
irpc_send_reply ( irpc , NT_STATUS_OK ) ;
}
2005-08-01 01:52:01 +00:00
/*
serve up EchoData over the irpc system
*/
static NTSTATUS irpc_EchoData ( struct irpc_message * irpc , struct echo_EchoData * r )
{
2007-10-06 22:28:14 +00:00
irpc - > defer_reply = true ;
2005-09-25 13:17:03 +00:00
event_add_timed ( irpc - > ev , irpc , timeval_zero ( ) , deferred_echodata , irpc ) ;
2005-08-01 01:52:01 +00:00
return NT_STATUS_OK ;
}
2005-06-05 06:53:07 +00:00
/*
test a addone call over the internal messaging system
*/
2006-10-16 13:06:41 +00:00
static bool test_addone ( struct torture_context * test , const void * _data ,
2006-09-14 11:43:59 +00:00
const void * _value )
2005-06-05 06:53:07 +00:00
{
struct echo_AddOne r ;
NTSTATUS status ;
2007-09-08 16:46:30 +00:00
const struct irpc_test_data * data = ( const struct irpc_test_data * ) _data ;
2009-02-01 00:02:17 +01:00
uint32_t value = * ( const uint32_t * ) _value ;
2006-06-12 20:10:11 +00:00
2005-06-05 06:53:07 +00:00
/* make the call */
2005-08-01 00:26:52 +00:00
r . in . in_data = value ;
2005-06-05 06:53:07 +00:00
2007-10-06 22:28:14 +00:00
test_debug = true ;
2008-02-04 17:51:38 +11:00
status = IRPC_CALL ( data - > msg_ctx1 , cluster_id ( 0 , MSG_ID2 ) ,
2007-01-10 10:52:09 +00:00
rpcecho , ECHO_ADDONE , & r , test ) ;
2007-10-06 22:28:14 +00:00
test_debug = false ;
2006-06-12 20:10:11 +00:00
torture_assert_ntstatus_ok ( test , status , " AddOne failed " ) ;
2005-06-05 06:53:07 +00:00
/* check the answer */
2006-10-16 13:06:41 +00:00
torture_assert ( test , * r . out . out_data = = r . in . in_data + 1 ,
2006-06-12 20:10:11 +00:00
" AddOne wrong answer " ) ;
2005-06-05 06:53:07 +00:00
2006-10-16 13:06:41 +00:00
torture_comment ( test , " %u + 1 = %u \n " , r . in . in_data , * r . out . out_data ) ;
return true ;
2005-06-05 06:53:07 +00:00
}
2005-08-01 01:52:01 +00:00
/*
test a echodata call over the internal messaging system
*/
2006-10-16 13:06:41 +00:00
static bool test_echodata ( struct torture_context * tctx ,
const void * tcase_data ,
const void * test_data )
2005-08-01 01:52:01 +00:00
{
struct echo_EchoData r ;
NTSTATUS status ;
2007-09-08 16:46:30 +00:00
const struct irpc_test_data * data = ( const struct irpc_test_data * ) tcase_data ;
2006-10-16 13:06:41 +00:00
TALLOC_CTX * mem_ctx = tctx ;
2006-06-12 20:10:11 +00:00
2005-08-01 01:52:01 +00:00
/* make the call */
2006-10-16 13:06:41 +00:00
r . in . in_data = ( unsigned char * ) talloc_strdup ( mem_ctx , " 0123456789 " ) ;
2005-09-25 13:17:03 +00:00
r . in . len = strlen ( ( char * ) r . in . in_data ) ;
2005-08-01 01:52:01 +00:00
2008-02-04 17:51:38 +11:00
status = IRPC_CALL ( data - > msg_ctx1 , cluster_id ( 0 , MSG_ID2 ) ,
2007-01-10 10:52:09 +00:00
rpcecho , ECHO_ECHODATA , & r ,
mem_ctx ) ;
2006-10-16 13:06:41 +00:00
torture_assert_ntstatus_ok ( tctx , status , " EchoData failed " ) ;
2005-08-01 01:52:01 +00:00
/* check the answer */
if ( memcmp ( r . out . out_data , r . in . in_data , r . in . len ) ! = 0 ) {
NDR_PRINT_OUT_DEBUG ( echo_EchoData , & r ) ;
2006-10-16 13:06:41 +00:00
torture_fail ( tctx , " EchoData wrong answer " ) ;
2005-08-01 01:52:01 +00:00
}
2006-10-16 13:06:41 +00:00
torture_comment ( tctx , " Echo '%*.*s' -> '%*.*s' \n " ,
2005-08-01 01:52:01 +00:00
r . in . len , r . in . len ,
r . in . in_data ,
r . in . len , r . in . len ,
r . out . out_data ) ;
2006-10-16 13:06:41 +00:00
return true ;
2005-08-01 01:52:01 +00:00
}
2005-06-05 07:30:44 +00:00
static void irpc_callback ( struct irpc_request * irpc )
{
2007-09-08 16:46:30 +00:00
struct echo_AddOne * r = ( struct echo_AddOne * ) irpc - > r ;
2009-02-01 00:03:47 +01:00
int * pong_count = ( int * ) irpc - > async . private_data ;
2005-06-05 07:30:44 +00:00
NTSTATUS status = irpc_call_recv ( irpc ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " irpc call failed - %s \n " , nt_errstr ( status ) ) ;
}
2005-07-31 23:55:10 +00:00
if ( * r - > out . out_data ! = r - > in . in_data + 1 ) {
printf ( " AddOne wrong answer - %u + 1 = %u should be %u \n " ,
r - > in . in_data , * r - > out . out_data , r - > in . in_data + 1 ) ;
}
2005-06-05 07:30:44 +00:00
( * pong_count ) + + ;
}
/*
test echo speed
*/
2006-10-16 13:06:41 +00:00
static bool test_speed ( struct torture_context * tctx ,
const void * tcase_data ,
const void * test_data )
2005-06-05 07:30:44 +00:00
{
int ping_count = 0 ;
int pong_count = 0 ;
2007-09-08 16:46:30 +00:00
const struct irpc_test_data * data = ( const struct irpc_test_data * ) tcase_data ;
2005-06-05 07:30:44 +00:00
struct timeval tv ;
struct echo_AddOne r ;
2006-10-16 13:06:41 +00:00
TALLOC_CTX * mem_ctx = tctx ;
int timelimit = torture_setting_int ( tctx , " timelimit " , 10 ) ;
2005-06-05 07:30:44 +00:00
tv = timeval_current ( ) ;
r . in . in_data = 0 ;
2006-10-16 13:06:41 +00:00
torture_comment ( tctx , " Sending echo for %d seconds \n " , timelimit ) ;
2005-07-28 04:07:51 +00:00
while ( timeval_elapsed ( & tv ) < timelimit ) {
2005-06-05 07:30:44 +00:00
struct irpc_request * irpc ;
2008-02-04 17:51:38 +11:00
irpc = IRPC_CALL_SEND ( data - > msg_ctx1 , cluster_id ( 0 , MSG_ID2 ) ,
2007-01-10 10:52:09 +00:00
rpcecho , ECHO_ADDONE ,
& r , mem_ctx ) ;
2006-10-16 13:06:41 +00:00
torture_assert ( tctx , irpc ! = NULL , " AddOne send failed " ) ;
2005-06-05 07:30:44 +00:00
irpc - > async . fn = irpc_callback ;
2009-02-01 00:03:47 +01:00
irpc - > async . private_data = & pong_count ;
2005-06-05 07:30:44 +00:00
ping_count + + ;
while ( ping_count > pong_count + 20 ) {
2006-06-16 22:06:09 +00:00
event_loop_once ( data - > ev ) ;
2005-06-05 07:30:44 +00:00
}
}
2006-10-16 13:06:41 +00:00
torture_comment ( tctx , " waiting for %d remaining replies (done %d) \n " ,
2005-06-05 07:30:44 +00:00
ping_count - pong_count , pong_count ) ;
while ( timeval_elapsed ( & tv ) < 30 & & pong_count < ping_count ) {
2006-06-16 22:06:09 +00:00
event_loop_once ( data - > ev ) ;
2005-06-05 07:30:44 +00:00
}
2006-10-16 13:06:41 +00:00
torture_assert_int_equal ( tctx , ping_count , pong_count , " ping test failed " ) ;
2005-06-05 07:30:44 +00:00
2006-10-16 13:06:41 +00:00
torture_comment ( tctx , " echo rate of %.0f messages/sec \n " ,
2005-06-05 07:30:44 +00:00
( ping_count + pong_count ) / timeval_elapsed ( & tv ) ) ;
2006-10-16 13:06:41 +00:00
return true ;
2005-06-05 07:30:44 +00:00
}
2007-10-06 22:28:14 +00:00
static bool irpc_setup ( struct torture_context * tctx , void * * _data )
2005-06-05 06:53:07 +00:00
{
2006-06-16 22:06:09 +00:00
struct irpc_test_data * data ;
2006-10-16 13:06:41 +00:00
* _data = data = talloc ( tctx , struct irpc_test_data ) ;
2005-06-05 06:53:07 +00:00
2010-07-16 14:32:42 +10:00
lpcfg_set_cmdline ( tctx - > lp_ctx , " pid directory " , " piddir.tmp " ) ;
2005-06-05 06:53:07 +00:00
2007-05-17 08:47:04 +00:00
data - > ev = tctx - > ev ;
2007-01-10 10:52:09 +00:00
torture_assert ( tctx , data - > msg_ctx1 =
messaging_init ( tctx ,
2010-07-16 14:32:42 +10:00
lpcfg_messaging_path ( tctx , tctx - > lp_ctx ) ,
2008-02-04 17:51:38 +11:00
cluster_id ( 0 , MSG_ID1 ) ,
2007-12-13 23:23:25 +01:00
data - > ev ) ,
2007-01-10 10:52:09 +00:00
" Failed to init first messaging context " ) ;
torture_assert ( tctx , data - > msg_ctx2 =
messaging_init ( tctx ,
2010-07-16 14:32:42 +10:00
lpcfg_messaging_path ( tctx , tctx - > lp_ctx ) ,
2008-02-04 17:51:38 +11:00
cluster_id ( 0 , MSG_ID2 ) ,
2007-12-13 23:23:25 +01:00
data - > ev ) ,
2007-01-10 10:52:09 +00:00
" Failed to init second messaging context " ) ;
2005-06-05 06:53:07 +00:00
2005-06-05 07:30:44 +00:00
/* register the server side function */
2006-06-16 22:06:09 +00:00
IRPC_REGISTER ( data - > msg_ctx1 , rpcecho , ECHO_ADDONE , irpc_AddOne , NULL ) ;
IRPC_REGISTER ( data - > msg_ctx2 , rpcecho , ECHO_ADDONE , irpc_AddOne , NULL ) ;
2005-06-05 07:30:44 +00:00
2006-06-16 22:06:09 +00:00
IRPC_REGISTER ( data - > msg_ctx1 , rpcecho , ECHO_ECHODATA , irpc_EchoData , NULL ) ;
IRPC_REGISTER ( data - > msg_ctx2 , rpcecho , ECHO_ECHODATA , irpc_EchoData , NULL ) ;
2005-08-01 01:52:01 +00:00
2007-10-06 22:28:14 +00:00
return true ;
2006-06-16 22:06:09 +00:00
}
2005-06-05 06:53:07 +00:00
2006-06-17 00:17:50 +00:00
struct torture_suite * torture_local_irpc ( TALLOC_CTX * mem_ctx )
2006-06-16 22:06:09 +00:00
{
2006-10-16 13:06:41 +00:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " IRPC " ) ;
2006-06-16 22:06:09 +00:00
struct torture_tcase * tcase = torture_suite_add_tcase ( suite , " irpc " ) ;
int i ;
2006-09-14 05:13:20 +00:00
uint32_t * values = talloc_array ( tcase , uint32_t , 5 ) ;
values [ 0 ] = 0 ;
values [ 1 ] = 0x7FFFFFFE ;
values [ 2 ] = 0xFFFFFFFE ;
values [ 3 ] = 0xFFFFFFFF ;
values [ 4 ] = random ( ) & 0xFFFFFFFF ;
2006-06-16 22:06:09 +00:00
tcase - > setup = irpc_setup ;
2006-09-14 05:13:20 +00:00
for ( i = 0 ; i < 5 ; i + + ) {
2007-12-24 13:04:56 -06:00
torture_tcase_add_test_const ( tcase , " addone " , test_addone ,
2009-02-01 00:02:17 +01:00
( void * ) & values [ i ] ) ;
2006-06-16 22:06:09 +00:00
}
2007-12-24 13:04:56 -06:00
torture_tcase_add_test_const ( tcase , " echodata " , test_echodata , NULL ) ;
torture_tcase_add_test_const ( tcase , " speed " , test_speed , NULL ) ;
2005-06-05 06:53:07 +00:00
2006-06-17 00:17:50 +00:00
return suite ;
2005-06-05 06:53:07 +00:00
}