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/>.
#include "CUnit/Basic.h"
#include "CUnit/Automated.h"
#ifdef _WIN32
#if defined(__MINGW32__) || !defined(WINAPI_FAMILY_PARTITION) || !defined(WINAPI_PARTITION_DESKTOP)
#define BC_TESTER_WINDOWS_DESKTOP 1
......@@ -43,6 +44,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#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_writable_dir_prefix = NULL;
......@@ -62,6 +67,8 @@ char* xml_file = "CUnitAutomated-Results.xml";
int xml_enabled = 0;
char * suite_name;
char * test_name;
static long max_vm_kb = 0;
void (*tester_printf_va)(int level, const char *fmt, va_list args);
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 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++) {
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) {
int 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;
}
}
......@@ -157,25 +164,35 @@ static void suite_start_message_handler(const CU_pSuite pSuite) {
suite_start_time = time(NULL);
}
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 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);
test_start_time = time(NULL);
if (test_suite[suite_index]->before_each) {
test_suite[suite_index]->before_each();
}
}
/*derivated from cunit*/
static void test_complete_message_handler(const CU_pTest pTest,
const CU_pSuite pSuite,
const CU_pFailureRecord pFailureList) {
static void test_complete_message_handler(const CU_pTest pTest, const CU_pSuite pSuite,
const CU_pFailureRecord pFailureList) {
int i;
int suite_index = bc_tester_suite_index(pSuite->pName);
char result[2048]={0};
char buffer[2048]={0};
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) {
for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, 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,
}
}
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
......@@ -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;
}
void bc_tester_helper(const char *name, const char* additionnal_helper) {
bc_tester_printf(bc_printf_verbosity_info,"%s --help\n"
"\t\t\t--list-suites\n"
"\t\t\t--list-tests <suite>\n"
"\t\t\t--suite <suite name>\n"
"\t\t\t--test <test name>\n"
bc_tester_printf(bc_printf_verbosity_info,
"%s --help\n"
"\t\t\t--list-suites\n"
"\t\t\t--list-tests <suite>\n"
"\t\t\t--suite <suite name>\n"
"\t\t\t--test <test name>\n"
#ifdef HAVE_CU_CURSES
"\t\t\t--curses\n"
"\t\t\t--curses\n"
#endif
"\t\t\t--xml\n"
"\t\t\t--xml-file <xml file name>\n"
"And additionally:\n"
"%s"
, name
, additionnal_helper);
"\t\t\t--xml\n"
"\t\t\t--xml-file <xml file name>\n"
"\t\t\t--max-alloc <size in ko> (maximum ammount of memory obtained via malloc allocator)\n"
"And additionally:\n"
"%s",
name, additionnal_helper);
}
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
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 i = argid;
if (strcmp(argv[i],"--help")==0){
return -1;
} else if (strcmp(argv[i],"--test")==0){
......@@ -325,7 +379,10 @@ int bc_tester_parse_args(int argc, char **argv, int argid)
xml_enabled = 1;
} else if (strcmp(argv[i], "--xml") == 0){
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]);
return -1;
}
......@@ -341,6 +398,10 @@ int bc_tester_parse_args(int argc, char **argv, int argid)
int bc_tester_start(void) {
int ret;
if (max_vm_kb)
bc_tester_set_max_vm(max_vm_kb);
if( xml_enabled ){
size_t size = strlen(xml_file) + strlen(".tmp") + 1;
char * xml_tmp_file = malloc(sizeof(char) * size);
......@@ -399,11 +460,8 @@ void bc_tester_uninit(void) {
}
static void bc_tester_set_dir_prefix(char **prefix, const char *name) {
size_t len = strlen(name);
if (*prefix != NULL) free(*prefix);
*prefix = malloc(len + 1);
strncpy(*prefix, name, len);
(*prefix)[len] = '\0';
*prefix = strdup(name);
}
const char * bc_tester_get_resource_dir_prefix(void) {
......@@ -428,7 +486,6 @@ static char * bc_tester_path(const char *prefix, const char *name) {
size_t len = strlen(prefix) + 1 + strlen(name) + 1;
file = malloc(len);
snprintf(file, len, "%s/%s", prefix, name);
file[strlen(file)] = '\0';
}
return file;
}
......
......@@ -35,9 +35,11 @@ extern int bc_printf_verbosity_info;
extern int bc_printf_verbosity_error;
typedef void (*test_function_t)(void);
typedef int (*init_function_t)(void);
typedef int (*cleanup_function_t)(void);
typedef int (*test_suite_function_t)(const char *name);
/** Function used in all suites - it is invoked before all and each tests and also after each and all tests
* @return 0 means success, otherwise it's an error
**/
typedef int (*pre_post_function_t)(void);
// typedef int (*test_suite_function_t)(const char *name);
typedef struct {
const char *name;
......@@ -45,11 +47,14 @@ typedef struct {
} test_t;
typedef struct {
const char *name;
init_function_t init_func;
cleanup_function_t cleanup_func;
int nb_tests;
test_t *tests;
const char *name; /*suite name*/
pre_post_function_t
before_all; /*function invoked before running the suite. If not returning 0, suite is not launched. */
pre_post_function_t after_all; /*function invoked at the end of the suite, even if some tests failed. */
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;
#ifdef __cplusplus
......
......@@ -41,7 +41,7 @@ static RtpProfile rtp_profile;
#define EDGE_BW 10
#define THIRDGENERATION_BW 200
static int tester_init(void) {
static int tester_before_all(void) {
ms_init();
ms_filter_enable_statistics(TRUE);
ortp_init();
......@@ -57,7 +57,7 @@ static int tester_init(void) {
return 0;
}
static int tester_cleanup(void) {
static int tester_after_all(void) {
ortp_exit();
ms_exit();
rtp_profile_clear_all(&rtp_profile);
......@@ -493,8 +493,10 @@ static test_t tests[] = {
test_suite_t adaptive_test_suite = {
"AdaptiveAlgorithm",
tester_init,
tester_cleanup,
tester_before_all,
tester_after_all,
NULL,
NULL,
sizeof(tests) / sizeof(tests[0]),
tests
};
......@@ -33,7 +33,7 @@ static RtpProfile rtp_profile;
#define SILK16_PAYLOAD_TYPE 123
#define PCMA8_PAYLOAD_TYPE 8
static int tester_init(void) {
static int tester_before_all(void) {
ms_init();
ms_filter_enable_statistics(TRUE);
ortp_init();
......@@ -46,7 +46,7 @@ static int tester_init(void) {
return 0;
}
static int tester_cleanup(void) {
static int tester_after_all(void) {
ms_exit();
rtp_profile_clear_all(&rtp_profile);
return 0;
......@@ -568,8 +568,10 @@ static test_t tests[] = {
test_suite_t audio_stream_test_suite = {
"AudioStream",
tester_init,
tester_cleanup,
tester_before_all,
tester_after_all,
NULL,
NULL,
sizeof(tests) / sizeof(tests[0]),
tests
};
......@@ -28,14 +28,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2_tester_private.h"
#include "private.h"
static int basic_audio_tester_init(void) {
static int basic_audio_tester_before_all(void) {
ms_init();
ms_filter_enable_statistics(TRUE);
ortp_init();
return 0;
}
static int basic_audio_tester_cleanup(void) {
static int basic_audio_tester_after_all(void) {
ms_exit();
return 0;
}
......@@ -268,8 +268,10 @@ test_t basic_audio_tests[] = {
test_suite_t basic_audio_test_suite = {
"Basic Audio",
basic_audio_tester_init,
basic_audio_tester_cleanup,
basic_audio_tester_before_all,
basic_audio_tester_after_all,
NULL,
NULL,
sizeof(basic_audio_tests) / sizeof(basic_audio_tests[0]),
basic_audio_tests
};
......@@ -27,14 +27,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2_tester.h"
#include "mediastreamer2_tester_private.h"
static int tester_init(void) {
static int tester_before_all(void) {
/* ms_init();
ms_filter_enable_statistics(TRUE);
ortp_init();*/
return 0;
}
static int tester_cleanup(void) {
static int tester_after_all(void) {
/* ms_exit();*/
return 0;
}
......@@ -189,8 +189,10 @@ static test_t tests[] = {
test_suite_t framework_test_suite = {
"Framework",
tester_init,
tester_cleanup,
tester_before_all,
tester_after_all,
NULL,
NULL,
sizeof(tests) / sizeof(tests[0]),
tests
};
......@@ -27,14 +27,14 @@
#ifdef __ARM_NEON__
#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);
ms_init();
srand(time(0));
return 0;
}
static int tester_cleanup() {
static int tester_after_all() {
ms_exit();
return 0;
}
......@@ -268,8 +268,10 @@ static test_t tests[] = {
test_suite_t neon_test_suite = {
"NEON",
tester_init,
tester_cleanup,
tester_before_all,
tester_after_all,
NULL,
NULL,
sizeof(tests)/sizeof(test_t),
tests
};
......
......@@ -21,12 +21,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msmediaplayer.h"
#include "mediastreamer2/mediastream.h"
static int tester_init() {
static int tester_before_all() {
ms_init();
return 0;
}
static int tester_cleanup() {
static int tester_after_all() {
ms_exit();
return 0;
}
......@@ -185,8 +185,10 @@ static test_t tests[] = {
test_suite_t player_test_suite = {
"Player",
tester_init,
tester_cleanup,
tester_before_all,
tester_after_all,
NULL,
NULL,
sizeof(tests)/sizeof(test_t),
tests
};
......@@ -26,13 +26,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2_tester.h"
#include "mediastreamer2_tester_private.h"
static int sound_card_tester_init(void) {
static int sound_card_tester_before_all(void) {
ms_init();
ms_filter_enable_statistics(TRUE);
return 0;
}
static int sound_card_tester_cleanup(void) {
static int sound_card_tester_after_all(void) {
ms_exit();
return 0;
}
......@@ -446,8 +446,10 @@ test_t sound_card_tests[] = {
test_suite_t sound_card_test_suite = {
"Sound Card",
sound_card_tester_init,
sound_card_tester_cleanup,
sound_card_tester_before_all,
sound_card_tester_after_all,
NULL,
NULL,
sizeof(sound_card_tests) / sizeof(sound_card_tests[0]),
sound_card_tests
};
......@@ -44,7 +44,7 @@ static void log_handler(int lev, const char *fmt, va_list args) {
}
}
void mediastreamer2_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args)) {
void mediastreamer2_tester_before_all(void(*ftester_printf)(int level, const char *fmt, va_list args)) {
if (ftester_printf == NULL) ftester_printf = log_handler;
bc_tester_init(ftester_printf, ORTP_MESSAGE, ORTP_ERROR);
......@@ -87,7 +87,7 @@ int main (int argc, char *argv[]) {
int i;
int ret;
mediastreamer2_tester_init(NULL);
mediastreamer2_tester_before_all(NULL);
// this allows to launch tester from outside of tester directory
if (strstr(argv[0], ".libs")) {
......
......@@ -54,7 +54,7 @@ extern test_suite_t neon_test_suite;
#endif
MSWebCam* mediastreamer2_tester_get_mire_webcam(MSWebCamManager *mgr);
extern void mediastreamer2_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args));
extern void mediastreamer2_tester_before_all(void(*ftester_printf)(int level, const char *fmt, va_list args));
extern void mediastreamer2_tester_uninit(void);
#ifdef __cplusplus
......
......@@ -62,7 +62,7 @@ static void ms2NativeOutputTraceHandler(OrtpLogLevel lev, const char *fmt, va_li
MS2Tester::MS2Tester()
: _deviceRotation(0)
{
mediastreamer2_tester_init(nativeOutputTraceHandler);
mediastreamer2_tester_before_all(nativeOutputTraceHandler);
bc_tester_set_resource_dir_prefix("Assets");
}
......
......@@ -49,7 +49,7 @@ MSWebCam* mediastreamer2_tester_get_mire_webcam(MSWebCamManager *mgr) {
return cam;
}
static int tester_init(void) {
static int tester_before_all(void) {
ms_init();
ms_filter_enable_statistics(TRUE);
ortp_init();
......@@ -59,7 +59,7 @@ static int tester_init(void) {
return 0;
}
static int tester_cleanup(void) {
static int tester_after_all(void) {
ms_exit();
rtp_profile_clear_all(&rtp_profile);
return 0;
......@@ -696,8 +696,10 @@ static test_t tests[] = {
test_suite_t video_stream_test_suite = {
"VideoStream",
tester_init,
tester_cleanup,
tester_before_all,
tester_after_all,
NULL,
NULL,
sizeof(tests) / sizeof(tests[0]),
tests
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment