2006-05-24 18:19:34 +04:00
/*
Unix SMB / CIFS implementation .
testing of the events subsystem
Copyright ( C ) Stefan Metzmacher
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 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-05-24 18:19:34 +04: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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-05-24 18:19:34 +04:00
*/
# include "includes.h"
# include "lib/events/events.h"
# include "system/filesys.h"
# include "torture/torture.h"
static int fde_count ;
static void fde_handler ( struct event_context * ev_ctx , struct fd_event * f ,
uint16_t flags , void * private )
{
2007-09-08 20:46:30 +04:00
int * fd = ( int * ) private ;
2007-01-21 13:32:39 +03:00
char c ;
# ifdef SA_SIGINFO
kill ( getpid ( ) , SIGUSR1 ) ;
# endif
kill ( getpid ( ) , SIGALRM ) ;
read ( fd [ 0 ] , & c , 1 ) ;
write ( fd [ 1 ] , & c , 1 ) ;
2006-05-24 18:19:34 +04:00
fde_count + + ;
}
2007-01-21 13:32:39 +03:00
static void finished_handler ( struct event_context * ev_ctx , struct timed_event * te ,
struct timeval tval , void * private )
2006-05-24 18:19:34 +04:00
{
2007-09-08 20:46:30 +04:00
int * finished = ( int * ) private ;
2007-01-21 13:32:39 +03:00
( * finished ) = 1 ;
2006-05-24 18:19:34 +04:00
}
2007-01-21 13:32:39 +03:00
static void count_handler ( struct event_context * ev_ctx , struct signal_event * te ,
int signum , int count , void * info , void * private )
{
2007-09-08 20:46:30 +04:00
int * countp = ( int * ) private ;
2007-01-21 13:32:39 +03:00
( * countp ) + = count ;
}
static bool test_event_context ( struct torture_context * test ,
const void * test_data )
2006-05-24 18:19:34 +04:00
{
2006-06-17 02:06:09 +04:00
struct event_context * ev_ctx ;
2006-05-24 18:19:34 +04:00
int fd [ 2 ] = { - 1 , - 1 } ;
2007-01-05 12:35:49 +03:00
const char * backend = ( const char * ) test_data ;
2007-01-21 13:32:39 +03:00
int alarm_count = 0 , info_count = 0 ;
struct fd_event * fde ;
struct signal_event * se1 , * se2 , * se3 ;
int finished = 0 ;
struct timeval t ;
char c = 0 ;
ev_ctx = event_context_init_byname ( test , backend ) ;
2007-01-05 12:35:49 +03:00
if ( ev_ctx = = NULL ) {
torture_comment ( test , " event backend '%s' not supported \n " , backend ) ;
return true ;
}
torture_comment ( test , " Testing event backend '%s' \n " , backend ) ;
2006-05-24 18:19:34 +04:00
/* reset globals */
fde_count = 0 ;
/* create a pipe */
pipe ( fd ) ;
2007-05-14 05:01:05 +04:00
fde = event_add_fd ( ev_ctx , ev_ctx , fd [ 0 ] , EVENT_FD_READ | EVENT_FD_AUTOCLOSE ,
2007-01-21 13:32:39 +03:00
fde_handler , fd ) ;
event_add_timed ( ev_ctx , ev_ctx , timeval_current_ofs ( 2 , 0 ) ,
finished_handler , & finished ) ;
2006-05-24 18:19:34 +04:00
2007-01-21 13:32:39 +03:00
se1 = event_add_signal ( ev_ctx , ev_ctx , SIGALRM , SA_RESTART , count_handler , & alarm_count ) ;
se2 = event_add_signal ( ev_ctx , ev_ctx , SIGALRM , SA_RESETHAND , count_handler , & alarm_count ) ;
# ifdef SA_SIGINFO
se3 = event_add_signal ( ev_ctx , ev_ctx , SIGUSR1 , SA_SIGINFO , count_handler , & info_count ) ;
# endif
2006-05-24 18:19:34 +04:00
2007-01-21 13:32:39 +03:00
write ( fd [ 1 ] , & c , 1 ) ;
t = timeval_current ( ) ;
while ( ! finished ) {
2007-08-10 11:40:50 +04:00
errno = 0 ;
2007-01-24 07:30:44 +03:00
if ( event_loop_once ( ev_ctx ) = = - 1 ) {
talloc_free ( ev_ctx ) ;
2007-08-17 09:21:05 +04:00
torture_fail ( test , talloc_asprintf ( test , " Failed event loop %s \n " , strerror ( errno ) ) ) ;
2007-01-24 07:30:44 +03:00
}
2007-01-21 13:32:39 +03:00
}
talloc_free ( fde ) ;
close ( fd [ 1 ] ) ;
while ( alarm_count < fde_count + 1 ) {
2007-01-24 07:30:44 +03:00
if ( event_loop_once ( ev_ctx ) = = - 1 ) {
break ;
}
2007-01-21 13:32:39 +03:00
}
torture_comment ( test , " Got %.2f pipe events/sec \n " , fde_count / timeval_elapsed ( & t ) ) ;
talloc_free ( se1 ) ;
torture_assert_int_equal ( test , alarm_count , 1 + fde_count , " alarm count mismatch " ) ;
# ifdef SA_SIGINFO
talloc_free ( se3 ) ;
torture_assert_int_equal ( test , info_count , fde_count , " info count mismatch " ) ;
# endif
2006-05-24 18:19:34 +04:00
2006-06-17 02:06:09 +04:00
talloc_free ( ev_ctx ) ;
2007-01-21 13:32:39 +03:00
2006-10-16 17:06:41 +04:00
return true ;
2006-05-24 18:19:34 +04:00
}
2006-06-17 04:17:50 +04:00
struct torture_suite * torture_local_event ( TALLOC_CTX * mem_ctx )
2006-05-24 18:19:34 +04:00
{
2006-10-16 17:06:41 +04:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " EVENT " ) ;
2007-01-05 12:35:49 +03:00
const char * * list = event_backend_list ( suite ) ;
int i ;
2006-05-24 18:19:34 +04:00
2007-01-05 12:35:49 +03:00
for ( i = 0 ; list & & list [ i ] ; i + + ) {
2007-12-24 22:04:56 +03:00
torture_suite_add_simple_tcase_const ( suite , list [ i ] ,
2007-01-05 12:35:49 +03:00
test_event_context ,
( const void * ) list [ i ] ) ;
}
2006-05-24 18:19:34 +04:00
2006-06-17 04:17:50 +04:00
return suite ;
2006-05-24 18:19:34 +04:00
}