mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-25 22:50:25 -05:00
Use commit 0e1e780fd6f18ce93119061e36a4fca9711bc020 Excluded multibuild folder, as this caused git issues
376 lines
11 KiB
C++
376 lines
11 KiB
C++
/*
|
|
Copyright (C) 2012 Equinor ASA, Norway.
|
|
|
|
The file 'test_util.c' is part of ERT - Ensemble based Reservoir Tool.
|
|
|
|
ERT 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 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
ERT 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 at <http://www.gnu.org/licenses/gpl.html>
|
|
for more details.
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
|
|
#include "ert/util/build_config.hpp"
|
|
#include <ert/util/util.h>
|
|
#include <ert/util/test_util.hpp>
|
|
#include <ert/util/stringlist.hpp>
|
|
#include <ert/util/util.h>
|
|
|
|
void test_error_exit( const char * fmt , ...) {
|
|
char * s;
|
|
va_list ap;
|
|
va_start(ap , fmt);
|
|
s = util_alloc_sprintf_va(fmt , ap);
|
|
va_end(ap);
|
|
fprintf(stderr, "%s", s);
|
|
free(s);
|
|
exit(1);
|
|
}
|
|
|
|
|
|
void test_exit__(const char * file , int line , const char * fmt , ...) {
|
|
fprintf(stderr , "Error at %s:%d:\n",file,line);
|
|
{
|
|
char * s;
|
|
va_list ap;
|
|
va_start(ap , fmt);
|
|
s = util_alloc_sprintf_va(fmt , ap);
|
|
va_end(ap);
|
|
fprintf(stderr, "%s", s);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
bool test_check_string_equal( const char * s1 , const char * s2 ) {
|
|
bool equal = true;
|
|
if (s1 == NULL && s2 == NULL)
|
|
return true;
|
|
else {
|
|
if (s1 == NULL)
|
|
equal = false;
|
|
if (s2 == NULL)
|
|
equal = false;
|
|
|
|
if (equal && (strcmp(s1,s2) != 0))
|
|
equal = false;
|
|
}
|
|
return equal;
|
|
}
|
|
|
|
|
|
|
|
void test_assert_string_equal__( const char * s1 , const char * s2 , const char * file, int line) {
|
|
bool equal = test_check_string_equal( s1 , s2 );
|
|
if (!equal)
|
|
test_error_exit( "%s:%d => String are different s1:[%s] s2:[%s]\n" , file , line , s1 , s2 );
|
|
}
|
|
|
|
|
|
void test_assert_string_not_equal__( const char * s1 , const char * s2 , const char * file, int line) {
|
|
bool equal = test_check_string_equal( s1 , s2 );
|
|
if (equal)
|
|
test_error_exit( "%s:%d => String are equal s1:[%s] s2:[%s]\n" , file , line , s1 , s2 );
|
|
}
|
|
|
|
|
|
void test_assert_long_equal__( long i1 , long i2 , const char * file , long line) {
|
|
if (i1 != i2)
|
|
test_error_exit( "%s:%d => Long values are different i1:[%d] i2:[%d]\n" , file , line , i1 , i2 );
|
|
}
|
|
|
|
|
|
void test_assert_long_not_equal__( long i1 , long i2 , const char * file , long line) {
|
|
if (i1 == i2)
|
|
test_error_exit( "%s:%d => Long values are equal i1:[%d] i2:[%d]\n" , file , line , i1 , i2 );
|
|
}
|
|
|
|
|
|
void test_assert_int_equal__( int i1 , int i2 , const char * file , int line) {
|
|
if (i1 != i2)
|
|
test_error_exit( "%s:%d => Integers are different i1:[%d] i2:[%d]\n" , file , line , i1 , i2 );
|
|
}
|
|
|
|
|
|
void test_assert_int_not_equal__( int i1 , int i2 , const char * file , int line) {
|
|
if (i1 == i2)
|
|
test_error_exit( "%s:%d => Integers are equal i1:[%d] i2:[%d]\n" , file , line , i1 , i2 );
|
|
}
|
|
|
|
|
|
void test_assert_uint_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line) {
|
|
if (i1 != i2)
|
|
test_error_exit( "%s:%d => Unsigned integers are different i1:[%d] i2:[%d]\n" , file , line , i1 , i2 );
|
|
}
|
|
|
|
|
|
void test_assert_uint_not_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line) {
|
|
if (i1 == i2)
|
|
test_error_exit( "%s:%d => Unsigned integers are equal i1:[%d] i2:[%d]\n" , file , line , i1 , i2 );
|
|
}
|
|
|
|
|
|
void test_assert_bool_equal__( bool b1 , bool b2 , const char * file , int line) {
|
|
if (b1 != b2)
|
|
test_error_exit( "%s:%d => Booleans are different b1:[%d] b2:[%d]\n" , file , line , b1 , b2 );
|
|
}
|
|
|
|
|
|
void test_assert_bool_not_equal__( bool b1 , bool b2 , const char * file , int line) {
|
|
if (b1 == b2)
|
|
test_error_exit( "%s:%d => Booleans are equal b1:[%d] b2:[%d]\n" , file , line , b1 , b2 );
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
void test_assert_size_t_equal__( size_t s1 , size_t s2 , const char * file , int line) {
|
|
if (s1 != s2)
|
|
test_error_exit("%s:%d => size_t values are different s1:%zu s2:[%zu]\n" , file , line , s1 , s2);
|
|
}
|
|
|
|
|
|
void test_assert_size_t_not_equal__( size_t s1 , size_t s2 , const char * file , int line) {
|
|
if (s1 == s2)
|
|
test_error_exit("%s:%d => size_t values are different s1:%zu s2:[%zu]\n" , file , line , s1 , s2);
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
void test_assert_time_t_equal__( time_t t1 , time_t t2 , const char * file , int line) {
|
|
if (t1 != t2)
|
|
test_error_exit("%s:%d => time_t values are different t1:%d t2:[%d]\n" , file , line , t1 , t2);
|
|
}
|
|
|
|
|
|
void test_assert_time_t_not_equal__( time_t t1 , time_t t2 , const char * file , int line) {
|
|
if (t1 == t2)
|
|
test_error_exit("%s:%d => time_t values are different t1:%d t2:[%d]\n" , file , line , t1 , t2);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
void test_assert_true__( bool value, const char * file , int line) {
|
|
if (!value)
|
|
test_error_exit("%s:%d => assert( true ) failed\n" , file , line);
|
|
}
|
|
|
|
|
|
void test_assert_false__( bool value, const char * file , int line) {
|
|
if (value)
|
|
test_error_exit("%s:%d => assert( false ) failed" , file , line);
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
void test_assert_ptr_equal__( const void * p1 , const void * p2 , const char * file , int line) {
|
|
bool equal = (p1 == p2);
|
|
if (!equal)
|
|
test_error_exit( "%s:%d => Pointers are different p1:[%p] p2:[%p]\n" , file , line , p1 , p2 );
|
|
}
|
|
|
|
|
|
void test_assert_ptr_not_equal__( const void * p1 , const void * p2 , const char * file , int line) {
|
|
bool equal = (p1 == p2);
|
|
if (equal)
|
|
test_error_exit( "%s:%d => Pointers are equal p1:[%p] p2:[%p]\n" , file , line , p1 , p2 );
|
|
}
|
|
|
|
|
|
void test_assert_NULL__( const void * p , const char * file , int line) {
|
|
if (p != NULL)
|
|
test_error_exit( "%s:%d => Pointer is != NULL \n" , file , line , p);
|
|
}
|
|
|
|
|
|
void test_assert_not_NULL__( const void * p , const char * file , int line) {
|
|
if (p == NULL)
|
|
test_error_exit( "%s:%d => Pointer is NULL \n" , file , line , p);
|
|
}
|
|
|
|
|
|
void test_assert_mem_equal__( const void * p1 , const void * p2 , size_t byte_size , const char * file , int line) {
|
|
if (memcmp(p1 ,p2 , byte_size) != 0) {
|
|
const char * char_ptr1 = (const char *) p1;
|
|
const char * char_ptr2 = (const char *) p2;
|
|
size_t offset = 0;
|
|
|
|
while( char_ptr1[offset] == char_ptr2[offset])
|
|
offset++;
|
|
|
|
test_error_exit( "%s:%d => Memory regions have different content. First difference at offset:%ld\n" , file , line , offset);
|
|
}
|
|
}
|
|
|
|
|
|
void test_assert_mem_not_equal__( const void * p1 , const void * p2 , size_t byte_size , const char * file , int line) {
|
|
if (memcmp(p1 ,p2 , byte_size) == 0)
|
|
test_error_exit( "%s:%d => Memory regions have the same content \n" , file , line);
|
|
}
|
|
|
|
|
|
bool test_check_double_equal( double d1 , double d2) {
|
|
const double tolerance = 1e-5;
|
|
return util_double_approx_equal__( d1 , d2 , tolerance , 0);
|
|
}
|
|
|
|
|
|
void test_assert_double_equal__( double d1 , double d2, const char * file , int line) {
|
|
if (!test_check_double_equal(d1 , d2))
|
|
test_error_exit( "%s:%d => double values:%g %g are not sufficiently similar\n" , file , line , d1 , d2);
|
|
}
|
|
|
|
|
|
void test_assert_double_not_equal__( double d1 , double d2, const char * file , int line) {
|
|
if (test_check_double_equal(d1 , d2))
|
|
test_error_exit( "%s:%d => double values:%15.12g %15.12g are equal.\n" , file , line , d1 , d2);
|
|
}
|
|
|
|
bool test_check_float_equal( float d1 , float d2) {
|
|
const float tolerance = 1e-4;
|
|
return util_float_approx_equal__( d1 , d2 , tolerance , 0);
|
|
}
|
|
|
|
|
|
void test_assert_float_equal__( float d1 , float d2, const char * file , int line) {
|
|
if (!test_check_float_equal(d1 , d2))
|
|
test_error_exit( "%s:%d => float values:%g %g are not sufficiently similar\n" , file , line , d1 , d2);
|
|
}
|
|
|
|
|
|
void test_assert_float_not_equal__( float d1 , float d2, const char * file , int line) {
|
|
if (test_check_float_equal(d1 , d2))
|
|
test_error_exit( "%s:%d => float values:%15.12g %15.12g are equal.\n" , file , line , d1 , d2);
|
|
}
|
|
|
|
|
|
void test_assert_file_content__( const char * input_file , const char * expected, const char * src_file , int line) {
|
|
if (util_file_exists( input_file )) {
|
|
char * content = util_fread_alloc_file_content(input_file, NULL);
|
|
if (!util_string_equal( content , expected))
|
|
test_error_exit("%s:%d content difference \n",src_file , line);
|
|
free( content );
|
|
} else
|
|
test_error_exit("%s:%d => No such file:%s \n", src_file , line , input_file);
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
void test_install_SIGNALS(void) {
|
|
signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */
|
|
signal(SIGINT , util_abort_signal); /* Control C */
|
|
signal(SIGTERM , util_abort_signal); /* If killing the program with SIGTERM (the default kill signal) you will get a backtrace.
|
|
Killing with SIGKILL (-9) will not give a backtrace.*/
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
#ifdef HAVE_BACKTRACE
|
|
#include <execinfo.h>
|
|
|
|
|
|
void test_util_addr2line() {
|
|
const char * file = __FILE__;
|
|
const char * func = __func__;
|
|
int line;
|
|
const int max_bt = 50;
|
|
void *bt_addr[max_bt];
|
|
int size;
|
|
char * func_name , * file_name;
|
|
int line_nr;
|
|
|
|
line = __LINE__ + 2;
|
|
size = backtrace(bt_addr , max_bt);
|
|
test_assert_int_equal( size , 4 );
|
|
test_assert_true( util_addr2line_lookup( bt_addr[0] , &func_name , &file_name , &line_nr));
|
|
test_assert_string_equal( func_name , func );
|
|
test_assert_int_equal( line , line_nr );
|
|
test_assert_string_equal( file_name , file );
|
|
}
|
|
|
|
|
|
void test_assert_util_abort(const char * function_name , void call_func (void *) , void * arg) {
|
|
bool util_abort_intercepted = false;
|
|
|
|
{
|
|
jmp_buf * context = util_abort_test_jump_buffer();
|
|
util_abort_test_set_intercept_function( function_name );
|
|
|
|
if (setjmp(*context) == 0)
|
|
call_func( arg );
|
|
else
|
|
util_abort_intercepted = true;
|
|
|
|
util_abort_test_set_intercept_function( NULL );
|
|
|
|
}
|
|
|
|
if (!util_abort_intercepted) {
|
|
fprintf(stderr,"Expected call to util_abort() from:%s missing \n",function_name);
|
|
test_assert_true( util_abort_intercepted );
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
/*
|
|
These are non-functional stubs.
|
|
*/
|
|
|
|
bool util_addr2line_lookup(const void * bt_addr , char ** func_name , char ** file_name , int * line_nr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
jmp_buf * util_abort_test_jump_buffer()
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
void util_abort_test_set_intercept_function(const char * function)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
#ifdef HAVE_PTHREAD
|
|
#include <pthread.h>
|
|
|
|
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
void * thread_pool_test_func1( void * arg ) {
|
|
int * value = (int *) arg;
|
|
pthread_mutex_lock( &mutex );
|
|
value[0]++;
|
|
pthread_mutex_unlock( &mutex );
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
|