2004-09-28 05:42:02 +00:00
/*
Unix SMB / CIFS implementation .
local testing of talloc routines .
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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2005-01-01 05:06:22 +00:00
# ifdef _SAMBA_BUILD_
# include "includes.h"
# else
2004-10-03 00:04:30 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <stdarg.h>
# include <sys/time.h>
# include <time.h>
# include "talloc.h"
# endif
/* the test suite can be built standalone, or as part of Samba */
2005-01-01 05:06:22 +00:00
# ifndef _SAMBA_BUILD_
2004-10-03 00:04:30 +00:00
typedef enum { False = 0 , True = 1 } BOOL ;
2005-01-02 07:47:34 +00:00
static struct timeval timeval_current ( void )
2004-10-03 00:04:30 +00:00
{
2004-11-03 10:09:48 +00:00
struct timeval tv ;
2005-01-02 07:47:34 +00:00
gettimeofday ( & tv , NULL ) ;
2004-11-03 10:09:48 +00:00
return tv ;
2004-10-03 00:04:30 +00:00
}
2005-01-02 07:47:34 +00:00
static double timeval_elapsed ( struct timeval * tv )
2004-10-03 00:04:30 +00:00
{
2005-01-02 07:47:34 +00:00
struct timeval tv2 = timeval_current ( ) ;
2004-11-03 10:09:48 +00:00
return ( tv2 . tv_sec - tv - > tv_sec ) +
( tv2 . tv_usec - tv - > tv_usec ) * 1.0e-6 ;
2004-10-03 00:04:30 +00:00
}
2005-01-01 05:06:22 +00:00
# endif /* _SAMBA_BUILD_ */
2004-09-28 05:42:02 +00:00
2004-09-28 23:30:14 +00:00
2004-09-29 06:31:14 +00:00
# define CHECK_SIZE(ptr, tsize) do { \
if ( talloc_total_size ( ptr ) ! = ( tsize ) ) { \
printf ( __location__ " failed: wrong '%s' tree size: got %u expected %u \n " , \
# ptr, \
( unsigned ) talloc_total_size ( ptr ) , \
( unsigned ) tsize ) ; \
talloc_report_full ( ptr , stdout ) ; \
return False ; \
} \
} while ( 0 )
2004-10-03 00:04:30 +00:00
# define CHECK_BLOCKS(ptr, tblocks) do { \
if ( talloc_total_blocks ( ptr ) ! = ( tblocks ) ) { \
printf ( __location__ " failed: wrong '%s' tree blocks: got %u expected %u \n " , \
# ptr, \
( unsigned ) talloc_total_blocks ( ptr ) , \
( unsigned ) tblocks ) ; \
talloc_report_full ( ptr , stdout ) ; \
return False ; \
} \
} while ( 0 )
2004-09-28 05:42:02 +00:00
/*
test references
*/
static BOOL test_ref1 ( void )
{
2004-09-28 23:30:14 +00:00
void * root , * p1 , * p2 , * ref , * r1 ;
2004-09-28 05:42:02 +00:00
printf ( " TESTING SINGLE REFERENCE FREE \n " ) ;
2004-09-28 23:30:14 +00:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
2004-09-28 05:42:02 +00:00
p2 = talloc_named_const ( p1 , 1 , " p2 " ) ;
talloc_named_const ( p1 , 1 , " x1 " ) ;
2004-09-28 23:30:14 +00:00
talloc_named_const ( p1 , 2 , " x2 " ) ;
talloc_named_const ( p1 , 3 , " x3 " ) ;
2004-09-28 05:42:02 +00:00
2004-09-28 23:30:14 +00:00
r1 = talloc_named_const ( root , 1 , " r1 " ) ;
2004-09-28 05:42:02 +00:00
ref = talloc_reference ( r1 , p2 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 5 ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( r1 , 2 ) ;
2004-09-28 05:42:02 +00:00
printf ( " Freeing p2 \n " ) ;
talloc_free ( p2 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 5 ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( r1 , 1 ) ;
2004-09-28 05:42:02 +00:00
printf ( " Freeing p1 \n " ) ;
talloc_free ( p1 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( r1 , 1 ) ;
2004-09-28 05:42:02 +00:00
printf ( " Freeing r1 \n " ) ;
talloc_free ( r1 ) ;
talloc_report_full ( NULL , stdout ) ;
2004-11-05 12:20:27 +00:00
printf ( " Testing NULL \n " ) ;
if ( talloc_reference ( root , NULL ) ) {
return False ;
}
2004-09-28 23:30:14 +00:00
CHECK_BLOCKS ( root , 1 ) ;
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( root , 0 ) ;
2004-09-28 05:42:02 +00:00
2004-09-28 23:30:14 +00:00
talloc_free ( root ) ;
2004-09-28 05:42:02 +00:00
return True ;
}
/*
test references
*/
static BOOL test_ref2 ( void )
{
2004-09-28 23:30:14 +00:00
void * root , * p1 , * p2 , * ref , * r1 ;
2004-09-28 05:42:02 +00:00
printf ( " TESTING DOUBLE REFERENCE FREE \n " ) ;
2004-09-28 23:30:14 +00:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
2004-09-28 05:42:02 +00:00
talloc_named_const ( p1 , 1 , " x1 " ) ;
talloc_named_const ( p1 , 1 , " x2 " ) ;
talloc_named_const ( p1 , 1 , " x3 " ) ;
p2 = talloc_named_const ( p1 , 1 , " p2 " ) ;
2004-09-28 23:30:14 +00:00
r1 = talloc_named_const ( root , 1 , " r1 " ) ;
2004-09-28 05:42:02 +00:00
ref = talloc_reference ( r1 , p2 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 5 ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( r1 , 2 ) ;
2004-09-28 11:54:17 +00:00
2004-09-28 05:42:02 +00:00
printf ( " Freeing ref \n " ) ;
talloc_free ( ref ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 5 ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( r1 , 1 ) ;
2004-09-28 11:54:17 +00:00
2004-09-28 05:42:02 +00:00
printf ( " Freeing p2 \n " ) ;
talloc_free ( p2 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 4 ) ;
CHECK_BLOCKS ( r1 , 1 ) ;
2004-09-28 11:54:17 +00:00
2004-09-28 05:42:02 +00:00
printf ( " Freeing p1 \n " ) ;
talloc_free ( p1 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( r1 , 1 ) ;
2004-09-28 11:54:17 +00:00
2004-09-28 05:42:02 +00:00
printf ( " Freeing r1 \n " ) ;
talloc_free ( r1 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
2004-09-28 05:42:02 +00:00
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( root , 0 ) ;
2004-09-28 11:54:17 +00:00
2004-09-28 23:30:14 +00:00
talloc_free ( root ) ;
2004-09-28 11:54:17 +00:00
return True ;
}
/*
test references
*/
static BOOL test_ref3 ( void )
{
2004-09-28 23:30:14 +00:00
void * root , * p1 , * p2 , * ref , * r1 ;
2004-09-28 11:54:17 +00:00
printf ( " TESTING PARENT REFERENCE FREE \n " ) ;
2004-09-28 23:30:14 +00:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
p2 = talloc_named_const ( root , 1 , " p2 " ) ;
2004-09-28 11:54:17 +00:00
r1 = talloc_named_const ( p1 , 1 , " r1 " ) ;
ref = talloc_reference ( p2 , r1 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
2004-09-28 11:54:17 +00:00
2004-09-28 23:30:14 +00:00
CHECK_BLOCKS ( p1 , 2 ) ;
CHECK_BLOCKS ( p2 , 2 ) ;
CHECK_BLOCKS ( r1 , 1 ) ;
2004-09-28 11:54:17 +00:00
printf ( " Freeing p1 \n " ) ;
talloc_free ( p1 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p2 , 2 ) ;
CHECK_BLOCKS ( r1 , 1 ) ;
2004-09-28 11:54:17 +00:00
printf ( " Freeing p2 \n " ) ;
talloc_free ( p2 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
2004-09-28 11:54:17 +00:00
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( root , 0 ) ;
2004-09-28 11:54:17 +00:00
2004-09-28 23:30:14 +00:00
talloc_free ( root ) ;
2004-09-28 11:54:17 +00:00
return True ;
}
/*
test references
*/
static BOOL test_ref4 ( void )
{
2004-09-28 23:30:14 +00:00
void * root , * p1 , * p2 , * ref , * r1 ;
2004-09-28 11:54:17 +00:00
printf ( " TESTING REFERRER REFERENCE FREE \n " ) ;
2004-09-28 23:30:14 +00:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
2004-09-28 11:54:17 +00:00
talloc_named_const ( p1 , 1 , " x1 " ) ;
talloc_named_const ( p1 , 1 , " x2 " ) ;
talloc_named_const ( p1 , 1 , " x3 " ) ;
p2 = talloc_named_const ( p1 , 1 , " p2 " ) ;
2004-09-28 23:30:14 +00:00
r1 = talloc_named_const ( root , 1 , " r1 " ) ;
2004-09-28 11:54:17 +00:00
ref = talloc_reference ( r1 , p2 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 5 ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( r1 , 2 ) ;
2004-09-28 11:54:17 +00:00
printf ( " Freeing r1 \n " ) ;
talloc_free ( r1 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 5 ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
2004-09-28 11:54:17 +00:00
printf ( " Freeing p2 \n " ) ;
talloc_free ( p2 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 4 ) ;
2004-09-28 11:54:17 +00:00
printf ( " Freeing p1 \n " ) ;
talloc_free ( p1 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
2004-09-28 11:54:17 +00:00
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( root , 0 ) ;
2004-09-28 11:54:17 +00:00
2004-09-28 23:30:14 +00:00
talloc_free ( root ) ;
2004-09-28 11:54:17 +00:00
return True ;
}
/*
test references
*/
2004-10-03 00:04:30 +00:00
static BOOL test_unlink1 ( void )
2004-09-28 11:54:17 +00:00
{
2004-09-28 23:30:14 +00:00
void * root , * p1 , * p2 , * ref , * r1 ;
2004-09-28 11:54:17 +00:00
2004-10-03 00:04:30 +00:00
printf ( " TESTING UNLINK \n " ) ;
2004-09-28 11:54:17 +00:00
2004-09-28 23:30:14 +00:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
2004-09-28 11:54:17 +00:00
talloc_named_const ( p1 , 1 , " x1 " ) ;
talloc_named_const ( p1 , 1 , " x2 " ) ;
talloc_named_const ( p1 , 1 , " x3 " ) ;
p2 = talloc_named_const ( p1 , 1 , " p2 " ) ;
r1 = talloc_named_const ( p1 , 1 , " r1 " ) ;
ref = talloc_reference ( r1 , p2 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 7 ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( r1 , 2 ) ;
2004-09-28 11:54:17 +00:00
printf ( " Unreferencing r1 \n " ) ;
2004-10-03 00:04:30 +00:00
talloc_unlink ( r1 , p2 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p1 , 6 ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( r1 , 1 ) ;
2004-09-28 11:54:17 +00:00
printf ( " Freeing p1 \n " ) ;
talloc_free ( p1 ) ;
2004-09-28 23:30:14 +00:00
talloc_report_full ( root , stdout ) ;
2004-09-28 11:54:17 +00:00
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( root , 0 ) ;
talloc_free ( root ) ;
return True ;
}
static int fail_destructor ( void * ptr )
{
return - 1 ;
}
/*
miscellaneous tests to try to get a higher test coverage percentage
*/
static BOOL test_misc ( void )
{
void * root , * p1 ;
char * p2 ;
double * d ;
printf ( " TESTING MISCELLANEOUS \n " ) ;
2005-01-06 02:32:43 +00:00
root = talloc_new ( NULL ) ;
2004-09-29 06:31:14 +00:00
2005-01-06 03:06:58 +00:00
p1 = talloc_size ( root , 0x7fffffff ) ;
2004-09-29 06:31:14 +00:00
if ( p1 ) {
printf ( " failed: large talloc allowed \n " ) ;
return False ;
}
p1 = talloc_strdup ( root , " foo " ) ;
talloc_increase_ref_count ( p1 ) ;
talloc_increase_ref_count ( p1 ) ;
talloc_increase_ref_count ( p1 ) ;
CHECK_BLOCKS ( p1 , 1 ) ;
CHECK_BLOCKS ( root , 2 ) ;
talloc_free ( p1 ) ;
CHECK_BLOCKS ( p1 , 1 ) ;
CHECK_BLOCKS ( root , 2 ) ;
2004-10-03 00:04:30 +00:00
talloc_unlink ( NULL , p1 ) ;
2004-09-29 06:31:14 +00:00
CHECK_BLOCKS ( p1 , 1 ) ;
CHECK_BLOCKS ( root , 2 ) ;
2004-10-03 00:04:30 +00:00
p2 = talloc_strdup ( p1 , " foo " ) ;
if ( talloc_unlink ( root , p2 ) ! = - 1 ) {
printf ( " failed: talloc_unlink() of non-reference context should return -1 \n " ) ;
return False ;
}
if ( talloc_unlink ( p1 , p2 ) ! = 0 ) {
printf ( " failed: talloc_unlink() of parent should succeed \n " ) ;
2004-09-29 06:31:14 +00:00
return False ;
}
talloc_free ( p1 ) ;
CHECK_BLOCKS ( p1 , 1 ) ;
CHECK_BLOCKS ( root , 2 ) ;
talloc_set_name ( p1 , " my name is %s " , " foo " ) ;
if ( strcmp ( talloc_get_name ( p1 ) , " my name is foo " ) ! = 0 ) {
printf ( " failed: wrong name after talloc_set_name \n " ) ;
return False ;
}
CHECK_BLOCKS ( p1 , 2 ) ;
CHECK_BLOCKS ( root , 3 ) ;
talloc_set_name_const ( p1 , NULL ) ;
if ( strcmp ( talloc_get_name ( p1 ) , " UNNAMED " ) ! = 0 ) {
printf ( " failed: wrong name after talloc_set_name(NULL) \n " ) ;
return False ;
}
CHECK_BLOCKS ( p1 , 2 ) ;
CHECK_BLOCKS ( root , 3 ) ;
if ( talloc_free ( NULL ) ! = - 1 ) {
printf ( " talloc_free(NULL) should give -1 \n " ) ;
return False ;
}
talloc_set_destructor ( p1 , fail_destructor ) ;
if ( talloc_free ( p1 ) ! = - 1 ) {
printf ( " Failed destructor should cause talloc_free to fail \n " ) ;
return False ;
}
talloc_set_destructor ( p1 , NULL ) ;
talloc_report ( root , stdout ) ;
2005-01-07 04:39:16 +00:00
p2 = talloc_zero_size ( p1 , 20 ) ;
2004-09-29 06:31:14 +00:00
if ( p2 [ 19 ] ! = 0 ) {
printf ( " Failed to give zero memory \n " ) ;
return False ;
}
talloc_free ( p2 ) ;
if ( talloc_strdup ( root , NULL ) ! = NULL ) {
printf ( " failed: strdup on NULL should give NULL \n " ) ;
return False ;
}
p2 = talloc_strndup ( p1 , " foo " , 2 ) ;
if ( strcmp ( " fo " , p2 ) ! = 0 ) {
printf ( " failed: strndup doesn't work \n " ) ;
return False ;
}
p2 = talloc_asprintf_append ( p2 , " o%c " , ' d ' ) ;
if ( strcmp ( " food " , p2 ) ! = 0 ) {
printf ( " failed: talloc_asprintf_append doesn't work \n " ) ;
return False ;
}
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( p1 , 3 ) ;
p2 = talloc_asprintf_append ( NULL , " hello %s " , " world " ) ;
if ( strcmp ( " hello world " , p2 ) ! = 0 ) {
printf ( " failed: talloc_asprintf_append doesn't work \n " ) ;
return False ;
}
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( p1 , 3 ) ;
talloc_free ( p2 ) ;
2005-01-07 04:47:58 +00:00
d = talloc_array ( p1 , double , 0x20000000 ) ;
2004-09-29 06:31:14 +00:00
if ( d ) {
printf ( " failed: integer overflow not detected \n " ) ;
return False ;
}
2005-01-07 04:47:58 +00:00
d = talloc_realloc ( p1 , d , double , 0x20000000 ) ;
2004-09-29 06:31:14 +00:00
if ( d ) {
printf ( " failed: integer overflow not detected \n " ) ;
return False ;
}
talloc_free ( p1 ) ;
CHECK_BLOCKS ( root , 1 ) ;
2004-10-03 00:04:30 +00:00
p1 = talloc_named ( root , 100 , " %d bytes " , 100 ) ;
CHECK_BLOCKS ( p1 , 2 ) ;
CHECK_BLOCKS ( root , 3 ) ;
talloc_unlink ( root , p1 ) ;
p1 = talloc_init ( " %d bytes " , 200 ) ;
p2 = talloc_asprintf ( p1 , " my test '%s' " , " string " ) ;
CHECK_BLOCKS ( p1 , 3 ) ;
CHECK_SIZE ( p2 , 17 ) ;
CHECK_BLOCKS ( root , 1 ) ;
talloc_unlink ( NULL , p1 ) ;
p1 = talloc_named_const ( root , 10 , " p1 " ) ;
p2 = talloc_named_const ( root , 20 , " p2 " ) ;
talloc_reference ( p1 , p2 ) ;
talloc_report_full ( root , stdout ) ;
talloc_unlink ( root , p2 ) ;
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( p1 , 2 ) ;
CHECK_BLOCKS ( root , 3 ) ;
talloc_unlink ( p1 , p2 ) ;
talloc_unlink ( root , p1 ) ;
p1 = talloc_named_const ( root , 10 , " p1 " ) ;
p2 = talloc_named_const ( root , 20 , " p2 " ) ;
talloc_reference ( NULL , p2 ) ;
talloc_report_full ( root , stdout ) ;
talloc_unlink ( root , p2 ) ;
talloc_report_full ( root , stdout ) ;
CHECK_BLOCKS ( p2 , 1 ) ;
CHECK_BLOCKS ( p1 , 1 ) ;
CHECK_BLOCKS ( root , 2 ) ;
talloc_unlink ( NULL , p2 ) ;
talloc_unlink ( root , p1 ) ;
2004-11-05 12:20:27 +00:00
/* Test that talloc_unlink is a no-op */
if ( talloc_unlink ( root , NULL ) ! = - 1 ) {
printf ( " failed: talloc_unlink(root, NULL) == -1 \n " ) ;
return False ;
}
2004-10-03 00:04:30 +00:00
2004-09-29 06:31:14 +00:00
talloc_report ( root , stdout ) ;
talloc_report ( NULL , stdout ) ;
CHECK_SIZE ( root , 0 ) ;
talloc_free ( root ) ;
CHECK_SIZE ( NULL , 0 ) ;
talloc_enable_leak_report ( ) ;
talloc_enable_leak_report_full ( ) ;
return True ;
}
/*
test realloc
*/
static BOOL test_realloc ( void )
{
void * root , * p1 , * p2 ;
printf ( " TESTING REALLOC \n " ) ;
2005-01-06 02:32:43 +00:00
root = talloc_new ( NULL ) ;
2004-09-29 06:31:14 +00:00
2005-01-06 03:06:58 +00:00
p1 = talloc_size ( root , 10 ) ;
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( p1 , 10 ) ;
2005-01-07 04:39:16 +00:00
p1 = talloc_realloc_size ( NULL , p1 , 20 ) ;
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( p1 , 20 ) ;
2005-01-06 03:20:56 +00:00
talloc_new ( p1 ) ;
2004-09-29 06:31:14 +00:00
2005-01-07 04:39:16 +00:00
p2 = talloc_realloc_size ( p1 , NULL , 30 ) ;
2004-09-29 06:31:14 +00:00
2005-01-06 03:20:56 +00:00
talloc_new ( p1 ) ;
2004-09-29 06:31:14 +00:00
2005-01-07 04:39:16 +00:00
p2 = talloc_realloc_size ( p1 , p2 , 40 ) ;
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( p2 , 40 ) ;
CHECK_SIZE ( root , 60 ) ;
CHECK_BLOCKS ( p1 , 4 ) ;
2005-01-07 04:39:16 +00:00
p1 = talloc_realloc_size ( NULL , p1 , 20 ) ;
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( p1 , 60 ) ;
talloc_increase_ref_count ( p2 ) ;
2005-01-07 04:39:16 +00:00
if ( talloc_realloc_size ( NULL , p2 , 5 ) ! = NULL ) {
2004-09-29 06:31:14 +00:00
printf ( " failed: talloc_realloc() on a referenced pointer should fail \n " ) ;
2004-09-28 05:42:02 +00:00
return False ;
}
2004-09-29 06:31:14 +00:00
CHECK_BLOCKS ( p1 , 4 ) ;
2005-01-07 04:39:16 +00:00
talloc_realloc_size ( NULL , p2 , 0 ) ;
talloc_realloc_size ( NULL , p2 , 0 ) ;
2004-09-29 06:31:14 +00:00
CHECK_BLOCKS ( p1 , 3 ) ;
2005-01-07 04:39:16 +00:00
if ( talloc_realloc_size ( NULL , p1 , 0x7fffffff ) ! = NULL ) {
2004-09-29 06:31:14 +00:00
printf ( " failed: oversize talloc should fail \n " ) ;
return False ;
}
2005-01-07 04:39:16 +00:00
talloc_realloc_size ( NULL , p1 , 0 ) ;
2004-09-29 06:31:14 +00:00
CHECK_BLOCKS ( root , 1 ) ;
CHECK_SIZE ( root , 0 ) ;
2004-09-28 05:42:02 +00:00
2004-09-28 23:30:14 +00:00
talloc_free ( root ) ;
2004-09-28 05:42:02 +00:00
return True ;
}
2005-01-02 07:47:34 +00:00
/*
test realloc with a child
*/
static BOOL test_realloc_child ( void )
{
void * root ;
struct el1 {
int count ;
struct el2 {
const char * name ;
2005-01-12 11:45:43 +00:00
} * * list , * * list2 , * * list3 ;
2005-01-02 07:47:34 +00:00
} * el1 ;
struct el2 * el2 ;
printf ( " TESTING REALLOC WITH CHILD \n " ) ;
2005-01-06 03:06:58 +00:00
root = talloc_new ( NULL ) ;
2005-01-02 07:47:34 +00:00
2005-01-07 04:47:58 +00:00
el1 = talloc ( root , struct el1 ) ;
el1 - > list = talloc ( el1 , struct el2 * ) ;
el1 - > list [ 0 ] = talloc ( el1 - > list , struct el2 ) ;
2005-01-02 07:47:34 +00:00
el1 - > list [ 0 ] - > name = talloc_strdup ( el1 - > list [ 0 ] , " testing " ) ;
2005-01-12 11:45:43 +00:00
el1 - > list2 = talloc ( el1 , struct el2 * ) ;
el1 - > list2 [ 0 ] = talloc ( el1 - > list2 , struct el2 ) ;
el1 - > list2 [ 0 ] - > name = talloc_strdup ( el1 - > list2 [ 0 ] , " testing2 " ) ;
el1 - > list3 = talloc ( el1 , struct el2 * ) ;
el1 - > list3 [ 0 ] = talloc ( el1 - > list3 , struct el2 ) ;
el1 - > list3 [ 0 ] - > name = talloc_strdup ( el1 - > list3 [ 0 ] , " testing2 " ) ;
2005-01-02 07:47:34 +00:00
2005-01-07 04:47:58 +00:00
el2 = talloc ( el1 - > list , struct el2 ) ;
2005-01-12 11:45:43 +00:00
el2 = talloc ( el1 - > list2 , struct el2 ) ;
el2 = talloc ( el1 - > list3 , struct el2 ) ;
2005-01-02 07:47:34 +00:00
2005-01-12 11:45:43 +00:00
el1 - > list = talloc_realloc ( el1 , el1 - > list , struct el2 * , 100 ) ;
el1 - > list2 = talloc_realloc ( el1 , el1 - > list2 , struct el2 * , 200 ) ;
el1 - > list3 = talloc_realloc ( el1 , el1 - > list3 , struct el2 * , 300 ) ;
2005-01-02 07:47:34 +00:00
talloc_free ( root ) ;
return True ;
}
2005-01-16 23:21:52 +00:00
/*
test type checking
*/
static BOOL test_type ( void )
{
void * root ;
struct el1 {
int count ;
} ;
struct el2 {
int count ;
} ;
struct el1 * el1 ;
printf ( " TESTING talloc type checking \n " ) ;
root = talloc_new ( NULL ) ;
el1 = talloc ( root , struct el1 ) ;
el1 - > count = 1 ;
if ( talloc_get_type ( el1 , struct el1 ) ! = el1 ) {
printf ( " type check failed on el1 \n " ) ;
return False ;
}
if ( talloc_get_type ( el1 , struct el2 ) ! = NULL ) {
printf ( " type check failed on el1 with el2 \n " ) ;
return False ;
}
talloc_set_type ( el1 , struct el2 ) ;
2005-01-31 16:36:57 +00:00
if ( talloc_get_type ( el1 , struct el2 ) ! = ( struct el2 * ) el1 ) {
2005-01-16 23:21:52 +00:00
printf ( " type set failed on el1 with el2 \n " ) ;
return False ;
}
talloc_free ( root ) ;
return True ;
}
2004-09-29 06:31:14 +00:00
/*
test steal
*/
static BOOL test_steal ( void )
{
void * root , * p1 , * p2 ;
printf ( " TESTING STEAL \n " ) ;
2005-01-06 03:06:58 +00:00
root = talloc_new ( NULL ) ;
2004-09-29 06:31:14 +00:00
2005-01-07 04:47:58 +00:00
p1 = talloc_array ( root , char , 10 ) ;
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( p1 , 10 ) ;
2005-01-07 04:47:58 +00:00
p2 = talloc_realloc ( root , NULL , char , 20 ) ;
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( p1 , 10 ) ;
CHECK_SIZE ( root , 30 ) ;
if ( talloc_steal ( p1 , NULL ) ! = NULL ) {
printf ( " failed: stealing NULL should give NULL \n " ) ;
return False ;
}
if ( talloc_steal ( p1 , p1 ) ! = p1 ) {
printf ( " failed: stealing to ourselves is a nop \n " ) ;
return False ;
}
CHECK_BLOCKS ( root , 3 ) ;
CHECK_SIZE ( root , 30 ) ;
talloc_steal ( NULL , p1 ) ;
talloc_steal ( NULL , p2 ) ;
CHECK_BLOCKS ( root , 1 ) ;
CHECK_SIZE ( root , 0 ) ;
talloc_free ( p1 ) ;
talloc_steal ( root , p2 ) ;
CHECK_BLOCKS ( root , 2 ) ;
CHECK_SIZE ( root , 20 ) ;
talloc_free ( p2 ) ;
CHECK_BLOCKS ( root , 1 ) ;
CHECK_SIZE ( root , 0 ) ;
talloc_free ( root ) ;
2005-01-07 04:45:11 +00:00
p1 = talloc_size ( NULL , 3 ) ;
2004-09-29 06:31:14 +00:00
CHECK_SIZE ( NULL , 3 ) ;
talloc_free ( p1 ) ;
return True ;
}
/*
2005-01-16 23:21:52 +00:00
test talloc_realloc_fn
2004-09-29 06:31:14 +00:00
*/
2005-01-16 23:21:52 +00:00
static BOOL test_realloc_fn ( void )
2004-09-29 06:31:14 +00:00
{
void * root , * p1 ;
2005-01-16 23:21:52 +00:00
printf ( " TESTING talloc_realloc_fn \n " ) ;
2004-09-29 06:31:14 +00:00
2005-01-06 03:06:58 +00:00
root = talloc_new ( NULL ) ;
2004-09-29 06:31:14 +00:00
2004-10-03 07:35:29 +00:00
p1 = talloc_realloc_fn ( root , NULL , 10 ) ;
2004-09-29 06:31:14 +00:00
CHECK_BLOCKS ( root , 2 ) ;
CHECK_SIZE ( root , 10 ) ;
2004-10-03 07:35:29 +00:00
p1 = talloc_realloc_fn ( root , p1 , 20 ) ;
2004-09-29 06:31:14 +00:00
CHECK_BLOCKS ( root , 2 ) ;
CHECK_SIZE ( root , 20 ) ;
2004-10-03 07:35:29 +00:00
p1 = talloc_realloc_fn ( root , p1 , 0 ) ;
2004-09-29 06:31:14 +00:00
CHECK_BLOCKS ( root , 1 ) ;
CHECK_SIZE ( root , 0 ) ;
talloc_free ( root ) ;
return True ;
}
2005-01-02 07:47:34 +00:00
static BOOL test_unref_reparent ( void )
{
void * root , * p1 , * p2 , * c1 ;
printf ( " TESTING UNREFERENCE AFTER PARENT FREED \n " ) ;
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " orig parent " ) ;
p2 = talloc_named_const ( root , 1 , " parent by reference " ) ;
c1 = talloc_named_const ( p1 , 1 , " child " ) ;
talloc_reference ( p2 , c1 ) ;
talloc_free ( p1 ) ;
talloc_unlink ( p2 , c1 ) ;
CHECK_SIZE ( root , 1 ) ;
talloc_free ( p2 ) ;
talloc_free ( root ) ;
return True ;
}
2004-09-28 06:12:07 +00:00
/*
measure the speed of talloc versus malloc
*/
static BOOL test_speed ( void )
{
2005-01-06 03:06:58 +00:00
void * ctx = talloc_new ( NULL ) ;
2004-10-03 00:04:30 +00:00
unsigned count ;
2004-11-03 10:09:48 +00:00
struct timeval tv ;
2004-09-28 06:12:07 +00:00
printf ( " MEASURING TALLOC VS MALLOC SPEED \n " ) ;
2004-11-03 10:09:48 +00:00
tv = timeval_current ( ) ;
2004-09-28 06:12:07 +00:00
count = 0 ;
do {
void * p1 , * p2 , * p3 ;
2005-01-06 03:06:58 +00:00
p1 = talloc_size ( ctx , count ) ;
2004-09-28 06:12:07 +00:00
p2 = talloc_strdup ( p1 , " foo bar " ) ;
2005-01-06 03:06:58 +00:00
p3 = talloc_size ( p1 , 300 ) ;
2004-09-28 06:12:07 +00:00
talloc_free ( p1 ) ;
count + = 3 ;
2004-11-03 10:09:48 +00:00
} while ( timeval_elapsed ( & tv ) < 5.0 ) ;
2004-09-28 06:12:07 +00:00
2004-11-03 10:09:48 +00:00
printf ( " talloc: %.0f ops/sec \n " , count / timeval_elapsed ( & tv ) ) ;
2004-09-28 06:12:07 +00:00
2004-09-28 11:54:17 +00:00
talloc_free ( ctx ) ;
2004-11-03 10:09:48 +00:00
tv = timeval_current ( ) ;
2004-09-28 06:12:07 +00:00
count = 0 ;
do {
void * p1 , * p2 , * p3 ;
p1 = malloc ( count ) ;
p2 = strdup ( " foo bar " ) ;
p3 = malloc ( 300 ) ;
free ( p1 ) ;
free ( p2 ) ;
free ( p3 ) ;
count + = 3 ;
2004-11-03 10:09:48 +00:00
} while ( timeval_elapsed ( & tv ) < 5.0 ) ;
2004-09-28 06:12:07 +00:00
2004-11-03 10:09:48 +00:00
printf ( " malloc: %.0f ops/sec \n " , count / timeval_elapsed ( & tv ) ) ;
2004-09-28 06:12:07 +00:00
return True ;
}
2004-09-28 05:42:02 +00:00
2004-10-28 13:40:50 +00:00
BOOL torture_local_talloc ( void )
2004-09-28 05:42:02 +00:00
{
BOOL ret = True ;
ret & = test_ref1 ( ) ;
ret & = test_ref2 ( ) ;
2004-09-28 11:54:17 +00:00
ret & = test_ref3 ( ) ;
ret & = test_ref4 ( ) ;
2004-10-03 00:04:30 +00:00
ret & = test_unlink1 ( ) ;
2004-09-29 06:31:14 +00:00
ret & = test_misc ( ) ;
ret & = test_realloc ( ) ;
2005-01-02 07:47:34 +00:00
ret & = test_realloc_child ( ) ;
2004-09-29 06:31:14 +00:00
ret & = test_steal ( ) ;
2005-01-02 07:47:34 +00:00
ret & = test_unref_reparent ( ) ;
2005-01-16 23:21:52 +00:00
ret & = test_realloc_fn ( ) ;
ret & = test_type ( ) ;
2004-10-03 00:04:30 +00:00
if ( ret ) {
ret & = test_speed ( ) ;
}
2004-09-28 05:42:02 +00:00
2004-09-28 11:54:17 +00:00
return ret ;
2004-09-28 05:42:02 +00:00
}
2004-10-03 00:04:30 +00:00
2005-01-01 05:06:22 +00:00
# ifndef _SAMBA_BUILD_
2005-01-02 07:47:34 +00:00
int main ( void )
2004-10-03 00:04:30 +00:00
{
2005-01-02 07:47:34 +00:00
if ( ! torture_local_talloc ( ) ) {
2004-10-03 00:04:30 +00:00
printf ( " ERROR: TESTSUIE FAILED \n " ) ;
return - 1 ;
}
return 0 ;
}
# endif