liblinphone_tester.c 15.6 KB
Newer Older
jehan's avatar
jehan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
	belle-sip - SIP (RFC3261) library.
    Copyright (C) 2010  Belledonne Communications SARL

    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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
21
#include "private.h"
jehan's avatar
jehan committed
22
#include "liblinphone_tester.h"
jehan's avatar
jehan committed
23 24 25
#if HAVE_CU_CURSES
#include "CUnit/CUCurses.h"
#endif
26

jehan's avatar
jehan committed
27

Ghislain MARY's avatar
Ghislain MARY committed
28 29 30 31 32 33 34 35 36 37
static test_suite_t **test_suite = NULL;
static int nb_test_suites = 0;


#if HAVE_CU_CURSES
static unsigned char curses = 0;
#endif


static  stats global_stat;
jehan's avatar
jehan committed
38 39
const char* test_domain="sipopen.example.org";
const char* auth_domain="sip.example.org";
jehan's avatar
jehan committed
40 41
const char* test_username="liblinphone_tester";
const char* test_password="secret";
42
const char* test_route="sip2.linphone.org";
jehan's avatar
jehan committed
43

44 45 46 47 48
#if WINAPI_FAMILY_PHONE_APP
const char *liblinphone_tester_file_prefix="Assets";
#else
const char *liblinphone_tester_file_prefix="./tester";
#endif
jehan's avatar
jehan committed
49

Yann Diorcet's avatar
Yann Diorcet committed
50 51 52 53 54 55
#ifdef ANDROID
extern void AndroidPrintf(FILE *stream, const char *fmt, ...);
#define fprintf(file, fmt, ...) AndroidPrintf(file, fmt, ##__VA_ARGS__)  
#endif


jehan's avatar
jehan committed
56
LinphoneAddress * create_linphone_address(const char * domain) {
jehan's avatar
jehan committed
57 58
	LinphoneAddress *addr = linphone_address_new(NULL);
	CU_ASSERT_PTR_NOT_NULL_FATAL(addr);
jehan's avatar
jehan committed
59 60
	linphone_address_set_username(addr,test_username);
	CU_ASSERT_STRING_EQUAL(test_username,linphone_address_get_username(addr));
61
	if (!domain) domain= test_route;
jehan's avatar
jehan committed
62 63
	linphone_address_set_domain(addr,domain);
	CU_ASSERT_STRING_EQUAL(domain,linphone_address_get_domain(addr));
jehan's avatar
jehan committed
64 65 66 67 68 69
	linphone_address_set_display_name(addr, NULL);
	linphone_address_set_display_name(addr, "Mr Tester");
	CU_ASSERT_STRING_EQUAL("Mr Tester",linphone_address_get_display_name(addr));
	return addr;
}

jehan's avatar
jehan committed
70
void auth_info_requested(LinphoneCore *lc, const char *realm, const char *username) {
Sylvain Berfini's avatar
Sylvain Berfini committed
71 72
	stats* counters;
	LinphoneAuthInfo *info;
73 74 75
	ms_message("Auth info requested  for user id [%s] at realm [%s]\n"
					,username
					,realm);
Sylvain Berfini's avatar
Sylvain Berfini committed
76
	counters = (stats*)linphone_core_get_user_data(lc);
77
	counters->number_of_auth_info_requested++;
Sylvain Berfini's avatar
Sylvain Berfini committed
78
	info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain); /*create authentication structure from identity*/
79
	linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
jehan's avatar
jehan committed
80

81
}
jehan's avatar
jehan committed
82

jehan's avatar
jehan committed
83
LinphoneCore* create_lc_with_auth(unsigned int with_auth) {
jehan's avatar
jehan committed
84
	LinphoneCoreVTable v_table;
jehan's avatar
jehan committed
85
	LinphoneCore* lc;
jehan's avatar
jehan committed
86 87
	memset (&v_table,0,sizeof(v_table));
	v_table.registration_state_changed=registration_state_changed;
88 89 90
	if (with_auth) {
		v_table.auth_info_requested=auth_info_requested;
	}
jehan's avatar
jehan committed
91 92
	lc = linphone_core_new(&v_table,NULL,NULL,NULL);
	linphone_core_set_user_data(lc,&global_stat);
Simon Morlat's avatar
Simon Morlat committed
93 94
	/* until we have good certificates on our test server... */
	linphone_core_verify_server_certificates(lc,FALSE);
95 96
	/*to allow testing with 127.0.0.1*/
	linphone_core_set_network_reachable(lc,TRUE);
jehan's avatar
jehan committed
97
	return lc;
jehan's avatar
jehan committed
98
}
jehan's avatar
jehan committed
99

jehan's avatar
jehan committed
100 101
void reset_counters( stats* counters) {
	memset(counters,0,sizeof(stats));
jehan's avatar
jehan committed
102
}
jehan's avatar
jehan committed
103

104
LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file, int proxy_count) {
jehan's avatar
jehan committed
105 106
	LinphoneCore* lc;
	int retry=0;
Sylvain Berfini's avatar
Sylvain Berfini committed
107
	stats* counters;
108 109 110
	char filepath[256];
	char ringpath[256];
	char ringbackpath[256];
jehan's avatar
jehan committed
111
	char rootcapath[256];
112 113
	sprintf(filepath, "%s/%s", path, file);
	lc =  linphone_core_new(v_table,NULL,filepath,NULL);
jehan's avatar
jehan committed
114
	linphone_core_set_user_data(lc,&global_stat);
Sylvain Berfini's avatar
Sylvain Berfini committed
115
	counters = (stats*)linphone_core_get_user_data(lc);
116
	
jehan's avatar
jehan committed
117 118 119 120
	/* until we have good certificates on our test server...
	linphone_core_verify_server_certificates(lc,FALSE);*/
	sprintf(rootcapath, "%s/certificates/cacert.pem", path);
	linphone_core_set_root_ca(lc,rootcapath);
Simon Morlat's avatar
Simon Morlat committed
121
	
122 123 124 125
	sprintf(ringpath, "%s/%s", path, "oldphone.wav");
	sprintf(ringbackpath, "%s/%s", path, "ringback.wav");
	linphone_core_set_ring(lc, ringpath);
	linphone_core_set_ringback(lc, ringbackpath);
jehan's avatar
jehan committed
126

jehan's avatar
jehan committed
127
	reset_counters(counters);
jehan's avatar
jehan committed
128
	/*CU_ASSERT_EQUAL(ms_list_size(linphone_core_get_proxy_config_list(lc)),proxy_count);*/
jehan's avatar
jehan committed
129

jehan's avatar
jehan committed
130
	while (counters->number_of_LinphoneRegistrationOk<proxy_count && retry++ <20) {
Simon Morlat's avatar
Simon Morlat committed
131 132
		linphone_core_iterate(lc);
		ms_usleep(100000);
jehan's avatar
jehan committed
133
	}
jehan's avatar
jehan committed
134
	CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationOk,proxy_count);
jehan's avatar
jehan committed
135 136
	return lc;
}
jehan's avatar
jehan committed
137 138

bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value) {
jehan's avatar
jehan committed
139
	MSList* lcs=NULL;
Sylvain Berfini's avatar
Sylvain Berfini committed
140
	bool_t result;
141 142 143 144
	if (lc_1)
		lcs=ms_list_append(lcs,lc_1);
	if (lc_2)
		lcs=ms_list_append(lcs,lc_2);
jehan's avatar
jehan committed
145 146 147 148
	result=wait_for_list(lcs,counter,value,2000);
	ms_list_free(lcs);
	return result;
}
Ghislain MARY's avatar
Ghislain MARY committed
149

jehan's avatar
jehan committed
150
bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms) {
jehan's avatar
jehan committed
151
	int retry=0;
jehan's avatar
jehan committed
152 153 154 155 156
	MSList* iterator;
	while (*counter<value && retry++ <timeout_ms/100) {
		 for (iterator=lcs;iterator!=NULL;iterator=iterator->next) {
			 linphone_core_iterate((LinphoneCore*)(iterator->data));
		 }
jehan's avatar
jehan committed
157 158 159 160 161
		ms_usleep(100000);
	}
	if(*counter<value) return FALSE;
	else return TRUE;
}
Ghislain MARY's avatar
Ghislain MARY committed
162

jehan's avatar
jehan committed
163 164 165
static void enable_codec(LinphoneCore* lc,const char* type,int rate) {
	MSList* codecs=ms_list_copy(linphone_core_get_audio_codecs(lc));
	MSList* codecs_it;
Sylvain Berfini's avatar
Sylvain Berfini committed
166
	PayloadType* pt;
jehan's avatar
jehan committed
167 168 169
	for (codecs_it=codecs;codecs_it!=NULL;codecs_it=codecs_it->next) {
			linphone_core_enable_payload_type(lc,(PayloadType*)codecs_it->data,0);
	}
170
	if((pt = linphone_core_find_payload_type(lc,type,rate,1))) {
jehan's avatar
jehan committed
171 172
		linphone_core_enable_payload_type(lc,pt, 1);
	}
173
	ms_list_free(codecs);
jehan's avatar
jehan committed
174
}
jehan's avatar
jehan committed
175

176
LinphoneCoreManager* linphone_core_manager_new2(const char* path, const char* rc_file, int check_for_proxies) {
jehan's avatar
jehan committed
177
	LinphoneCoreManager* mgr= malloc(sizeof(LinphoneCoreManager));
jehan's avatar
jehan committed
178
	LinphoneProxyConfig* proxy;
jehan's avatar
jehan committed
179 180 181
	memset (mgr,0,sizeof(LinphoneCoreManager));
	mgr->v_table.registration_state_changed=registration_state_changed;
	mgr->v_table.call_state_changed=call_state_changed;
jehan's avatar
jehan committed
182
	mgr->v_table.text_received=text_message_received;
183
	mgr->v_table.message_received=message_received;
jehan's avatar
jehan committed
184 185
	mgr->v_table.new_subscription_request=new_subscribtion_request;
	mgr->v_table.notify_presence_recv=notify_presence_received;
jehan's avatar
jehan committed
186
	mgr->v_table.transfer_state_changed=linphone_transfer_state_changed;
187
	mgr->lc=configure_lc_from(&mgr->v_table, path, rc_file, check_for_proxies?(rc_file?1:0):0);
jehan's avatar
jehan committed
188 189
	enable_codec(mgr->lc,"PCMU",8000);
	linphone_core_set_user_data(mgr->lc,&mgr->stat);
jehan's avatar
jehan committed
190
	linphone_core_get_default_proxy(mgr->lc,&proxy);
jehan's avatar
jehan committed
191 192 193 194
	if (proxy) {
		mgr->identity = linphone_address_new(linphone_proxy_config_get_identity(proxy));
		linphone_address_clean(mgr->identity);
	}
jehan's avatar
jehan committed
195 196
	return mgr;
}
Ghislain MARY's avatar
Ghislain MARY committed
197

198 199 200 201
LinphoneCoreManager* linphone_core_manager_new(const char* path, const char* rc_file) {
	return linphone_core_manager_new2(path, rc_file, TRUE);
}

jehan's avatar
jehan committed
202
void linphone_core_manager_destroy(LinphoneCoreManager* mgr) {
203
	if (mgr->lc) linphone_core_destroy(mgr->lc);
jehan's avatar
jehan committed
204
	if (mgr->identity) linphone_address_destroy(mgr->identity);
jehan's avatar
jehan committed
205 206
	free(mgr);
}
jehan's avatar
jehan committed
207

jehan's avatar
jehan committed
208

Ghislain MARY's avatar
Ghislain MARY committed
209 210 211 212 213 214 215 216 217 218
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 *));
	}
}
jehan's avatar
jehan committed
219

Ghislain MARY's avatar
Ghislain MARY committed
220 221
static int run_test_suite(test_suite_t *suite) {
	int i;
jehan's avatar
jehan committed
222

Ghislain MARY's avatar
Ghislain MARY committed
223
	CU_pSuite pSuite = CU_add_suite(suite->name, suite->init_func, suite->cleanup_func);
jehan's avatar
jehan committed
224

Ghislain MARY's avatar
Ghislain MARY committed
225 226 227 228 229
	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();
		}
	}
jehan's avatar
jehan committed
230

Ghislain MARY's avatar
Ghislain MARY committed
231 232 233 234 235 236 237 238 239 240
	return 0;
}

static int test_suite_index(const char *suite_name) {
	int i;

	for (i = 0; i < liblinphone_tester_nb_test_suites(); i++) {
		if ((strcmp(suite_name, test_suite[i]->name) == 0) && (strlen(suite_name) == strlen(test_suite[i]->name))) {
			return i;
		}
jehan's avatar
jehan committed
241
	}
Ghislain MARY's avatar
Ghislain MARY committed
242 243 244 245

	return -1;
}

Yann Diorcet's avatar
Yann Diorcet committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
static int test_index(const char *suite_name, const char *test_name) {
	int j,i;
	
	j = test_suite_index(suite_name);
	if(j != -1) {
		for (i = 0; i < test_suite[j]->nb_tests; i++) {
			if ((strcmp(test_name, test_suite[j]->tests[i].name) == 0) && (strlen(test_name) == strlen(test_suite[j]->tests[i].name))) {
				return i;
			}
		}
	}

	return -1;
}

Ghislain MARY's avatar
Ghislain MARY committed
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
int liblinphone_tester_nb_test_suites(void) {
	return nb_test_suites;
}

int liblinphone_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 * liblinphone_tester_test_suite_name(int suite_index) {
	if (suite_index >= liblinphone_tester_nb_test_suites()) return NULL;
	return test_suite[suite_index]->name;
}

const char * liblinphone_tester_test_name(const char *suite_name, int test_index) {
	int suite_index = test_suite_index(suite_name);
	if ((suite_index < 0) || (suite_index >= liblinphone_tester_nb_test_suites())) return NULL;
	if (test_index >= test_suite[suite_index]->nb_tests) return NULL;
	return test_suite[suite_index]->tests[test_index].name;
}

void liblinphone_tester_init(void) {
	add_test_suite(&setup_test_suite);
	add_test_suite(&register_test_suite);
	add_test_suite(&call_test_suite);
	add_test_suite(&message_test_suite);
	add_test_suite(&presence_test_suite);
289
#ifdef UPNP
Yann Diorcet's avatar
Yann Diorcet committed
290
	add_test_suite(&upnp_test_suite);
291
#endif
Ghislain MARY's avatar
Ghislain MARY committed
292 293 294 295 296 297 298
}

void liblinphone_tester_uninit(void) {
	if (test_suite != NULL) {
		free(test_suite);
		test_suite = NULL;
		nb_test_suites = 0;
jehan's avatar
jehan committed
299
	}
Ghislain MARY's avatar
Ghislain MARY committed
300
}
301

Ghislain MARY's avatar
Ghislain MARY committed
302 303
int liblinphone_tester_run_tests(const char *suite_name, const char *test_name) {
	int i;
304

Ghislain MARY's avatar
Ghislain MARY committed
305 306 307
	/* initialize the CUnit test registry */
	if (CUE_SUCCESS != CU_initialize_registry())
		return CU_get_error();
308

Ghislain MARY's avatar
Ghislain MARY committed
309 310 311
	for (i = 0; i < liblinphone_tester_nb_test_suites(); i++) {
		run_test_suite(test_suite[i]);
	}
312

Ghislain MARY's avatar
Ghislain MARY committed
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
#if HAVE_CU_GET_SUITE
	if (suite_name){
		CU_pSuite suite;
		CU_basic_set_mode(CU_BRM_VERBOSE);
		suite=CU_get_suite(suite_name);
		if (test_name) {
			CU_pTest test=CU_get_test_by_name(test_name, suite);
			CU_basic_run_test(suite, test);
		} else
			CU_basic_run_suite(suite);
	} else
#endif
	{
#if HAVE_CU_CURSES
		if (curses) {
			/* Run tests using the CUnit curses interface */
			CU_curses_run_tests();
		}
		else
#endif
		{
			/* Run all tests using the CUnit Basic interface */
			CU_basic_set_mode(CU_BRM_VERBOSE);
			CU_basic_run_tests();
		}
	}
339

Ghislain MARY's avatar
Ghislain MARY committed
340 341
	CU_cleanup_registry();
	return CU_get_error();
jehan's avatar
jehan committed
342
}
Ghislain MARY's avatar
Ghislain MARY committed
343

344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
#ifdef ANDROID
#include <android/log.h>

static const char* LogDomain = "liblinphone_tester";

void linphone_android_log_handler(int prio, const char *fmt, va_list args) {
	char str[4096];
	char *current;
	char *next;

	vsnprintf(str, sizeof(str) - 1, fmt, args);
	str[sizeof(str) - 1] = '\0';
	if (strlen(str) < 512) {
		__android_log_write(prio, LogDomain, str);
	} else {
		current = str;
		while ((next = strchr(current, '\n')) != NULL) {
			*next = '\0';
			__android_log_write(prio, LogDomain, current);
			current = next + 1;
		}
		__android_log_write(prio, LogDomain, current);
	}
}

static void linphone_android_ortp_log_handler(OrtpLogLevel lev, const char *fmt, va_list args) {
	int prio;
	switch(lev){
	case ORTP_DEBUG:	prio = ANDROID_LOG_DEBUG;	break;
	case ORTP_MESSAGE:	prio = ANDROID_LOG_INFO;	break;
	case ORTP_WARNING:	prio = ANDROID_LOG_WARN;	break;
	case ORTP_ERROR:	prio = ANDROID_LOG_ERROR;	break;
	case ORTP_FATAL:	prio = ANDROID_LOG_FATAL;	break;
	default:		prio = ANDROID_LOG_DEFAULT;	break;
	}
	linphone_android_log_handler(prio, fmt, args);
}
#endif
Ghislain MARY's avatar
Ghislain MARY committed
382

Yann Diorcet's avatar
Yann Diorcet committed
383 384 385
void helper(const char *name) {
	fprintf(stderr,"%s \t--help\n"
			"\t\t\t--verbose\n"
386
			"\t\t\t--silent\n"
Yann Diorcet's avatar
Yann Diorcet committed
387 388 389 390
			"\t\t\t--list-suites\n"
			"\t\t\t--list-tests <suite>\n"
			"\t\t\t--config <config path>\n"
			"\t\t\t--domain <test sip domain>\n"
391
			"\t\t\t--auth-domain <test auth domain>\n"
Yann Diorcet's avatar
Yann Diorcet committed
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
#if HAVE_CU_GET_SUITE
			"\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
			, 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
408
#ifndef WINAPI_FAMILY_PHONE_APP
jehan's avatar
jehan committed
409
int main (int argc, char *argv[]) {
410
	int i,j;
Ghislain MARY's avatar
Ghislain MARY committed
411
	int ret;
412 413
	const char *suite_name=NULL;
	const char *test_name=NULL;
Yann Diorcet's avatar
Yann Diorcet committed
414 415
	
	liblinphone_tester_init();
Ghislain MARY's avatar
Ghislain MARY committed
416

jehan's avatar
jehan committed
417 418
	for(i=1;i<argc;++i){
		if (strcmp(argv[i],"--help")==0){
Yann Diorcet's avatar
Yann Diorcet committed
419
			helper(argv[0]);
Ghislain MARY's avatar
Ghislain MARY committed
420
			return 0;
Yann Diorcet's avatar
Yann Diorcet committed
421
		} else if (strcmp(argv[i],"--verbose")==0){
422
#ifndef ANDROID
Ghislain MARY's avatar
Ghislain MARY committed
423
			linphone_core_enable_logs(NULL);
424 425 426
#else
			linphone_core_enable_logs_with_cb(linphone_android_ortp_log_handler);
#endif
427 428
		} else if (strcmp(argv[i],"--silent")==0){
			ortp_set_log_level_mask(ORTP_FATAL);
Yann Diorcet's avatar
Yann Diorcet committed
429 430
		} else if (strcmp(argv[i],"--domain")==0){
			CHECK_ARG("--domain", ++i, argc);
jehan's avatar
jehan committed
431
			test_domain=argv[i];
Yann Diorcet's avatar
Yann Diorcet committed
432 433
		} else if (strcmp(argv[i],"--auth-domain")==0){
			CHECK_ARG("--auth-domain", ++i, argc);
jehan's avatar
jehan committed
434
			auth_domain=argv[i];
Yann Diorcet's avatar
Yann Diorcet committed
435 436
		} else if (strcmp(argv[i],"--test")==0){
			CHECK_ARG("--test", ++i, argc);
jehan's avatar
jehan committed
437
			test_name=argv[i];
Yann Diorcet's avatar
Yann Diorcet committed
438 439
		} else if (strcmp(argv[i],"--config")==0){
			CHECK_ARG("--config", ++i, argc);
440
			liblinphone_tester_file_prefix=argv[i];
Yann Diorcet's avatar
Yann Diorcet committed
441 442
		} else if (strcmp(argv[i],"--suite")==0){
			CHECK_ARG("--suite", ++i, argc);
jehan's avatar
jehan committed
443
			suite_name=argv[i];
Yann Diorcet's avatar
Yann Diorcet committed
444
		} else if (strcmp(argv[i],"--list-suites")==0){
445 446 447
			for(j=0;j<liblinphone_tester_nb_test_suites();j++) {
				suite_name = liblinphone_tester_test_suite_name(j);
				fprintf(stdout, "%s\n", suite_name);
Yann Diorcet's avatar
Yann Diorcet committed
448 449
			}
			return 0;	
Yann Diorcet's avatar
Yann Diorcet committed
450 451 452
		} else if (strcmp(argv[i],"--list-tests")==0){
			CHECK_ARG("--list-tests", ++i, argc);
			suite_name = argv[i];
453 454 455 456
			for(j=0;j<liblinphone_tester_nb_tests(suite_name);j++) {
				test_name = liblinphone_tester_test_name(suite_name, j);
				fprintf(stdout, "%s\n", test_name);
			}	
Yann Diorcet's avatar
Yann Diorcet committed
457
			return 0;
Yann Diorcet's avatar
Yann Diorcet committed
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
		} else {
			helper(argv[0]);
			return -1;
		}
	}

	// Check arguments
	if(suite_name != NULL) {
		if(test_suite_index(suite_name) == -1) {
			fprintf(stderr, "Suite \"%s\" not found\n", suite_name);
			return -1;
		}		
		if(test_name != NULL) {
			if(test_index(suite_name, test_name) == -1) {
				fprintf(stderr, "Test \"%s\" not found\n", test_name);
				return -1;
			}		
jehan's avatar
jehan committed
475 476 477
		}
	}
	
Ghislain MARY's avatar
Ghislain MARY committed
478 479 480 481
	ret = liblinphone_tester_run_tests(suite_name, test_name);
	liblinphone_tester_uninit();
	return ret;
}
jehan's avatar
jehan committed
482
#endif
jehan's avatar
jehan committed
483

484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
#ifdef ANDROID
#include <jni.h>
#include <CUnit/Util.h>
#define CALLBACK_BUFFER_SIZE  1024
static JNIEnv *current_env = NULL;
static jobject current_obj = 0;

void cunit_android_trace_handler(int level, const char *fmt, va_list args) {
	char buffer[CALLBACK_BUFFER_SIZE];
	JNIEnv *env = current_env;
	if(env == NULL) return;
	vsnprintf(buffer, CALLBACK_BUFFER_SIZE, fmt, args);
	jstring javaString = (*env)->NewStringUTF(env, buffer);
	jint javaLevel = level;
	jclass cls = (*env)->GetObjectClass(env, current_obj);
	jmethodID method = (*env)->GetMethodID(env, cls, "printLog", "(ILjava/lang/String;)V");
	(*env)->CallVoidMethod(env, current_obj, method, javaLevel, javaString);
}

Yann Diorcet's avatar
Yann Diorcet committed
503 504
JNIEXPORT 

505 506 507 508 509 510 511 512 513
JNIEXPORT jint JNICALL Java_org_linphone_tester_Tester_run(JNIEnv *env, jobject obj, jobjectArray stringArray) {
	int i, ret;
	int argc = (*env)->GetArrayLength(env, stringArray);
	char **argv = (char**) malloc(sizeof(char*) * argc);

	for (i=0; i<argc; i++) {
		jstring string = (jstring) (*env)->GetObjectArrayElement(env, stringArray, i);
		const char *rawString = (const char *) (*env)->GetStringUTFChars(env, string, 0);
		argv[i] = strdup(rawString);
Yann Diorcet's avatar
Yann Diorcet committed
514
		(*env)->ReleaseStringUTFChars(env, string, rawString);
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
	}
	current_env = env;
	current_obj = obj;
	CU_set_trace_handler(cunit_android_trace_handler);
	ret = main(argc, argv);
	current_env = NULL;
	CU_set_trace_handler(NULL);
	for (i=0; i<argc; i++) {
		free(argv[i]);
	}
	free(argv);
	return ret;
}
#endif