tester.c 21.7 KB
Newer Older
1
 /*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 tester - liblinphone test suite
 Copyright (C) 2013  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 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, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
20
#include "CUnit/TestRun.h"
21
#include "CUnit/Automated.h"
22 23 24 25 26 27
#include "linphonecore.h"
#include "private.h"
#include "liblinphone_tester.h"
#if HAVE_CU_CURSES
#include "CUnit/CUCurses.h"
#endif
28 29 30
#ifdef HAVE_GTK
#include <gtk/gtk.h>
#endif
31 32 33 34 35 36 37 38 39 40 41 42 43 44

static test_suite_t **test_suite = NULL;
static int nb_test_suites = 0;


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

const char* test_domain="sipopen.example.org";
const char* auth_domain="sip.example.org";
const char* test_username="liblinphone_tester";
const char* test_password="secret";
const char* test_route="sip2.linphone.org";
45
int liblinphone_tester_use_log_file=0;
46
static int liblinphone_tester_keep_accounts_flag = 0;
47
static bool_t liblinphone_tester_ipv6_enabled=FALSE;
48
static int manager_count = 0;
49

50 51 52
static const char* liblinphone_tester_xml_file = NULL;
static int      liblinphone_tester_xml_enabled = FALSE;

53 54 55 56 57 58 59 60
#if WINAPI_FAMILY_PHONE_APP
const char *liblinphone_tester_file_prefix="Assets";
#elif defined(__QNX__)
const char *liblinphone_tester_file_prefix="./app/native/assets/";
#else
const char *liblinphone_tester_file_prefix=".";
#endif

61
/* TODO: have the same "static" for QNX and windows as above? */
62 63 64
#ifdef ANDROID
const char *liblinphone_tester_writable_dir_prefix = "/data/data/org.linphone.tester/cache";
#else
65
const char *liblinphone_tester_writable_dir_prefix = ".";
66
#endif
67

68
const char *userhostsfile = "tester_hosts";
69 70 71 72 73 74 75 76 77
static void network_reachable(LinphoneCore *lc, bool_t reachable) {
	stats* counters;
	ms_message("Network reachable [%s]",reachable?"TRUE":"FALSE");
	counters = get_stats(lc);
	if (reachable)
		counters->number_of_NetworkReachableTrue++;
	else
		counters->number_of_NetworkReachableFalse++;
}
78 79 80 81 82 83 84 85 86 87 88 89
void liblinphone_tester_clock_start(MSTimeSpec *start){
	ms_get_cur_time(start);
}

bool_t liblinphone_tester_clock_elapsed(const MSTimeSpec *start, int value_ms){
	MSTimeSpec current;
	ms_get_cur_time(&current);
	if ((((current.tv_sec-start->tv_sec)*1000LL) + ((current.tv_nsec-start->tv_nsec)/1000000LL))>=value_ms)
		return TRUE;
	return FALSE;
}

90 91 92 93
void liblinphone_tester_enable_ipv6(bool_t enabled){
	liblinphone_tester_ipv6_enabled=enabled;
}

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
LinphoneAddress * create_linphone_address(const char * domain) {
	LinphoneAddress *addr = linphone_address_new(NULL);
	CU_ASSERT_PTR_NOT_NULL_FATAL(addr);
	linphone_address_set_username(addr,test_username);
	CU_ASSERT_STRING_EQUAL(test_username,linphone_address_get_username(addr));
	if (!domain) domain= test_route;
	linphone_address_set_domain(addr,domain);
	CU_ASSERT_STRING_EQUAL(domain,linphone_address_get_domain(addr));
	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;
}

static void auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain) {
	stats* counters;
	ms_message("Auth info requested  for user id [%s] at realm [%s]\n"
111 112
			   ,username
			   ,realm);
113 114 115 116 117 118 119
	counters = get_stats(lc);
	counters->number_of_auth_info_requested++;
}



void reset_counters( stats* counters) {
120
	if (counters->last_received_chat_message) linphone_chat_message_unref(counters->last_received_chat_message);
121 122 123
	memset(counters,0,sizeof(stats));
}

124
LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file, void* user_data) {
125
	LinphoneCore* lc;
126 127 128 129 130 131 132
	LpConfig* config = NULL;
	char *filepath         = NULL;
	char *ringpath         = NULL;
	char *ringbackpath     = NULL;
	char *rootcapath       = NULL;
	char *dnsuserhostspath = NULL;
	char *nowebcampath     = NULL;
133 134 135 136

	if (path==NULL) path=".";

	if (file){
137
		filepath = ms_strdup_printf("%s/%s", path, file);
138
		CU_ASSERT_TRUE_FATAL(ortp_file_exist(filepath)==0);
139
		config = lp_config_new_with_factory(NULL,filepath);
140 141 142
	}


143 144 145 146 147 148
	// setup dynamic-path assets
	ringpath         = ms_strdup_printf("%s/sounds/oldphone.wav",path);
	ringbackpath     = ms_strdup_printf("%s/sounds/ringback.wav", path);
	nowebcampath     = ms_strdup_printf("%s/images/nowebcamCIF.jpg", path);
	rootcapath       = ms_strdup_printf("%s/certificates/cn/cafile.pem", path);
	dnsuserhostspath = ms_strdup_printf( "%s/%s", path, userhostsfile);
149 150


151 152 153 154 155 156
	if( config != NULL ) {
		lp_config_set_string(config, "sound", "remote_ring", ringbackpath);
		lp_config_set_string(config, "sound", "local_ring" , ringpath);
		lp_config_set_string(config, "sip",   "root_ca"    , rootcapath);
		lc = linphone_core_new_with_config(v_table, config, user_data);
	} else {
157
		lc = linphone_core_new(v_table,NULL,(filepath!=NULL&&filepath[0]!='\0') ? filepath : NULL, user_data);
158 159 160 161 162

		linphone_core_set_ring(lc, ringpath);
		linphone_core_set_ringback(lc, ringbackpath);
		linphone_core_set_root_ca(lc,rootcapath);
	}
163

164 165
	sal_enable_test_features(lc->sal,TRUE);
	sal_set_dns_user_hosts_file(lc->sal, dnsuserhostspath);
166
	linphone_core_set_static_picture(lc,nowebcampath);
167

168
	linphone_core_enable_ipv6(lc, liblinphone_tester_ipv6_enabled);
169 170 171 172 173 174 175 176 177 178 179

	ms_free(ringpath);
	ms_free(ringbackpath);
	ms_free(nowebcampath);
	ms_free(rootcapath);
	ms_free(dnsuserhostspath);

	if( filepath ) ms_free(filepath);

	if( config ) lp_config_unref(config);

180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
	return lc;
}


bool_t wait_for_until(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value,int timout) {
	MSList* lcs=NULL;
	bool_t result;
	if (lc_1)
		lcs=ms_list_append(lcs,lc_1);
	if (lc_2)
		lcs=ms_list_append(lcs,lc_2);
	result=wait_for_list(lcs,counter,value,timout);
	ms_list_free(lcs);
	return result;
}

bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value) {
197
	return wait_for_until(lc_1, lc_2,counter,value,10000);
198 199 200 201
}

bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms) {
	MSList* iterator;
202
	MSTimeSpec start;
203

204 205 206
	liblinphone_tester_clock_start(&start);
	while ((counter==NULL || *counter<value) && !liblinphone_tester_clock_elapsed(&start,timeout_ms)) {
		for (iterator=lcs;iterator!=NULL;iterator=iterator->next) {
207 208 209 210 211
#ifdef HAVE_GTK
			gdk_threads_enter();
			gtk_main_iteration_do(FALSE);
			gdk_threads_leave();
#endif
212 213
			linphone_core_iterate((LinphoneCore*)(iterator->data));
		}
214 215 216 217 218 219 220 221 222
#ifdef WIN32
		{
			MSG msg;
			while (PeekMessage(&msg, NULL, 0, 0,1)){
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
#endif
223
		ms_usleep(20000);
224 225 226 227 228 229 230 231 232 233
	}
	if(counter && *counter<value) return FALSE;
	else return TRUE;
}

static void set_codec_enable(LinphoneCore* lc,const char* type,int rate,bool_t enable) {
	MSList* codecs=ms_list_copy(linphone_core_get_audio_codecs(lc));
	MSList* codecs_it;
	PayloadType* pt;
	for (codecs_it=codecs;codecs_it!=NULL;codecs_it=codecs_it->next) {
234
		linphone_core_enable_payload_type(lc,(PayloadType*)codecs_it->data,0);
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
	}
	if((pt = linphone_core_find_payload_type(lc,type,rate,1))) {
		linphone_core_enable_payload_type(lc,pt, enable);
	}
	ms_list_free(codecs);
}

static void enable_codec(LinphoneCore* lc,const char* type,int rate) {
	set_codec_enable(lc,type,rate,TRUE);
}
stats * get_stats(LinphoneCore *lc){
	LinphoneCoreManager *manager=(LinphoneCoreManager *)linphone_core_get_user_data(lc);
	return &manager->stat;
}

LinphoneCoreManager *get_manager(LinphoneCore *lc){
	LinphoneCoreManager *manager=(LinphoneCoreManager *)linphone_core_get_user_data(lc);
	return manager;
}

LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_for_proxies) {
	LinphoneCoreManager* mgr= ms_new0(LinphoneCoreManager,1);
	LinphoneProxyConfig* proxy;
	char *rc_path = NULL;
	int proxy_count;

	mgr->v_table.registration_state_changed=registration_state_changed;
	mgr->v_table.auth_info_requested=auth_info_requested;
	mgr->v_table.call_state_changed=call_state_changed;
	mgr->v_table.text_received=text_message_received;
	mgr->v_table.message_received=message_received;
	mgr->v_table.is_composing_received=is_composing_received;
	mgr->v_table.new_subscription_requested=new_subscription_requested;
	mgr->v_table.notify_presence_received=notify_presence_received;
	mgr->v_table.transfer_state_changed=linphone_transfer_state_changed;
	mgr->v_table.info_received=info_message_received;
	mgr->v_table.subscription_state_changed=linphone_subscription_state_change;
	mgr->v_table.notify_received=linphone_notify_received;
	mgr->v_table.publish_state_changed=linphone_publish_state_changed;
	mgr->v_table.configuring_status=linphone_configuration_status;
jehan's avatar
jehan committed
275
	mgr->v_table.call_encryption_changed=linphone_call_encryption_changed;
276
	mgr->v_table.network_reachable=network_reachable;
277
	mgr->v_table.dtmf_received=dtmf_received;
278
	mgr->v_table.call_stats_updated=call_stats_updated;
279 280 281 282

	reset_counters(&mgr->stat);
	if (rc_file) rc_path = ms_strdup_printf("rcfiles/%s", rc_file);
	mgr->lc=configure_lc_from(&mgr->v_table, liblinphone_tester_file_prefix, rc_path, mgr);
283
	linphone_core_manager_check_accounts(mgr);
284 285 286 287 288 289
	/*CU_ASSERT_EQUAL(ms_list_size(linphone_core_get_proxy_config_list(lc)),proxy_count);*/
	if (check_for_proxies && rc_file) /**/
		proxy_count=ms_list_size(linphone_core_get_proxy_config_list(mgr->lc));
	else
		proxy_count=0;

290 291
	manager_count++;

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
292
#if TARGET_OS_IPHONE
293 294
	linphone_core_set_ringer_device( mgr->lc, "AQ: Audio Queue Device");
	linphone_core_set_ringback(mgr->lc, NULL);
295 296
#endif

297
	if( manager_count >= 2){
298
		char hellopath[512];
299
		char *recordpath = ms_strdup_printf("%s/record_for_lc_%p.wav",liblinphone_tester_writable_dir_prefix,mgr->lc);
300 301
		ms_message("Manager for '%s' using files", rc_file ? rc_file : "--");
		linphone_core_use_files(mgr->lc, TRUE);
302 303
		snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", liblinphone_tester_file_prefix);
		linphone_core_set_play_file(mgr->lc,hellopath);
304 305
		linphone_core_set_record_file(mgr->lc,recordpath);
		ms_free(recordpath);
306
	}
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
307

308 309 310
	if (proxy_count){
#define REGISTER_TIMEOUT 20 /* seconds */
		int success = wait_for_until(mgr->lc,NULL,&mgr->stat.number_of_LinphoneRegistrationOk,
Guillaume BIENKOWSKI's avatar
Typo  
Guillaume BIENKOWSKI committed
311
									proxy_count,(REGISTER_TIMEOUT * 1000 * proxy_count));
312 313 314 315
		if( !success ){
			ms_error("Did not register after %d seconds for %d proxies", REGISTER_TIMEOUT, proxy_count);
		}
	}
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
	CU_ASSERT_EQUAL(mgr->stat.number_of_LinphoneRegistrationOk,proxy_count);
	enable_codec(mgr->lc,"PCMU",8000);

	linphone_core_get_default_proxy(mgr->lc,&proxy);
	if (proxy) {
		mgr->identity = linphone_address_new(linphone_proxy_config_get_identity(proxy));
		linphone_address_clean(mgr->identity);
	}
	if (rc_path) ms_free(rc_path);
	return mgr;
}

LinphoneCoreManager* linphone_core_manager_new( const char* rc_file) {
	return linphone_core_manager_new2(rc_file, TRUE);
}

void linphone_core_manager_stop(LinphoneCoreManager *mgr){
	if (mgr->lc) {
		linphone_core_destroy(mgr->lc);
		mgr->lc=NULL;
	}
}

void linphone_core_manager_destroy(LinphoneCoreManager* mgr) {
Simon Morlat's avatar
Simon Morlat committed
340 341 342 343 344 345 346 347
	if (mgr->lc){
		const char *record_file=linphone_core_get_record_file(mgr->lc);
		if (record_file){
			if (CU_get_number_of_failures()>0) {
				ms_message ("Test has failed, keeping recorded file [%s]",record_file);
			} else {
				unlink(record_file);
			}
348
		}
Simon Morlat's avatar
Simon Morlat committed
349
		linphone_core_destroy(mgr->lc);
350
	}
351
	if (mgr->identity) linphone_address_destroy(mgr->identity);
Simon Morlat's avatar
Simon Morlat committed
352
	if (mgr->stat.last_received_chat_message) linphone_chat_message_unref(mgr->stat.last_received_chat_message);
353
	manager_count--;
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 382 383 384 385 386 387 388 389 390 391 392 393 394 395
	ms_free(mgr);
}


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 *));
	}
}

static int run_test_suite(test_suite_t *suite) {
	int i;

	CU_pSuite pSuite = CU_add_suite(suite->name, suite->init_func, suite->cleanup_func);

	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;
}

int liblinphone_tester_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;
		}
	}

	return -1;
}

396 397 398
void liblinphone_tester_list_suites() {
	int j;
	for(j=0;j<liblinphone_tester_nb_test_suites();j++) {
jehan's avatar
jehan committed
399
		liblinphone_tester_fprintf(stdout, "%s\n", liblinphone_tester_test_suite_name(j));
400 401 402
	}
}

403 404 405 406
void liblinphone_tester_list_suite_tests(const char *suite_name) {
	int j;
	for( j = 0; j < liblinphone_tester_nb_tests(suite_name); j++) {
		const char *test_name = liblinphone_tester_test_name(suite_name, j);
jehan's avatar
jehan committed
407
		liblinphone_tester_fprintf(stdout, "%s\n", test_name);
408 409 410
	}
}

411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
int liblinphone_tester_test_index(const char *suite_name, const char *test_name) {
	int j,i;

	j = liblinphone_tester_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;
}

int liblinphone_tester_nb_test_suites(void) {
	return nb_test_suites;
}

int liblinphone_tester_nb_tests(const char *suite_name) {
	int i = liblinphone_tester_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 = liblinphone_tester_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;
}

448 449 450 451
void liblinphone_tester_set_fileprefix(const char* file_prefix){
	liblinphone_tester_file_prefix = file_prefix;
}

452 453 454 455
void liblinphone_tester_set_writable_dir_prefix(const char* writable_dir_prefix){
	liblinphone_tester_writable_dir_prefix = writable_dir_prefix;
}

456

457 458 459
void liblinphone_tester_init(void) {
	add_test_suite(&setup_test_suite);
	add_test_suite(&register_test_suite);
460
	add_test_suite(&offeranswer_test_suite);
461 462 463 464 465 466 467 468 469 470
	add_test_suite(&call_test_suite);
	add_test_suite(&message_test_suite);
	add_test_suite(&presence_test_suite);
#ifdef UPNP
	add_test_suite(&upnp_test_suite);
#endif
	add_test_suite(&stun_test_suite);
	add_test_suite(&event_test_suite);
	add_test_suite(&flexisip_test_suite);
	add_test_suite(&remote_provisioning_test_suite);
471
	add_test_suite(&quality_reporting_test_suite);
472
	add_test_suite(&log_collection_test_suite);
473
	add_test_suite(&transport_test_suite);
474
	add_test_suite(&player_test_suite);
475
	add_test_suite(&dtmf_test_suite);
476 477 478
#if defined(VIDEO_ENABLED) && defined(HAVE_GTK)
	add_test_suite(&video_test_suite);
#endif
jehan's avatar
jehan committed
479
	add_test_suite(&multicast_call_test_suite);
480 481 482 483 484 485 486 487 488 489
}

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

490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
/*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;
	if (pFailure) {
		if (liblinphone_tester_use_log_file) ms_warning("Suite [%s], Test [%s] had failures:", pSuite->pName, pTest->pName);
		liblinphone_tester_fprintf(stdout,"\nSuite [%s], Test [%s] had failures:", pSuite->pName, pTest->pName);
	} else {
		if (liblinphone_tester_use_log_file) ms_warning(" passed");
		liblinphone_tester_fprintf(stdout," passed");
	}
      for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) {
    	  if (liblinphone_tester_use_log_file) ms_warning("\n    %d. %s:%u  - %s", i,
            (NULL != pFailure->strFileName) ? pFailure->strFileName : "",
            pFailure->uiLineNumber,
            (NULL != pFailure->strCondition) ? pFailure->strCondition : "");
    	  liblinphone_tester_fprintf(stdout,"\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) {
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
517 518 519 520 521 522
  	char * results = CU_get_run_results_string();
  	if (liblinphone_tester_use_log_file) {
  		ms_warning("\n\n %s", results);
  	}
	liblinphone_tester_fprintf(stdout,"\n\n %s",results);
	ms_free(results);
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
}

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

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

static void test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite) {
	if (liblinphone_tester_use_log_file) ms_warning("Suite [%s] Test [%s]", pSuite->pName,pTest->pName);
	liblinphone_tester_fprintf(stdout,"\nSuite [%s] Test [%s]\n", pSuite->pName,pTest->pName);
}
static void test_suite_start_message_handler(const CU_pSuite pSuite) {
	if (liblinphone_tester_use_log_file) ms_warning("Suite [%s]", pSuite->pName);
	liblinphone_tester_fprintf(stdout,"\nSuite [%s]", pSuite->pName);
}

544 545 546 547 548 549 550 551 552 553 554
int liblinphone_tester_run_tests(const char *suite_name, const char *test_name) {
	int i;
	int ret;
	/* initialize the CUnit test registry */
	if (CUE_SUCCESS != CU_initialize_registry())
		return CU_get_error();

	for (i = 0; i < liblinphone_tester_nb_test_suites(); i++) {
		run_test_suite(test_suite[i]);
	}

555 556 557 558 559 560 561 562
	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);
	CU_set_suite_start_handler(test_suite_start_message_handler);


563 564
	if( liblinphone_tester_xml_file != NULL ){
		CU_set_output_filename(liblinphone_tester_xml_file);
565
	}
566 567 568 569 570 571 572 573
	if( liblinphone_tester_xml_enabled != 0 ){
		CU_automated_run_tests();
	} else {

#if !HAVE_CU_GET_SUITE
		if( suite_name ){
			ms_warning("Tester compiled without CU_get_suite() function, running all tests instead of suite '%s'\n", suite_name);
		}
574
#else
575 576 577 578 579 580 581 582 583 584 585
		if (suite_name){
			CU_pSuite suite;
			suite=CU_get_suite(suite_name);
			if (!suite) {
				ms_error("Could not find suite '%s'. Available suites are:", suite_name);
				liblinphone_tester_list_suites();
				return -1;
			} else if (test_name) {
				CU_pTest test=CU_get_test_by_name(test_name, suite);
				if (!test) {
					ms_error("Could not find test '%s' in suite '%s'. Available tests are:", test_name, suite_name);
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
586
					// do not use suite_name here, since this method is case sensitive
587 588 589 590 591 592
					liblinphone_tester_list_suite_tests(suite->pName);
					return -2;
				} else {
					CU_ErrorCode err= CU_run_test(suite, test);
					if (err != CUE_SUCCESS) ms_error("CU_basic_run_test error %d", err);
				}
593
			} else {
594
				CU_run_suite(suite);
595
			}
596 597 598 599
		}
		else
#endif
		{
600 601 602 603 604 605 606 607 608 609 610
#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_run_all_tests();
			}
611 612
		}

613
	}
614
	ret=CU_get_number_of_tests_failed()!=0;
615 616 617 618

	/* Redisplay list of failed tests on end */
	if (CU_get_number_of_failure_records()){
		CU_basic_show_failures(CU_get_failure_list());
619
		liblinphone_tester_fprintf(stdout,"\n");
620 621
	}

622
	CU_cleanup_registry();
623 624 625 626

	if( liblinphone_tester_keep_accounts_flag == 0){
		liblinphone_tester_clear_accounts();
	}
627 628
	return ret;
}
629

jehan's avatar
jehan committed
630
int  liblinphone_tester_fprintf(FILE * stream, const char * format, ...) {
631
	int result;
jehan's avatar
jehan committed
632 633 634
	va_list args;
	va_start(args, format);
#ifndef ANDROID
jehan's avatar
jehan committed
635 636
	result = vfprintf(stream,format,args);
	fflush(stream);
jehan's avatar
jehan committed
637 638
#else
	/*used by liblinphone tester to retrieve suite list*/
jehan's avatar
jehan committed
639
	result = 0;
640
	cunit_android_trace_handler(stream == stderr, format, args);
jehan's avatar
jehan committed
641 642 643 644
#endif
	va_end(args);
	return result;
}
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663

int liblinphone_tester_ipv6_available(void){
	struct addrinfo *ai=belle_sip_ip_address_to_addrinfo(AF_INET6,"2a01:e00::2",53);
	if (ai){
		struct sockaddr_storage ss;
		struct addrinfo src;
		socklen_t slen=sizeof(ss);
		char localip[128];
		int port=0;
		belle_sip_get_src_addr_for(ai->ai_addr,ai->ai_addrlen,(struct sockaddr*) &ss,&slen,4444);
		src.ai_addr=(struct sockaddr*) &ss;
		src.ai_addrlen=slen;
		belle_sip_addrinfo_to_ip(&src,localip, sizeof(localip),&port);
		freeaddrinfo(ai);
		return strcmp(localip,"::1")!=0;
	}
	return FALSE;
}

664 665 666 667 668 669 670 671
void liblinphone_tester_keep_accounts( int keep ){
	liblinphone_tester_keep_accounts_flag = keep;
}

void liblinphone_tester_clear_accounts(void){
	account_manager_destroy();
}

672 673 674 675 676 677 678 679 680 681 682 683 684 685
void liblinphone_tester_enable_xml( bool_t enable ){
	liblinphone_tester_xml_enabled = enable;
}

void liblinphone_tester_set_xml_output(const char *xml_path ) {
	liblinphone_tester_xml_file = xml_path;
}

const char* liblinphone_tester_get_xml_output( void ) {
	return liblinphone_tester_xml_file;
}



686