2005-05-18 04:17:24 +00:00
/*
Unix SMB / CIFS implementation .
CLDAP benchmark test
Copyright ( C ) Andrew Tridgell 2005
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-05-18 04:17:24 +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-05-18 04:17:24 +00:00
*/
# include "includes.h"
# include "libcli/cldap/cldap.h"
2006-03-07 11:07:23 +00:00
# include "libcli/resolve/resolve.h"
2014-02-27 09:08:17 +01:00
# include "libcli/ldap/ldap_client.h"
2006-03-25 16:23:42 +00:00
# include "torture/torture.h"
2014-02-27 09:08:17 +01:00
# include "torture/ldap/proto.h"
2007-12-03 18:47:35 +01:00
# include "param/param.h"
2009-06-15 17:55:43 +02:00
# include "../lib/tsocket/tsocket.h"
# define CHECK_VAL(v, correct) torture_assert_int_equal(tctx, (v), (correct), "incorrect value");
2005-05-18 04:17:24 +00:00
struct bench_state {
2009-02-13 13:13:54 +01:00
struct torture_context * tctx ;
2005-05-18 04:17:24 +00:00
int pass_count , fail_count ;
} ;
2009-02-13 13:13:54 +01:00
static void request_netlogon_handler ( struct tevent_req * req )
2005-05-18 04:17:24 +00:00
{
struct cldap_netlogon io ;
2009-02-13 13:13:54 +01:00
struct bench_state * state = tevent_req_callback_data ( req , struct bench_state ) ;
2005-05-18 04:17:24 +00:00
NTSTATUS status ;
TALLOC_CTX * tmp_ctx = talloc_new ( NULL ) ;
io . in . version = 6 ;
2010-05-09 17:20:01 +02:00
status = cldap_netlogon_recv ( req , tmp_ctx , & io ) ;
2009-02-13 13:13:54 +01:00
talloc_free ( req ) ;
2005-05-18 04:17:24 +00:00
if ( NT_STATUS_IS_OK ( status ) ) {
state - > pass_count + + ;
} else {
state - > fail_count + + ;
}
talloc_free ( tmp_ctx ) ;
}
/*
2009-02-23 16:10:42 +01:00
benchmark cldap netlogon calls
2005-05-18 04:17:24 +00:00
*/
2009-02-23 16:10:42 +01:00
static bool bench_cldap_netlogon ( struct torture_context * tctx , const char * address )
2005-05-18 04:17:24 +00:00
{
2008-04-21 17:58:23 -04:00
struct cldap_socket * cldap ;
2005-05-18 04:17:24 +00:00
int num_sent = 0 ;
struct timeval tv = timeval_current ( ) ;
2007-08-28 00:16:58 +00:00
int timelimit = torture_setting_int ( tctx , " timelimit " , 10 ) ;
2005-05-18 04:17:24 +00:00
struct cldap_netlogon search ;
struct bench_state * state ;
2009-02-13 13:13:54 +01:00
NTSTATUS status ;
2009-06-15 17:55:43 +02:00
struct tsocket_address * dest_addr ;
int ret ;
2005-05-18 04:17:24 +00:00
2009-06-15 17:55:43 +02:00
ret = tsocket_address_inet_from_strings ( tctx , " ip " ,
address ,
2010-07-16 14:32:42 +10:00
lpcfg_cldap_port ( tctx - > lp_ctx ) ,
2009-06-15 17:55:43 +02:00
& dest_addr ) ;
CHECK_VAL ( ret , 0 ) ;
2011-10-10 15:58:24 +02:00
status = cldap_socket_init ( tctx , NULL , dest_addr , & cldap ) ;
2009-02-13 13:13:54 +01:00
torture_assert_ntstatus_ok ( tctx , status , " cldap_socket_init " ) ;
2008-04-21 17:58:23 -04:00
2007-08-28 00:16:58 +00:00
state = talloc_zero ( tctx , struct bench_state ) ;
2009-02-13 13:13:54 +01:00
state - > tctx = tctx ;
2005-05-18 04:17:24 +00:00
ZERO_STRUCT ( search ) ;
2010-02-25 12:47:38 +01:00
search . in . dest_address = NULL ;
search . in . dest_port = 0 ;
2005-05-18 04:17:24 +00:00
search . in . acct_control = - 1 ;
search . in . version = 6 ;
2009-02-23 16:10:42 +01:00
printf ( " Running CLDAP/netlogon for %d seconds \n " , timelimit ) ;
2005-05-18 04:17:24 +00:00
while ( timeval_elapsed ( & tv ) < timelimit ) {
while ( num_sent - ( state - > pass_count + state - > fail_count ) < 10 ) {
2009-02-13 13:13:54 +01:00
struct tevent_req * req ;
2011-10-10 15:42:57 +02:00
req = cldap_netlogon_send ( state , tctx - > ev ,
cldap , & search ) ;
2009-02-13 13:13:54 +01:00
tevent_req_set_callback ( req , request_netlogon_handler , state ) ;
2005-05-18 04:17:24 +00:00
num_sent + + ;
if ( num_sent % 50 = = 0 ) {
2007-08-28 00:16:58 +00:00
if ( torture_setting_bool ( tctx , " progress " , true ) ) {
2007-04-29 21:37:29 +00:00
printf ( " %.1f queries per second (%d failures) \r " ,
state - > pass_count / timeval_elapsed ( & tv ) ,
state - > fail_count ) ;
fflush ( stdout ) ;
}
2005-05-18 04:17:24 +00:00
}
}
2009-02-13 13:13:54 +01:00
tevent_loop_once ( tctx - > ev ) ;
2005-05-18 04:17:24 +00:00
}
while ( num_sent ! = ( state - > pass_count + state - > fail_count ) ) {
2009-02-13 13:13:54 +01:00
tevent_loop_once ( tctx - > ev ) ;
2005-05-18 04:17:24 +00:00
}
printf ( " %.1f queries per second (%d failures) \n " ,
state - > pass_count / timeval_elapsed ( & tv ) ,
state - > fail_count ) ;
talloc_free ( cldap ) ;
2009-06-15 17:55:43 +02:00
return true ;
2005-05-18 04:17:24 +00:00
}
2009-02-13 13:13:54 +01:00
static void request_rootdse_handler ( struct tevent_req * req )
2009-02-23 16:10:42 +01:00
{
struct cldap_search io ;
2009-02-13 13:13:54 +01:00
struct bench_state * state = tevent_req_callback_data ( req , struct bench_state ) ;
2009-02-23 16:10:42 +01:00
NTSTATUS status ;
TALLOC_CTX * tmp_ctx = talloc_new ( NULL ) ;
status = cldap_search_recv ( req , tmp_ctx , & io ) ;
2009-02-13 13:13:54 +01:00
talloc_free ( req ) ;
2009-02-23 16:10:42 +01:00
if ( NT_STATUS_IS_OK ( status ) ) {
state - > pass_count + + ;
} else {
state - > fail_count + + ;
}
talloc_free ( tmp_ctx ) ;
}
/*
benchmark cldap netlogon calls
*/
static bool bench_cldap_rootdse ( struct torture_context * tctx , const char * address )
{
struct cldap_socket * cldap ;
int num_sent = 0 ;
struct timeval tv = timeval_current ( ) ;
int timelimit = torture_setting_int ( tctx , " timelimit " , 10 ) ;
struct cldap_search search ;
struct bench_state * state ;
2009-02-13 13:13:54 +01:00
NTSTATUS status ;
2010-02-25 12:47:38 +01:00
struct tsocket_address * dest_addr ;
int ret ;
ret = tsocket_address_inet_from_strings ( tctx , " ip " ,
address ,
2010-07-16 14:32:42 +10:00
lpcfg_cldap_port ( tctx - > lp_ctx ) ,
2010-02-25 12:47:38 +01:00
& dest_addr ) ;
CHECK_VAL ( ret , 0 ) ;
2009-02-23 16:10:42 +01:00
2009-06-15 17:55:43 +02:00
/* cldap_socket_init should now know about the dest. address */
2011-10-10 15:58:24 +02:00
status = cldap_socket_init ( tctx , NULL , dest_addr , & cldap ) ;
2009-02-13 13:13:54 +01:00
torture_assert_ntstatus_ok ( tctx , status , " cldap_socket_init " ) ;
2009-02-23 16:10:42 +01:00
state = talloc_zero ( tctx , struct bench_state ) ;
ZERO_STRUCT ( search ) ;
2010-02-25 12:47:38 +01:00
search . in . dest_address = NULL ;
search . in . dest_port = 0 ;
2009-02-23 16:10:42 +01:00
search . in . filter = " (objectClass=*) " ;
search . in . timeout = 2 ;
search . in . retries = 1 ;
printf ( " Running CLDAP/rootdse for %d seconds \n " , timelimit ) ;
while ( timeval_elapsed ( & tv ) < timelimit ) {
while ( num_sent - ( state - > pass_count + state - > fail_count ) < 10 ) {
2009-02-13 13:13:54 +01:00
struct tevent_req * req ;
2011-10-10 15:46:17 +02:00
req = cldap_search_send ( state , tctx - > ev , cldap , & search ) ;
2009-02-13 13:13:54 +01:00
tevent_req_set_callback ( req , request_rootdse_handler , state ) ;
2009-02-23 16:10:42 +01:00
num_sent + + ;
if ( num_sent % 50 = = 0 ) {
if ( torture_setting_bool ( tctx , " progress " , true ) ) {
printf ( " %.1f queries per second (%d failures) \r " ,
state - > pass_count / timeval_elapsed ( & tv ) ,
state - > fail_count ) ;
fflush ( stdout ) ;
}
}
}
tevent_loop_once ( tctx - > ev ) ;
}
while ( num_sent ! = ( state - > pass_count + state - > fail_count ) ) {
tevent_loop_once ( tctx - > ev ) ;
}
printf ( " %.1f queries per second (%d failures) \n " ,
state - > pass_count / timeval_elapsed ( & tv ) ,
state - > fail_count ) ;
talloc_free ( cldap ) ;
2009-06-15 17:55:43 +02:00
return true ;
2009-02-23 16:10:42 +01:00
}
2005-05-18 04:17:24 +00:00
/*
benchmark how fast a CLDAP server can respond to a series of parallel
requests
*/
2007-08-28 00:16:58 +00:00
bool torture_bench_cldap ( struct torture_context * torture )
2005-05-18 04:17:24 +00:00
{
const char * address ;
struct nbt_name name ;
NTSTATUS status ;
2007-08-28 00:16:58 +00:00
bool ret = true ;
2005-05-18 04:17:24 +00:00
2006-10-18 14:23:19 +00:00
make_nbt_name_server ( & name , torture_setting_string ( torture , " host " , NULL ) ) ;
2005-05-18 04:17:24 +00:00
/* do an initial name resolution to find its IP */
2011-05-02 16:36:48 +10:00
status = resolve_name_ex ( lpcfg_resolve_context ( torture - > lp_ctx ) ,
0 , 0 , & name , torture , & address , torture - > ev ) ;
2005-05-18 04:17:24 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to resolve %s - %s \n " ,
name . name , nt_errstr ( status ) ) ;
2007-08-28 00:16:58 +00:00
return false ;
2005-05-18 04:17:24 +00:00
}
2009-02-23 16:10:42 +01:00
ret & = bench_cldap_netlogon ( torture , address ) ;
ret & = bench_cldap_rootdse ( torture , address ) ;
2005-05-18 04:17:24 +00:00
return ret ;
}