make leak test exit with an error code

and run the libvips leak test in CI
This commit is contained in:
John Cupitt 2021-02-08 11:25:56 +00:00
parent 8b791a072e
commit 1f4f975e7d
8 changed files with 67 additions and 27 deletions

View File

@ -81,4 +81,4 @@ jobs:
run: pip3 install pyvips pytest
- name: Run test suite
run: python3 -m pytest
run: VIPS_LEAK=1 python3 -m pytest

View File

@ -16,6 +16,7 @@
- avoid NaN in mapim [afontenot]
- hist_find outputs a double histogram for large images [erdmann]
- fix ref leaks in mosaicing package
- run libvips leak test in CI
22/12/20 start 8.10.6
- don't seek on bad file descriptors [kleisauke]

View File

@ -114,9 +114,9 @@ void vips__threadpool_init( void );
void vips__cache_init( void );
void vips__print_renders( void );
void vips__type_leak( void );
int vips__print_renders( void );
int vips__type_leak( void );
int vips__object_leak( void );
typedef int (*im__fftproc_fn)( VipsImage *, VipsImage *, VipsImage * );
int im__fftproc( VipsImage *dummy,

View File

@ -200,7 +200,7 @@ vips_error_buffer_copy( void )
g_mutex_lock( vips__global_lock );
msg = g_strdup( vips_buf_all( &vips_error_buf ) );
vips_error_clear();
vips_buf_rewind( &vips_error_buf );
g_mutex_unlock( vips__global_lock );
return( msg );

View File

@ -643,13 +643,20 @@ vips_check_init( void )
vips_error_clear();
}
static void
static int
vips_leak( void )
{
char txt[1024];
VipsBuf buf = VIPS_BUF_STATIC( txt );
int n_leaks;
vips_object_print_all();
n_leaks = 0;
n_leaks += vips__object_leak();
n_leaks += vips__type_leak();
n_leaks += vips_tracked_get_allocs();
n_leaks += vips_tracked_get_mem();
n_leaks += vips_tracked_get_files();
if( vips_tracked_get_allocs() ||
vips_tracked_get_mem() ||
@ -664,21 +671,27 @@ vips_leak( void )
vips_buf_append_size( &buf, vips_tracked_get_mem_highwater() );
vips_buf_appends( &buf, "\n" );
if( strlen( vips_error_buffer() ) > 0 )
if( strlen( vips_error_buffer() ) > 0 ) {
vips_buf_appendf( &buf, "error buffer: %s",
vips_error_buffer() );
n_leaks += strlen( vips_error_buffer() );
}
if( vips__n_active_threads > 0 )
if( vips__n_active_threads > 0 ) {
vips_buf_appendf( &buf, "threads: %d not joined\n",
vips__n_active_threads );
n_leaks += vips__n_active_threads;
}
fprintf( stderr, "%s", vips_buf_all( &buf ) );
vips__print_renders();
n_leaks += vips__print_renders();
#ifdef DEBUG
vips_buffer_dump_all();
#endif /*DEBUG*/
return( n_leaks );
}
/**
@ -755,8 +768,9 @@ vips_shutdown( void )
{
static gboolean done = FALSE;
if( !done )
vips_leak();
if( !done &&
vips_leak() )
exit( 1 );
done = TRUE;
}

View File

@ -3167,23 +3167,34 @@ vips_object_print_all_cb( VipsObject *object, int *n, void *b )
return( NULL );
}
void
vips_object_print_all( void )
int
vips__object_leak( void )
{
int n_leaks;
n_leaks = 0;
/* Don't count static objects.
*/
if( vips__object_all &&
g_hash_table_size( vips__object_all ) >
vips_object_n_static() ) {
int n;
fprintf( stderr, "%d objects alive:\n",
g_hash_table_size( vips__object_all ) );
n = 0;
vips_object_map(
(VipsSListMap2Fn) vips_object_print_all_cb, &n, NULL );
(VipsSListMap2Fn) vips_object_print_all_cb,
&n_leaks, NULL );
}
vips__type_leak();
return( n_leaks );
}
void
vips_object_print_all( void )
{
(void) vips__object_leak();
(void) vips__type_leak();
}
static void *

View File

@ -1146,23 +1146,29 @@ vips_sink_screen( VipsImage *in, VipsImage *out, VipsImage *mask,
return( 0 );
}
void
int
vips__print_renders( void )
{
int n_leaks;
n_leaks = 0;
#ifdef VIPS_DEBUG_AMBER
if( render_num_renders > 0 )
if( render_num_renders > 0 ) {
printf( "%d active renders\n", render_num_renders );
n_leaks += render_num_renders;
}
#endif /*VIPS_DEBUG_AMBER*/
if( render_dirty_lock ) {
int n_dirty;
g_mutex_lock( render_dirty_lock );
n_dirty = g_slist_length( render_dirty_all );
if( n_dirty > 0 )
printf( "%d dirty renders\n", n_dirty );
n_leaks += g_slist_length( render_dirty_all );
if( render_dirty_all )
printf( "dirty renders\n" );
g_mutex_unlock( render_dirty_lock );
}
return( n_leaks );
}

View File

@ -285,9 +285,13 @@ vips_area_new( VipsCallbackFn free_fn, void *data )
return( area );
}
void
int
vips__type_leak( void )
{
int n_leaks;
n_leaks = 0;
if( vips_area_all ) {
GSList *p;
@ -298,8 +302,12 @@ vips__type_leak( void )
fprintf( stderr, "\t%p count = %d, bytes = %zd\n",
area, area->count, area->length );
n_leaks += 1;
}
}
return( n_leaks );
}
/**