mediastreamer2_tester.c 11 KB
Newer Older
Ghislain MARY's avatar
Ghislain MARY committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006-2013 Belledonne Communications, Grenoble

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "mediastreamer2_tester.h"
21
#include "mediastreamer2_tester_private.h"
Ghislain MARY's avatar
Ghislain MARY committed
22

Simon Morlat's avatar
Simon Morlat committed
23
#include <mediastreamer2/mediastream.h>
24
#if HAVE_CONFIG_H
Simon Morlat's avatar
Simon Morlat committed
25
#include <mediastreamer-config.h>
26
#endif
Simon Morlat's avatar
Simon Morlat committed
27

Ghislain MARY's avatar
Ghislain MARY committed
28 29
#include <stdio.h>
#include "CUnit/Basic.h"
30
#include "CUnit/Automated.h"
Ghislain MARY's avatar
Ghislain MARY committed
31 32 33
#if HAVE_CU_CURSES
#include "CUnit/CUCurses.h"
#endif
jehan's avatar
jehan committed
34 35 36
#ifdef __APPLE__
#include "TargetConditionals.h"
#endif
37

38

39 40
static test_suite_t **test_suite = NULL;
static int nb_test_suites = 0;
41 42 43
static const char* tester_fileroot = SOUND_FILE_PATH;
static const char* tester_writable_dir= WRITE_FILE_PATH;

44
static unsigned char xml = 0;
45 46
static const char *xml_file = "CUnitAutomated-Results.xml";
static char *xml_tmp_file = NULL;
47

Ghislain MARY's avatar
Ghislain MARY committed
48 49 50 51
#if HAVE_CU_CURSES
static unsigned char curses = 0;
#endif

52 53 54 55 56 57 58 59 60 61
static void add_test_suite(test_suite_t *suite) {
	if (test_suite == NULL) {
		test_suite = (test_suite_t **)malloc(10 * sizeof(test_suite_t *));
	}
	test_suite[nb_test_suites] = suite;
	nb_test_suites++;
	if ((nb_test_suites % 10) == 0) {
		test_suite = (test_suite_t **)realloc(test_suite, (nb_test_suites + 10) * sizeof(test_suite_t *));
	}
}
Ghislain MARY's avatar
Ghislain MARY committed
62 63

static int run_test_suite(test_suite_t *suite) {
64
	int i;
Ghislain MARY's avatar
Ghislain MARY committed
65

66
	CU_pSuite pSuite = CU_add_suite(suite->name, suite->init_func, suite->cleanup_func);
Ghislain MARY's avatar
Ghislain MARY committed
67 68 69 70 71 72 73 74 75 76

	for (i = 0; i < suite->nb_tests; i++) {
		if (NULL == CU_add_test(pSuite, suite->tests[i].name, suite->tests[i].func)) {
			return CU_get_error();
		}
	}

	return 0;
}

77 78
static int test_suite_index(const char *suite_name) {
	int i;
Ghislain MARY's avatar
Ghislain MARY committed
79 80 81

	for (i = 0; i < mediastreamer2_tester_nb_test_suites(); i++) {
		if ((strcmp(suite_name, test_suite[i]->name) == 0) && (strlen(suite_name) == strlen(test_suite[i]->name))) {
82
			return i;
Ghislain MARY's avatar
Ghislain MARY committed
83 84 85
		}
	}

86
	return -1;
Ghislain MARY's avatar
Ghislain MARY committed
87
}
88 89

#if HAVE_CU_GET_SUITE
90 91 92 93 94 95 96 97 98 99 100 101 102 103
static void list_suite_tests(const char *suite_name) {
	int j;
	for( j = 0; j < mediastreamer2_tester_nb_tests(suite_name); j++) {
		const char *test_name = mediastreamer2_tester_test_name(suite_name, j);
		fprintf(stdout, "%s\n", test_name);
	}
}
static void list_suites() {
	int j;
	for(j = 0; j < mediastreamer2_tester_nb_test_suites(); j++) {
		const char *suite_name = mediastreamer2_tester_test_suite_name(j);
		fprintf(stdout, "%s\n", suite_name);
	}
}
104
#endif
Ghislain MARY's avatar
Ghislain MARY committed
105

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

const char* mediastreamer2_tester_get_file_root(){
    return tester_fileroot;
}

void mediastreamer2_tester_set_file_root(const char* fileroot){
    tester_fileroot = fileroot;
}

const char* mediastreamer2_tester_get_writable_dir(){
    return tester_writable_dir;
}
void mediastreamer2_tester_set_writable_dir(const char* writable_dir){
    tester_writable_dir = writable_dir;
}


123 124 125 126 127 128 129 130 131 132 133
int mediastreamer2_tester_nb_test_suites(void) {
	return nb_test_suites;
}

int mediastreamer2_tester_nb_tests(const char *suite_name) {
	int i = test_suite_index(suite_name);
	if (i < 0) return 0;
	return test_suite[i]->nb_tests;
}

const char * mediastreamer2_tester_test_suite_name(int suite_index) {
Ghislain MARY's avatar
Ghislain MARY committed
134 135 136 137
	if (suite_index >= mediastreamer2_tester_nb_test_suites()) return NULL;
	return test_suite[suite_index]->name;
}

138 139 140
const char * mediastreamer2_tester_test_name(const char *suite_name, int test_index) {
	int suite_index = test_suite_index(suite_name);
	if ((suite_index < 0) || (suite_index >= mediastreamer2_tester_nb_test_suites())) return NULL;
Ghislain MARY's avatar
Ghislain MARY committed
141 142 143 144
	if (test_index >= test_suite[suite_index]->nb_tests) return NULL;
	return test_suite[suite_index]->tests[test_index].name;
}

145
void mediastreamer2_tester_init(void) {
146 147
	int i;

Ghislain MARY's avatar
Ghislain MARY committed
148 149
	add_test_suite(&basic_audio_test_suite);
	add_test_suite(&sound_card_test_suite);
150
	add_test_suite(&adaptive_test_suite);
jehan's avatar
jehan committed
151
	add_test_suite(&audio_stream_test_suite);
152
#ifdef VIDEO_ENABLED
153
	add_test_suite(&video_stream_test_suite);
154
#endif
155
	add_test_suite(&framework_test_suite);
François Grisez's avatar
François Grisez committed
156
	add_test_suite(&player_test_suite);
157 158 159
#ifdef __ARM_NEON__
    add_test_suite(&neon_test_suite);
#endif
160 161 162 163
	for (i = 0; i < mediastreamer2_tester_nb_test_suites(); i++) {
		run_test_suite(test_suite[i]);
	}

164 165 166 167 168 169 170 171 172 173
}

void mediastreamer2_tester_uninit(void) {
	if (test_suite != NULL) {
		free(test_suite);
		test_suite = NULL;
		nb_test_suites = 0;
	}
}

174 175 176 177 178 179 180 181


	/*derivated from cunit*/
static void test_complete_message_handler(const CU_pTest pTest,
											const CU_pSuite pSuite,
											const CU_pFailureRecord pFailureList) {
	int i;
	CU_pFailureRecord pFailure = pFailureList;
182

183 184 185 186 187 188 189 190 191 192 193 194 195 196
	if (pFailure) {
		ms_warning("Suite [%s], Test [%s] had failures:", pSuite->pName, pTest->pName);
	} else {
		ms_warning(" passed");
	}
	for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) {
		ms_warning("\n    %d. %s:%u  - %s", i,
			(NULL != pFailure->strFileName) ? pFailure->strFileName : "",
			pFailure->uiLineNumber,
			(NULL != pFailure->strCondition) ? pFailure->strCondition : "");
	}
}

static void test_all_tests_complete_message_handler(const CU_pFailureRecord pFailure) {
Simon Morlat's avatar
Simon Morlat committed
197
#ifdef HAVE_CU_GET_SUITE
198
	ms_warning("\n\n %s",CU_get_run_results_string());
Simon Morlat's avatar
Simon Morlat committed
199
#endif
200 201 202 203 204 205 206 207 208 209 210 211 212
}

static void test_suite_init_failure_message_handler(const CU_pSuite pSuite) {
	ms_warning("Suite initialization failed for [%s].", pSuite->pName);
}

static void test_suite_cleanup_failure_message_handler(const CU_pSuite pSuite) {
	ms_warning("Suite cleanup failed for '%s'.", pSuite->pName);
}

static void test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite) {
	ms_warning("Suite [%s] Test [%s]", pSuite->pName,pTest->pName);
}
Simon Morlat's avatar
Simon Morlat committed
213 214 215


#ifdef HAVE_CU_GET_SUITE
216 217 218
static void test_suite_start_message_handler(const CU_pSuite pSuite) {
	ms_warning("Suite [%s]", pSuite->pName);
}
Simon Morlat's avatar
Simon Morlat committed
219
#endif
220

Ghislain MARY's avatar
Ghislain MARY committed
221
int mediastreamer2_tester_run_tests(const char *suite_name, const char *test_name) {
222
	int ret;
Ghislain MARY's avatar
Ghislain MARY committed
223

224 225 226 227 228
	CU_set_test_start_handler(test_start_message_handler);
	CU_set_test_complete_handler(test_complete_message_handler);
	CU_set_all_test_complete_handler(test_all_tests_complete_message_handler);
	CU_set_suite_init_failure_handler(test_suite_init_failure_message_handler);
	CU_set_suite_cleanup_failure_handler(test_suite_cleanup_failure_message_handler);
Simon Morlat's avatar
Simon Morlat committed
229
#ifdef HAVE_CU_GET_SUITE
230
	CU_set_suite_start_handler(test_suite_start_message_handler);
Simon Morlat's avatar
Simon Morlat committed
231
#endif
232 233 234
	if( xml ){
		xml_tmp_file = ms_strdup_printf("%s.tmp", xml_file);
		CU_set_output_filename(xml_tmp_file);
235 236
		CU_automated_run_tests();
	} else {
Ghislain MARY's avatar
Ghislain MARY committed
237
#if HAVE_CU_GET_SUITE
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
		if (suite_name){
			CU_pSuite suite;
			CU_basic_set_mode(CU_BRM_VERBOSE);
			suite=CU_get_suite(suite_name);
			if (!suite) {
				fprintf(stderr, "Could not find suite '%s'. Available suites are:\n", suite_name);
				list_suites();
			} else if (test_name) {
				CU_pTest test=CU_get_test_by_name(test_name, suite);
				if (!test) {
					fprintf(stderr, "Could not find test '%s' in suite '%s'. Available tests are:\n", test_name, suite_name);
					// do not use suite_name here, since this method is case sentisitive
					list_suite_tests(suite->pName);
				} else {
					CU_ErrorCode err= CU_basic_run_test(suite, test);
					if (err != CUE_SUCCESS) fprintf(stderr, "CU_basic_run_test error=%d\n", err);
				}
255
			} else {
256
				CU_basic_run_suite(suite);
257
			}
258
		} else
Ghislain MARY's avatar
Ghislain MARY committed
259
#endif
260
		{
Ghislain MARY's avatar
Ghislain MARY committed
261
#if HAVE_CU_CURSES
262 263 264 265 266
			if (curses) {
				/* Run tests using the CUnit curses interface */
				CU_curses_run_tests();
			}
			else
Ghislain MARY's avatar
Ghislain MARY committed
267
#endif
268 269 270 271 272
			{
				/* Run all tests using the CUnit Basic interface */
				CU_basic_set_mode(CU_BRM_VERBOSE);
				CU_basic_run_tests();
			}
Ghislain MARY's avatar
Ghislain MARY committed
273 274
		}
	}
275
	/* Redisplay list of failed tests on end */
276 277 278 279
	if (CU_get_number_of_failure_records()){
		CU_basic_show_failures(CU_get_failure_list());
		printf("\n");
	}
Ghislain MARY's avatar
Ghislain MARY committed
280

jehan's avatar
jehan committed
281 282
	ret=CU_get_number_of_tests_failed()!=0;
	return ret;
Ghislain MARY's avatar
Ghislain MARY committed
283 284
}

285 286
void helper(const char *name) {
	fprintf(stderr, "%s \t--help\n"
287
#ifndef _WIN32
288
		"\t\t\t--verbose\n"
289
#endif
290
		"\t\t\t--silent\n"
291 292 293 294 295 296 297 298 299
#if HAVE_CU_GET_SUITE
		"\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"
#endif
#if HAVE_CU_CURSES
		"\t\t\t--curses\n"
#endif
300
		"\t\t\t--xml\n"
301
		"\t\t\t--xml-file <xml file prefix (will be suffixed by '-Results.xml')>\n"
302 303 304 305 306 307 308 309
		, name);
}

#define CHECK_ARG(argument, index, argc) \
	if (index >= argc) { \
		fprintf(stderr, "Missing argument for \"%s\"\n", argument); \
		return -1; \
	}
Ghislain MARY's avatar
Ghislain MARY committed
310

311
#if defined(WIN32) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
312
#define BUILD_ENTRY_POINT 0
313 314
#else
#define BUILD_ENTRY_POINT 1
315 316 317
#endif

#if BUILD_ENTRY_POINT
318 319
#if TARGET_OS_MAC || TARGET_OS_IPHONE
int apple_main (int argc, char *argv[]) {
jehan's avatar
jehan committed
320
#else
Ghislain MARY's avatar
Ghislain MARY committed
321
int main (int argc, char *argv[]) {
jehan's avatar
jehan committed
322
#endif
Ghislain MARY's avatar
Ghislain MARY committed
323
	int i;
324
	int ret;
325 326
	const char *suite_name = NULL;
	const char *test_name = NULL;
Ghislain MARY's avatar
Ghislain MARY committed
327 328
	unsigned char verbose = FALSE;

329 330 331 332 333 334
	/* initialize the CUnit test registry */
	if (CUE_SUCCESS != CU_initialize_registry())
		return CU_get_error();

	mediastreamer2_tester_init();

Ghislain MARY's avatar
Ghislain MARY committed
335 336
	for(i = 1; i < argc; ++i) {
		if (strcmp(argv[i], "--help") == 0) {
337
			helper(argv[0]);
Ghislain MARY's avatar
Ghislain MARY committed
338 339 340
			return 0;
		} else if (strcmp(argv[i], "--verbose") == 0) {
			verbose = TRUE;
341 342
		} else if (strcmp(argv[i], "--silent") == 0) {
			verbose = FALSE;
343 344 345
		} else if (strcmp(argv[i], "--xml-file") == 0){
			CHECK_ARG("--xml-file", ++i, argc);
			xml_file = argv[i];
346
			xml = 1;
347 348
		} else if (strcmp(argv[i], "--xml") == 0){
			xml = 1;
Ghislain MARY's avatar
Ghislain MARY committed
349 350 351
		}
#if HAVE_CU_GET_SUITE
		else if (strcmp(argv[i], "--test")==0) {
352
			CHECK_ARG("--test", ++i, argc);
Ghislain MARY's avatar
Ghislain MARY committed
353 354
			test_name = argv[i];
		} else if (strcmp(argv[i], "--suite") == 0) {
355
			CHECK_ARG("--suite", ++i, argc);
Ghislain MARY's avatar
Ghislain MARY committed
356
			suite_name = argv[i];
357
		}  else if (strcmp(argv[i],"--list-suites")==0){
358
			list_suites();
359 360 361 362
			return 0;
		} else if (strcmp(argv[i],"--list-tests")==0){
			CHECK_ARG("--list-tests", ++i, argc);
			suite_name = argv[i];
363 364 365 366 367 368 369 370
			if (CU_get_suite(suite_name)==NULL){
				fprintf(stderr, "Could not find suite '%s'. Available suites are:\n", suite_name);
				list_suites();
				return -1;
			}else{
				list_suite_tests(suite_name);
				return 0;
			}
Ghislain MARY's avatar
Ghislain MARY committed
371 372 373 374 375 376 377
		}
#endif
#if HAVE_CU_CURSES
		else if (strcmp(argv[i], "--curses") == 0) {
			curses = 1;
		}
#endif
378
		else {
379 380
			fprintf(stderr, "Unknown option \"%s\"\n", argv[i]); \

381 382 383
			helper(argv[0]);
			return -1;
		}
Ghislain MARY's avatar
Ghislain MARY committed
384 385
	}

386

Ghislain MARY's avatar
Ghislain MARY committed
387
	if (verbose) {
Simon Morlat's avatar
Simon Morlat committed
388
		putenv("MEDIASTREAMER_DEBUG=1");
Ghislain MARY's avatar
Ghislain MARY committed
389
	} else {
390
		putenv("MEDIASTREAMER_DEBUG=0");
Ghislain MARY's avatar
Ghislain MARY committed
391 392
	}

393
#ifdef HAVE_CU_CURSES
394
	if( xml && curses ){
395 396 397 398 399
		printf("Cannot use both xml and curses\n");
		return -1;
	}
#endif

400
	if( xml && (suite_name || test_name) ){
401 402 403 404
		printf("Cannot use both xml and specific test suite\n");
		return -1;
	}

405
	ret = mediastreamer2_tester_run_tests(suite_name, test_name);
406
	CU_cleanup_registry();
407
	mediastreamer2_tester_uninit();
408 409 410 411 412 413 414 415

	if ( xml ) {
		/*create real xml file only if tester did not crash*/
		ms_strcat_printf(xml_tmp_file, "-Results.xml");
		rename(xml_tmp_file, xml_file);
		ms_free(xml_tmp_file);
	}

416
	return ret;
Ghislain MARY's avatar
Ghislain MARY committed
417 418
}
#endif