Commit a4067c18 authored by Gautier Pelloux-Prayer's avatar Gautier Pelloux-Prayer
Browse files

tester: add before_each and after_each functions to allow init/cleanup of tests individually

parent d24bc5aa
...@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "CUnit/Basic.h" #include "CUnit/Basic.h"
#include "CUnit/Automated.h" #include "CUnit/Automated.h"
#ifdef _WIN32 #ifdef _WIN32
#if defined(__MINGW32__) || !defined(WINAPI_FAMILY_PARTITION) || !defined(WINAPI_PARTITION_DESKTOP) #if defined(__MINGW32__) || !defined(WINAPI_FAMILY_PARTITION) || !defined(WINAPI_PARTITION_DESKTOP)
#define BC_TESTER_WINDOWS_DESKTOP 1 #define BC_TESTER_WINDOWS_DESKTOP 1
...@@ -43,6 +44,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -43,6 +44,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif #endif
#endif #endif
#ifdef __linux
/*for monitoring total space allocated via malloc*/
#include <malloc.h>
#endif
static char *bc_tester_resource_dir_prefix = NULL; static char *bc_tester_resource_dir_prefix = NULL;
static char *bc_tester_writable_dir_prefix = NULL; static char *bc_tester_writable_dir_prefix = NULL;
...@@ -62,6 +67,8 @@ char* xml_file = "CUnitAutomated-Results.xml"; ...@@ -62,6 +67,8 @@ char* xml_file = "CUnitAutomated-Results.xml";
int xml_enabled = 0; int xml_enabled = 0;
char * suite_name; char * suite_name;
char * test_name; char * test_name;
static long max_vm_kb = 0;
void (*tester_printf_va)(int level, const char *fmt, va_list args); void (*tester_printf_va)(int level, const char *fmt, va_list args);
void bc_tester_printf(int level, const char *fmt, ...) { void bc_tester_printf(int level, const char *fmt, ...) {
...@@ -74,7 +81,7 @@ void bc_tester_printf(int level, const char *fmt, ...) { ...@@ -74,7 +81,7 @@ void bc_tester_printf(int level, const char *fmt, ...) {
int bc_tester_run_suite(test_suite_t *suite) { int bc_tester_run_suite(test_suite_t *suite) {
int i; int i;
CU_pSuite pSuite = CU_add_suite(suite->name, suite->init_func, suite->cleanup_func); CU_pSuite pSuite = CU_add_suite(suite->name, suite->before_all, suite->after_all);
for (i = 0; i < suite->nb_tests; i++) { for (i = 0; i < suite->nb_tests; i++) {
if (NULL == CU_add_test(pSuite, suite->tests[i].name, suite->tests[i].func)) { if (NULL == CU_add_test(pSuite, suite->tests[i].name, suite->tests[i].func)) {
...@@ -94,7 +101,7 @@ int bc_tester_suite_index(const char *suite_name) { ...@@ -94,7 +101,7 @@ int bc_tester_suite_index(const char *suite_name) {
int i; int i;
for (i = 0; i < nb_test_suites; i++) { for (i = 0; i < nb_test_suites; i++) {
if ((strcmp(suite_name, test_suite[i]->name) == 0) && (strlen(suite_name) == strlen(test_suite[i]->name))) { if (strcmp(suite_name, test_suite[i]->name) == 0) {
return i; return i;
} }
} }
...@@ -157,25 +164,35 @@ static void suite_start_message_handler(const CU_pSuite pSuite) { ...@@ -157,25 +164,35 @@ static void suite_start_message_handler(const CU_pSuite pSuite) {
suite_start_time = time(NULL); suite_start_time = time(NULL);
} }
static void suite_complete_message_handler(const CU_pSuite pSuite, const CU_pFailureRecord pFailure) { static void suite_complete_message_handler(const CU_pSuite pSuite, const CU_pFailureRecord pFailure) {
bc_tester_printf(bc_printf_verbosity_info,"Suite [%s] ended in %lu sec\n", pSuite->pName, time(NULL) - suite_start_time); bc_tester_printf(bc_printf_verbosity_info, "Suite [%s] ended in %lu sec\n", pSuite->pName,
time(NULL) - suite_start_time);
} }
static time_t test_start_time = 0; static time_t test_start_time = 0;
static void test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite) { static void test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite) {
int suite_index = bc_tester_suite_index(pSuite->pName);
bc_tester_printf(bc_printf_verbosity_info,"Suite [%s] Test [%s] started", pSuite->pName,pTest->pName); bc_tester_printf(bc_printf_verbosity_info,"Suite [%s] Test [%s] started", pSuite->pName,pTest->pName);
test_start_time = time(NULL); test_start_time = time(NULL);
if (test_suite[suite_index]->before_each) {
test_suite[suite_index]->before_each();
}
} }
/*derivated from cunit*/ /*derivated from cunit*/
static void test_complete_message_handler(const CU_pTest pTest, static void test_complete_message_handler(const CU_pTest pTest, const CU_pSuite pSuite,
const CU_pSuite pSuite, const CU_pFailureRecord pFailureList) {
const CU_pFailureRecord pFailureList) {
int i; int i;
int suite_index = bc_tester_suite_index(pSuite->pName);
char result[2048]={0}; char result[2048]={0};
char buffer[2048]={0}; char buffer[2048]={0};
CU_pFailureRecord pFailure = pFailureList; CU_pFailureRecord pFailure = pFailureList;
snprintf(result, sizeof(result), "Suite [%s] Test [%s] %s in %lu secs"
, pSuite->pName, pTest->pName, pFailure?"failed":"passed",(unsigned long)(time(NULL) - test_start_time)); if (test_suite[suite_index]->after_each) {
test_suite[suite_index]->after_each();
}
snprintf(result, sizeof(result), "Suite [%s] Test [%s] %s in %lu secs", pSuite->pName, pTest->pName,
pFailure ? "failed" : "passed", (unsigned long)(time(NULL) - test_start_time));
if (pFailure) { if (pFailure) {
for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) { for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) {
snprintf(buffer, sizeof(buffer), "\n %d. %s:%u - %s", i, snprintf(buffer, sizeof(buffer), "\n %d. %s:%u - %s", i,
...@@ -186,6 +203,27 @@ static void test_complete_message_handler(const CU_pTest pTest, ...@@ -186,6 +203,27 @@ static void test_complete_message_handler(const CU_pTest pTest,
} }
} }
bc_tester_printf(bc_printf_verbosity_info,"%s\n", result); bc_tester_printf(bc_printf_verbosity_info,"%s\n", result);
#ifdef __linux
/* use mallinfo() to monitor allocated space. It is linux specific but other methods don't work:
* setrlimit() RLIMIT_DATA doesn't count memory allocated via mmap() (which is used internally by malloc)
* setrlimit() RLIMIT_AS works but also counts virtual memory allocated by thread stacks, which is very big and
* hardly controllable.
* setrlimit() RLIMIT_RSS does nothing interesting on linux.
* getrusage() of RSS is unreliable: memory blocks can be leaked without being read or written, which would not
* appear in RSS.
* mallinfo() itself is the less worse solution. Allocated bytes are returned as 'int' so limited to 2GB
*/
if (max_vm_kb) {
struct mallinfo minfo = mallinfo();
if (minfo.uordblks > max_vm_kb * 1024) {
bc_tester_printf(
bc_printf_verbosity_error,
"The program exceeded the maximum amount of memory allocatable (%i bytes), aborting now.\n",
minfo.uordblks);
abort();
}
}
#endif
} }
#endif #endif
...@@ -256,26 +294,32 @@ int bc_tester_run_tests(const char *suite_name, const char *test_name) { ...@@ -256,26 +294,32 @@ int bc_tester_run_tests(const char *suite_name, const char *test_name) {
} }
} }
} }
#ifdef __linux
bc_tester_printf(bc_printf_verbosity_info, "Still %i kilobytes allocated when all tests are finished.",
mallinfo().uordblks / 1024);
#endif
return CU_get_number_of_tests_failed()!=0; return CU_get_number_of_tests_failed()!=0;
} }
void bc_tester_helper(const char *name, const char* additionnal_helper) { void bc_tester_helper(const char *name, const char* additionnal_helper) {
bc_tester_printf(bc_printf_verbosity_info,"%s --help\n" bc_tester_printf(bc_printf_verbosity_info,
"\t\t\t--list-suites\n" "%s --help\n"
"\t\t\t--list-tests <suite>\n" "\t\t\t--list-suites\n"
"\t\t\t--suite <suite name>\n" "\t\t\t--list-tests <suite>\n"
"\t\t\t--test <test name>\n" "\t\t\t--suite <suite name>\n"
"\t\t\t--test <test name>\n"
#ifdef HAVE_CU_CURSES #ifdef HAVE_CU_CURSES
"\t\t\t--curses\n" "\t\t\t--curses\n"
#endif #endif
"\t\t\t--xml\n" "\t\t\t--xml\n"
"\t\t\t--xml-file <xml file name>\n" "\t\t\t--xml-file <xml file name>\n"
"And additionally:\n" "\t\t\t--max-alloc <size in ko> (maximum ammount of memory obtained via malloc allocator)\n"
"%s" "And additionally:\n"
, name "%s",
, additionnal_helper); name, additionnal_helper);
} }
void bc_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list args), int iverbosity_info, int iverbosity_error) { void bc_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list args), int iverbosity_info, int iverbosity_error) {
...@@ -300,9 +344,19 @@ void bc_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list a ...@@ -300,9 +344,19 @@ void bc_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list a
bc_printf_verbosity_info = iverbosity_info; bc_printf_verbosity_info = iverbosity_info;
} }
void bc_tester_set_max_vm(long max_vm_kb) {
#ifdef __linux
max_vm_kb = max_vm_kb;
bc_tester_printf(bc_printf_verbosity_info, "Maximum virtual memory space set to %li kilo bytes", max_vm_kb);
#else
bc_tester_printf(bc_printf_verbosity_error, "Maximum virtual memory space setting is only implemented on Linux.");
#endif
}
int bc_tester_parse_args(int argc, char **argv, int argid) int bc_tester_parse_args(int argc, char **argv, int argid)
{ {
int i = argid; int i = argid;
if (strcmp(argv[i],"--help")==0){ if (strcmp(argv[i],"--help")==0){
return -1; return -1;
} else if (strcmp(argv[i],"--test")==0){ } else if (strcmp(argv[i],"--test")==0){
...@@ -325,7 +379,10 @@ int bc_tester_parse_args(int argc, char **argv, int argid) ...@@ -325,7 +379,10 @@ int bc_tester_parse_args(int argc, char **argv, int argid)
xml_enabled = 1; xml_enabled = 1;
} else if (strcmp(argv[i], "--xml") == 0){ } else if (strcmp(argv[i], "--xml") == 0){
xml_enabled = 1; xml_enabled = 1;
}else { } else if (strcmp(argv[i], "--max-alloc") == 0) {
CHECK_ARG("--max-alloc", ++i, argc);
max_vm_kb = atol(argv[i]);
} else {
bc_tester_printf(bc_printf_verbosity_error, "Unknown option \"%s\"\n", argv[i]); bc_tester_printf(bc_printf_verbosity_error, "Unknown option \"%s\"\n", argv[i]);
return -1; return -1;
} }
...@@ -341,6 +398,10 @@ int bc_tester_parse_args(int argc, char **argv, int argid) ...@@ -341,6 +398,10 @@ int bc_tester_parse_args(int argc, char **argv, int argid)
int bc_tester_start(void) { int bc_tester_start(void) {
int ret; int ret;
if (max_vm_kb)
bc_tester_set_max_vm(max_vm_kb);
if( xml_enabled ){ if( xml_enabled ){
size_t size = strlen(xml_file) + strlen(".tmp") + 1; size_t size = strlen(xml_file) + strlen(".tmp") + 1;
char * xml_tmp_file = malloc(sizeof(char) * size); char * xml_tmp_file = malloc(sizeof(char) * size);
...@@ -399,11 +460,8 @@ void bc_tester_uninit(void) { ...@@ -399,11 +460,8 @@ void bc_tester_uninit(void) {
} }
static void bc_tester_set_dir_prefix(char **prefix, const char *name) { static void bc_tester_set_dir_prefix(char **prefix, const char *name) {
size_t len = strlen(name);
if (*prefix != NULL) free(*prefix); if (*prefix != NULL) free(*prefix);
*prefix = malloc(len + 1); *prefix = strdup(name);
strncpy(*prefix, name, len);
(*prefix)[len] = '\0';
} }
const char * bc_tester_get_resource_dir_prefix(void) { const char * bc_tester_get_resource_dir_prefix(void) {
...@@ -428,7 +486,6 @@ static char * bc_tester_path(const char *prefix, const char *name) { ...@@ -428,7 +486,6 @@ static char * bc_tester_path(const char *prefix, const char *name) {
size_t len = strlen(prefix) + 1 + strlen(name) + 1; size_t len = strlen(prefix) + 1 + strlen(name) + 1;
file = malloc(len); file = malloc(len);
snprintf(file, len, "%s/%s", prefix, name); snprintf(file, len, "%s/%s", prefix, name);
file[strlen(file)] = '\0';
} }
return file; return file;
} }
......
...@@ -35,9 +35,11 @@ extern int bc_printf_verbosity_info; ...@@ -35,9 +35,11 @@ extern int bc_printf_verbosity_info;
extern int bc_printf_verbosity_error; extern int bc_printf_verbosity_error;
typedef void (*test_function_t)(void); typedef void (*test_function_t)(void);
typedef int (*init_function_t)(void); /** Function used in all suites - it is invoked before all and each tests and also after each and all tests
typedef int (*cleanup_function_t)(void); * @return 0 means success, otherwise it's an error
typedef int (*test_suite_function_t)(const char *name); **/
typedef int (*pre_post_function_t)(void);
// typedef int (*test_suite_function_t)(const char *name);
typedef struct { typedef struct {
const char *name; const char *name;
...@@ -45,11 +47,14 @@ typedef struct { ...@@ -45,11 +47,14 @@ typedef struct {
} test_t; } test_t;
typedef struct { typedef struct {
const char *name; const char *name; /*suite name*/
init_function_t init_func; pre_post_function_t
cleanup_function_t cleanup_func; before_all; /*function invoked before running the suite. If not returning 0, suite is not launched. */
int nb_tests; pre_post_function_t after_all; /*function invoked at the end of the suite, even if some tests failed. */
test_t *tests; test_function_t before_each; /*function invoked before each test within this suite. */
test_function_t after_each; /*function invoked after each test within this suite, even if it failed. */
int nb_tests; /* number of tests */
test_t *tests; /* tests within this suite */
} test_suite_t; } test_suite_t;
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -41,7 +41,7 @@ static RtpProfile rtp_profile; ...@@ -41,7 +41,7 @@ static RtpProfile rtp_profile;
#define EDGE_BW 10 #define EDGE_BW 10
#define THIRDGENERATION_BW 200 #define THIRDGENERATION_BW 200
static int tester_init(void) { static int tester_before_all(void) {
ms_init(); ms_init();
ms_filter_enable_statistics(TRUE); ms_filter_enable_statistics(TRUE);
ortp_init(); ortp_init();
...@@ -57,7 +57,7 @@ static int tester_init(void) { ...@@ -57,7 +57,7 @@ static int tester_init(void) {
return 0; return 0;
} }
static int tester_cleanup(void) { static int tester_after_all(void) {
ortp_exit(); ortp_exit();
ms_exit(); ms_exit();
rtp_profile_clear_all(&rtp_profile); rtp_profile_clear_all(&rtp_profile);
...@@ -493,8 +493,10 @@ static test_t tests[] = { ...@@ -493,8 +493,10 @@ static test_t tests[] = {
test_suite_t adaptive_test_suite = { test_suite_t adaptive_test_suite = {
"AdaptiveAlgorithm", "AdaptiveAlgorithm",
tester_init, tester_before_all,
tester_cleanup, tester_after_all,
NULL,
NULL,
sizeof(tests) / sizeof(tests[0]), sizeof(tests) / sizeof(tests[0]),
tests tests
}; };
...@@ -33,7 +33,7 @@ static RtpProfile rtp_profile; ...@@ -33,7 +33,7 @@ static RtpProfile rtp_profile;
#define SILK16_PAYLOAD_TYPE 123 #define SILK16_PAYLOAD_TYPE 123
#define PCMA8_PAYLOAD_TYPE 8 #define PCMA8_PAYLOAD_TYPE 8
static int tester_init(void) { static int tester_before_all(void) {
ms_init(); ms_init();
ms_filter_enable_statistics(TRUE); ms_filter_enable_statistics(TRUE);
ortp_init(); ortp_init();
...@@ -46,7 +46,7 @@ static int tester_init(void) { ...@@ -46,7 +46,7 @@ static int tester_init(void) {
return 0; return 0;
} }
static int tester_cleanup(void) { static int tester_after_all(void) {
ms_exit(); ms_exit();
rtp_profile_clear_all(&rtp_profile); rtp_profile_clear_all(&rtp_profile);
return 0; return 0;
...@@ -568,8 +568,10 @@ static test_t tests[] = { ...@@ -568,8 +568,10 @@ static test_t tests[] = {
test_suite_t audio_stream_test_suite = { test_suite_t audio_stream_test_suite = {
"AudioStream", "AudioStream",
tester_init, tester_before_all,
tester_cleanup, tester_after_all,
NULL,
NULL,
sizeof(tests) / sizeof(tests[0]), sizeof(tests) / sizeof(tests[0]),
tests tests
}; };
...@@ -28,14 +28,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -28,14 +28,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2_tester_private.h" #include "mediastreamer2_tester_private.h"
#include "private.h" #include "private.h"
static int basic_audio_tester_init(void) { static int basic_audio_tester_before_all(void) {
ms_init(); ms_init();
ms_filter_enable_statistics(TRUE); ms_filter_enable_statistics(TRUE);
ortp_init(); ortp_init();
return 0; return 0;
} }
static int basic_audio_tester_cleanup(void) { static int basic_audio_tester_after_all(void) {
ms_exit(); ms_exit();
return 0; return 0;
} }
...@@ -268,8 +268,10 @@ test_t basic_audio_tests[] = { ...@@ -268,8 +268,10 @@ test_t basic_audio_tests[] = {
test_suite_t basic_audio_test_suite = { test_suite_t basic_audio_test_suite = {
"Basic Audio", "Basic Audio",
basic_audio_tester_init, basic_audio_tester_before_all,
basic_audio_tester_cleanup, basic_audio_tester_after_all,
NULL,
NULL,
sizeof(basic_audio_tests) / sizeof(basic_audio_tests[0]), sizeof(basic_audio_tests) / sizeof(basic_audio_tests[0]),
basic_audio_tests basic_audio_tests
}; };
...@@ -27,14 +27,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -27,14 +27,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2_tester.h" #include "mediastreamer2_tester.h"
#include "mediastreamer2_tester_private.h" #include "mediastreamer2_tester_private.h"
static int tester_init(void) { static int tester_before_all(void) {
/* ms_init(); /* ms_init();
ms_filter_enable_statistics(TRUE); ms_filter_enable_statistics(TRUE);
ortp_init();*/ ortp_init();*/
return 0; return 0;
} }
static int tester_cleanup(void) { static int tester_after_all(void) {
/* ms_exit();*/ /* ms_exit();*/
return 0; return 0;
} }
...@@ -189,8 +189,10 @@ static test_t tests[] = { ...@@ -189,8 +189,10 @@ static test_t tests[] = {
test_suite_t framework_test_suite = { test_suite_t framework_test_suite = {
"Framework", "Framework",
tester_init, tester_before_all,
tester_cleanup, tester_after_all,
NULL,
NULL,
sizeof(tests) / sizeof(tests[0]), sizeof(tests) / sizeof(tests[0]),
tests tests
}; };
...@@ -27,14 +27,14 @@ ...@@ -27,14 +27,14 @@
#ifdef __ARM_NEON__ #ifdef __ARM_NEON__
#include <arm_neon.h> #include <arm_neon.h>
static int tester_init() { static int tester_before_all() {
ortp_set_log_level_mask(ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL); ortp_set_log_level_mask(ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL);
ms_init(); ms_init();
srand(time(0)); srand(time(0));
return 0; return 0;
} }
static int tester_cleanup() { static int tester_after_all() {
ms_exit(); ms_exit();
return 0; return 0;
} }
...@@ -268,8 +268,10 @@ static test_t tests[] = { ...@@ -268,8 +268,10 @@ static test_t tests[] = {
test_suite_t neon_test_suite = { test_suite_t neon_test_suite = {
"NEON", "NEON",
tester_init, tester_before_all,
tester_cleanup, tester_after_all,
NULL,
NULL,
sizeof(tests)/sizeof(test_t), sizeof(tests)/sizeof(test_t),
tests tests
}; };
......
...@@ -21,12 +21,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -21,12 +21,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msmediaplayer.h" #include "mediastreamer2/msmediaplayer.h"
#include "mediastreamer2/mediastream.h" #include "mediastreamer2/mediastream.h"
static int tester_init() { static int tester_before_all() {
ms_init(); ms_init();
return 0; return 0;
} }
static int tester_cleanup() { static int tester_after_all() {
ms_exit(); ms_exit();
return 0; return 0;
} }
...@@ -185,8 +185,10 @@ static test_t tests[] = { ...@@ -185,8 +185,10 @@ static test_t tests[] = {
test_suite_t player_test_suite = { test_suite_t player_test_suite = {
"Player", "Player",
tester_init, tester_before_all,
tester_cleanup, tester_after_all,
NULL,
NULL,
sizeof(tests)/sizeof(test_t), sizeof(tests)/sizeof(test_t),
tests tests
}; };
...@@ -26,13 +26,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -26,13 +26,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2_tester.h" #include "mediastreamer2_tester.h"
#include "mediastreamer2_tester_private.h" #include "mediastreamer2_tester_private.h"
static int sound_card_tester_init(void) { static int sound_card_tester_before_all(void) {