diff --git a/configure.ac b/configure.ac
index 3495d5f59..3142b0ffd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,7 +30,7 @@ AC_SUBST(LINPHONE_VERSION)
AC_MSG_NOTICE([$PACKAGE_NAME-$PACKAGE_VERSION A full featured audio/video sip phone.])
AC_MSG_NOTICE([licensed under the terms of the General Public License (GPL)])
-AM_INIT_AUTOMAKE([1.9 tar-pax])
+AM_INIT_AUTOMAKE([1.9 tar-pax subdir-objects])
AC_SUBST([LIBTOOL_DEPS])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
AC_SUBST([docdir], [${datadir}/doc])
diff --git a/mediastreamer2 b/mediastreamer2
index a56f04bfa..a9374f30b 160000
--- a/mediastreamer2
+++ b/mediastreamer2
@@ -1 +1 @@
-Subproject commit a56f04bfa4619186ba51ac8d3d2d73c942ee4fcf
+Subproject commit a9374f30b2e5098e646608b0562e50a156fba820
diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt
index 12454c80f..e9583b955 100644
--- a/tester/CMakeLists.txt
+++ b/tester/CMakeLists.txt
@@ -26,6 +26,8 @@ endif()
find_package(GTK2 2.18 COMPONENTS gtk)
set(SOURCE_FILES
+ common/bc_tester_utils.c
+ common/bc_tester_utils.h
accountmanager.c
call_tester.c
dtmf_tester.c
@@ -50,6 +52,8 @@ set(SOURCE_FILES
video_tester.c
)
+add_definitions(-DBC_CONFIG_FILE="config.h")
+
add_executable(liblinphone_tester ${SOURCE_FILES})
set_target_properties(liblinphone_tester PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(liblinphone_tester PUBLIC ${CUNIT_INCLUDE_DIRS})
diff --git a/tester/Makefile.am b/tester/Makefile.am
index 9e5731950..ece11eda7 100644
--- a/tester/Makefile.am
+++ b/tester/Makefile.am
@@ -10,33 +10,35 @@ liblinphone_HEADERS = liblinphone_tester.h
lib_LTLIBRARIES = liblinphonetester.la
-liblinphonetester_la_SOURCES = tester.c \
- setup_tester.c \
- register_tester.c \
- message_tester.c \
+liblinphonetester_la_SOURCES = \
+ accountmanager.c \
call_tester.c \
- multicast_call_tester.c \
- presence_tester.c \
- upnp_tester.c \
+ dtmf_tester.c \
eventapi_tester.c \
flexisip_tester.c \
- stun_tester.c \
- remote_provisioning_tester.c \
- quality_reporting_tester.c \
log_collection_tester.c \
- transport_tester.c \
- player_tester.c \
- dtmf_tester.c \
- accountmanager.c \
+ message_tester.c \
+ multi_call.c \
+ multicast_call_tester.c \
offeranswer_tester.c \
+ player_tester.c \
+ presence_tester.c \
+ quality_reporting_tester.c \
+ register_tester.c \
+ remote_provisioning_tester.c \
+ setup_tester.c \
+ stun_tester.c \
+ transport_tester.c \
+ tester.c \
+ upnp_tester.c \
video_tester.c \
- multi_call.c
+ common/bc_tester_utils.c common/bc_tester_utils.h
liblinphonetester_la_LDFLAGS= -no-undefined
liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS)
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/coreapi
-AM_CFLAGS = $(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS)
+AM_CFLAGS = -DBC_CONFIG_FILE=\"config.h\" $(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS)
if BUILD_GTK_UI
diff --git a/tester/accountmanager.c b/tester/accountmanager.c
index 80bc7942e..d46c2064d 100644
--- a/tester/accountmanager.c
+++ b/tester/accountmanager.c
@@ -33,7 +33,7 @@ typedef struct _Account Account;
Account *account_new(LinphoneAddress *identity, const char *unique_id){
char *modified_username;
Account *obj=ms_new0(Account,1);
-
+
/* we need to inhibit leak detector because the two LinphoneAddress will remain behond the scope of the test being run */
belle_sip_object_inhibit_leak_detector(TRUE);
obj->identity=linphone_address_clone(identity);
@@ -82,7 +82,7 @@ void account_manager_destroy(void){
Account *account_manager_get_account(AccountManager *m, const LinphoneAddress *identity){
MSList *it;
-
+
for(it=m->accounts;it!=NULL;it=it->next){
Account *a=(Account*)it->data;
if (linphone_address_weak_equal(a->identity,identity)){
@@ -120,15 +120,15 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf
char *tmp;
LinphoneAddress *server_addr;
LCSipTransports tr;
-
+
vtable.registration_state_changed=account_created_on_server_cb;
vtable.auth_info_requested=account_created_auth_requested_cb;
- lc=configure_lc_from(&vtable,liblinphone_tester_file_prefix,NULL,account);
+ lc=configure_lc_from(&vtable,bc_tester_read_dir_prefix,NULL,account);
tr.udp_port=LC_SIP_TRANSPORT_RANDOM;
tr.tcp_port=LC_SIP_TRANSPORT_RANDOM;
tr.tls_port=LC_SIP_TRANSPORT_RANDOM;
linphone_core_set_sip_transports(lc,&tr);
-
+
cfg=linphone_core_create_proxy_config(lc);
linphone_address_set_secure(tmp_identity, FALSE);
linphone_address_set_password(tmp_identity,account->password);
@@ -137,7 +137,7 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf
linphone_proxy_config_set_identity(cfg,tmp);
ms_free(tmp);
linphone_address_unref(tmp_identity);
-
+
server_addr=linphone_address_new(linphone_proxy_config_get_server_addr(refcfg));
linphone_address_set_secure(server_addr, FALSE);
linphone_address_set_transport(server_addr,LinphoneTransportTcp); /*use tcp for account creation, we may not have certificates configured at this stage*/
@@ -147,9 +147,9 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf
ms_free(tmp);
linphone_address_unref(server_addr);
linphone_proxy_config_set_expires(cfg,3600);
-
+
linphone_core_add_proxy_config(lc,cfg);
-
+
if (wait_for_until(lc,NULL,&account->auth_requested,1,10000)==FALSE){
ms_fatal("Account for %s could not be created on server.", linphone_proxy_config_get_identity(refcfg));
}
@@ -161,13 +161,13 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf
linphone_address_unref(tmp_identity);
ms_free(tmp);
linphone_proxy_config_done(cfg);
-
+
ai=linphone_auth_info_new(linphone_address_get_username(account->modified_identity),
NULL,
account->password,NULL,NULL,linphone_address_get_domain(account->modified_identity));
linphone_core_add_auth_info(lc,ai);
linphone_auth_info_destroy(ai);
-
+
if (wait_for_until(lc,NULL,&account->created,1,3000)==FALSE){
ms_fatal("Account for %s is not working on server.", linphone_proxy_config_get_identity(refcfg));
}
@@ -187,7 +187,7 @@ LinphoneAddress *account_manager_check_account(AccountManager *m, LinphoneProxyC
LinphoneAuthInfo *ai;
char *tmp;
bool_t create_account=FALSE;
-
+
if (!account){
account=account_new(id_addr,m->unique_id);
ms_message("No account for %s exists, going to create one.",identity);
@@ -199,7 +199,7 @@ LinphoneAddress *account_manager_check_account(AccountManager *m, LinphoneProxyC
tmp=linphone_address_as_string(id_addr);
linphone_proxy_config_set_identity(cfg,tmp);
ms_free(tmp);
-
+
if (create_account){
account_create_on_server(account,cfg);
}
@@ -208,7 +208,7 @@ LinphoneAddress *account_manager_check_account(AccountManager *m, LinphoneProxyC
account->password,NULL,NULL,linphone_address_get_domain(account->modified_identity));
linphone_core_add_auth_info(lc,ai);
linphone_auth_info_destroy(ai);
-
+
linphone_address_unref(id_addr);
return account->modified_identity;
}
diff --git a/tester/call_tester.c b/tester/call_tester.c
index 50effd1eb..61708877a 100644
--- a/tester/call_tester.c
+++ b/tester/call_tester.c
@@ -1650,8 +1650,8 @@ static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* ma
}
if (mode==LinphoneMediaEncryptionDTLS) { /* for DTLS we must access certificates or at least have a directory to store them */
- marie->lc->user_certificates_path = ms_strdup_printf("%s/certificates/marie", liblinphone_tester_file_prefix);
- pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", liblinphone_tester_file_prefix);
+ marie->lc->user_certificates_path = ms_strdup_printf("%s/certificates/marie", bc_tester_read_dir_prefix);
+ pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", bc_tester_read_dir_prefix);
}
linphone_core_set_media_encryption(marie->lc,mode);
@@ -2089,12 +2089,12 @@ static void call_with_file_player(void) {
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
LinphonePlayer *player;
char hellopath[256];
- char *recordpath = create_filepath(liblinphone_tester_writable_dir_prefix, "record", "wav");
+ char *recordpath = create_filepath(bc_tester_writable_dir_prefix, "record", "wav");
/*make sure the record file doesn't already exists, otherwise this test will append new samples to it*/
unlink(recordpath);
- snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", liblinphone_tester_file_prefix);
+ snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", bc_tester_read_dir_prefix);
/*caller uses files instead of soundcard in order to avoid mixing soundcard input with file played using call's player*/
linphone_core_use_files(marie->lc,TRUE);
@@ -2167,12 +2167,12 @@ static void call_with_mkv_file_player(void) {
ms_warning("Test skipped, no mkv support.");
goto end;
}
- recordpath = create_filepath(liblinphone_tester_writable_dir_prefix, "record", "wav");
+ recordpath = create_filepath(bc_tester_writable_dir_prefix, "record", "wav");
/*make sure the record file doesn't already exists, otherwise this test will append new samples to it*/
unlink(recordpath);
- snprintf(hellowav,sizeof(hellowav), "%s/sounds/hello8000_mkv_ref.wav", liblinphone_tester_file_prefix);
- snprintf(hellomkv,sizeof(hellomkv), "%s/sounds/hello8000.mkv", liblinphone_tester_file_prefix);
+ snprintf(hellowav,sizeof(hellowav), "%s/sounds/hello8000_mkv_ref.wav", bc_tester_read_dir_prefix);
+ snprintf(hellomkv,sizeof(hellomkv), "%s/sounds/hello8000.mkv", bc_tester_read_dir_prefix);
/*caller uses files instead of soundcard in order to avoid mixing soundcard input with file played using call's player*/
linphone_core_use_files(marie->lc,TRUE);
@@ -2250,8 +2250,8 @@ void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_r
linphone_core_set_media_encryption(marie->lc,mode);
linphone_core_set_media_encryption(pauline->lc,mode);
if (mode==LinphoneMediaEncryptionDTLS) { /* for DTLS we must access certificates or at least have a directory to store them */
- marie->lc->user_certificates_path = ms_strdup_printf("%s/certificates/marie", liblinphone_tester_file_prefix);
- pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", liblinphone_tester_file_prefix);
+ marie->lc->user_certificates_path = ms_strdup_printf("%s/certificates/marie", bc_tester_read_dir_prefix);
+ pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", bc_tester_read_dir_prefix);
}
linphone_core_set_firewall_policy(marie->lc,policy);
@@ -2883,7 +2883,7 @@ static void record_call(const char *filename, bool_t enableVideo) {
formats = linphone_core_get_supported_file_formats(marie->lc);
for(i=0, format = formats[0]; format != NULL; i++, format = formats[i]) {
- filepath = create_filepath(liblinphone_tester_writable_dir_prefix, filename, format);
+ filepath = create_filepath(bc_tester_writable_dir_prefix, filename, format);
remove(filepath);
linphone_call_params_set_record_file(marieParams, filepath);
CU_ASSERT_TRUE(call_succeeded = call_with_params(marie, pauline, marieParams, paulineParams));
@@ -2921,7 +2921,7 @@ static void video_call_snapshot(void) {
LinphoneCallParams *marieParams = linphone_core_create_default_call_parameters(marie->lc);
LinphoneCallParams *paulineParams = linphone_core_create_default_call_parameters(pauline->lc);
LinphoneCall *callInst = NULL;
- char *filename = create_filepath(liblinphone_tester_writable_dir_prefix, "snapshot", "jpeg");
+ char *filename = create_filepath(bc_tester_writable_dir_prefix, "snapshot", "jpeg");
int dummy = 0;
bool_t call_succeeded = FALSE;
@@ -3373,8 +3373,8 @@ static void call_with_generic_cn(void) {
LinphoneCoreManager* marie;
LinphoneCoreManager* pauline;
LinphoneCall *pauline_call;
- char *audio_file_with_silence=ms_strdup_printf("%s/%s",liblinphone_tester_file_prefix,"sounds/ahbahouaismaisbon.wav");
- char *recorded_file=ms_strdup_printf("%s/%s",liblinphone_tester_writable_dir_prefix,"result.wav");
+ char *audio_file_with_silence=ms_strdup_printf("%s/%s",bc_tester_read_dir_prefix,"sounds/ahbahouaismaisbon.wav");
+ char *recorded_file=ms_strdup_printf("%s/%s",bc_tester_writable_dir_prefix,"result.wav");
belle_sip_object_enable_leak_detector(TRUE);
begin=belle_sip_object_get_object_count();
diff --git a/tester/liblinphone_completion b/tester/common/bc_tester_completion
similarity index 100%
rename from tester/liblinphone_completion
rename to tester/common/bc_tester_completion
diff --git a/tester/common/bc_tester_utils.c b/tester/common/bc_tester_utils.c
new file mode 100644
index 000000000..25e92143f
--- /dev/null
+++ b/tester/common/bc_tester_utils.c
@@ -0,0 +1,357 @@
+/*
+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 .
+*/
+
+
+/* this must be provided at compile time*/
+#include BC_CONFIG_FILE
+
+#include "bc_tester_utils.h"
+
+#include
+#include
+#include "CUnit/Automated.h"
+
+#if WINAPI_FAMILY_PHONE_APP
+const char *bc_tester_read_dir_prefix="Assets";
+#elif defined(__QNX__)
+const char *bc_tester_read_dir_prefix="./app/native/assets/";
+#else
+const char *bc_tester_read_dir_prefix=".";
+#endif
+
+/* TODO: have the same "static" for QNX and windows as above? */
+#ifdef ANDROID
+const char *bc_tester_writable_dir_prefix = "/data/data/org.linphone.tester/cache";
+#else
+const char *bc_tester_writable_dir_prefix = ".";
+#endif
+
+static test_suite_t **test_suite = NULL;
+static int nb_test_suites = 0;
+
+#ifdef HAVE_CU_CURSES
+#include "CUnit/CUCurses.h"
+static unsigned char curses = 0;
+#endif
+
+char* xml_file = "CUnitAutomated-Results.xml";
+int xml_enabled = 0;
+char * suite_name;
+char * test_name;
+void (*tester_printf_va)(int level, const char *fmt, va_list args);
+int verbosity_info;
+int verbosity_error;
+
+static void tester_printf(int level, const char *fmt, ...) {
+ va_list args;
+ va_start (args, fmt);
+ tester_printf_va(level, fmt, args);
+ va_end (args);
+}
+
+static int tester_run_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;
+}
+
+const char * tester_test_suite_name(int suite_index) {
+ if (suite_index >= nb_test_suites) return NULL;
+ return test_suite[suite_index]->name;
+}
+
+static int tester_test_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))) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+const char * tester_test_name(const char *suite_name, int test_index) {
+ int suite_index = tester_test_suite_index(suite_name);
+ if ((suite_index < 0) || (suite_index >= 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;
+}
+
+static int tester_nb_tests(const char *suite_name) {
+ int i = tester_test_suite_index(suite_name);
+ if (i < 0) return 0;
+ return test_suite[i]->nb_tests;
+}
+
+static void tester_list_suites() {
+ int j;
+ for(j=0;jpName);
+}
+
+static void suite_cleanup_failure_message_handler(const CU_pSuite pSuite) {
+ tester_printf(verbosity_error,"Suite cleanup failed for [%s].", pSuite->pName);
+}
+
+#ifdef HAVE_CU_GET_SUITE
+static void suite_start_message_handler(const CU_pSuite pSuite) {
+ tester_printf(verbosity_info,"Suite [%s] started\n", pSuite->pName);
+}
+static void suite_complete_message_handler(const CU_pSuite pSuite, const CU_pFailureRecord pFailure) {
+ tester_printf(verbosity_info,"Suite [%s] ended\n", pSuite->pName);
+}
+
+static void test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite) {
+ tester_printf(verbosity_info,"Suite [%s] Test [%s] started", pSuite->pName,pTest->pName);
+}
+
+/*derivated from cunit*/
+static void test_complete_message_handler(const CU_pTest pTest,
+ const CU_pSuite pSuite,
+ const CU_pFailureRecord pFailureList) {
+ int i;
+ char * result = malloc(sizeof(char)*2048);//not very pretty but...
+ CU_pFailureRecord pFailure = pFailureList;
+ sprintf(result, "Suite [%s] Test [%s]", pSuite->pName, pTest->pName);
+ if (pFailure) {
+ strncat(result, " failed:", strlen(" failed:"));
+ for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) {
+ sprintf(result, "%s\n %d. %s:%u - %s", result, i,
+ (NULL != pFailure->strFileName) ? pFailure->strFileName : "",
+ pFailure->uiLineNumber,
+ (NULL != pFailure->strCondition) ? pFailure->strCondition : "");
+ }
+ } else {
+ strncat(result, " passed", strlen(" passed"));
+ }
+ tester_printf(verbosity_info,"%s\n", result);
+ free(result);
+}
+#endif
+
+static int tester_run_tests(const char *suite_name, const char *test_name) {
+ int i;
+
+ /* initialize the CUnit test registry */
+ if (CUE_SUCCESS != CU_initialize_registry())
+ return CU_get_error();
+
+ for (i = 0; i < nb_test_suites; i++) {
+ tester_run_suite(test_suite[i]);
+ }
+#ifdef HAVE_CU_GET_SUITE
+ CU_set_suite_start_handler(suite_start_message_handler);
+ CU_set_suite_complete_handler(suite_complete_message_handler);
+ CU_set_test_start_handler(test_start_message_handler);
+ CU_set_test_complete_handler(test_complete_message_handler);
+#endif
+ CU_set_all_test_complete_handler(all_complete_message_handler);
+ CU_set_suite_init_failure_handler(suite_init_failure_message_handler);
+ CU_set_suite_cleanup_failure_handler(suite_cleanup_failure_message_handler);
+
+ if( xml_enabled != 0 ){
+ CU_automated_run_tests();
+ } else {
+
+#ifndef HAVE_CU_GET_SUITE
+ if( suite_name ){
+ tester_printf(verbosity_info, "Tester compiled without CU_get_suite() function, running all tests instead of suite '%s'", suite_name);
+ }
+#else
+ if (suite_name){
+ CU_pSuite suite;
+ suite=CU_get_suite(suite_name);
+ if (!suite) {
+ tester_printf(verbosity_error, "Could not find suite '%s'. Available suites are:", suite_name);
+ tester_list_suites();
+ return -1;
+ } else if (test_name) {
+ CU_pTest test=CU_get_test_by_name(test_name, suite);
+ if (!test) {
+ tester_printf(verbosity_error, "Could not find test '%s' in suite '%s'. Available tests are:", test_name, suite_name);
+ // do not use suite_name here, since this method is case sensitive
+ tester_list_suite_tests(suite->pName);
+ return -2;
+ } else {
+ CU_ErrorCode err= CU_run_test(suite, test);
+ if (err != CUE_SUCCESS) tester_printf(verbosity_error, "CU_basic_run_test error %d", err);
+ }
+ } else {
+ CU_run_suite(suite);
+ }
+ }
+ else
+#endif
+ {
+#ifdef 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();
+ }
+ }
+ }
+ return CU_get_number_of_tests_failed()!=0;
+
+}
+
+
+void bc_tester_helper(const char *name, const char* additionnal_helper) {
+ fprintf(stdout,"%s --help\n"
+ "\t\t\t--list-suites\n"
+ "\t\t\t--list-tests \n"
+ "\t\t\t--suite \n"
+ "\t\t\t--test \n"
+#ifdef HAVE_CU_CURSES
+ "\t\t\t--curses\n"
+#endif
+ "\t\t\t--xml\n"
+ "\t\t\t--xml-file \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) {
+ tester_printf_va = ftester_printf;
+ verbosity_error = iverbosity_error;
+ verbosity_info = iverbosity_info;
+}
+
+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){
+ CHECK_ARG("--test", ++i, argc);
+ test_name=argv[i];
+ }else if (strcmp(argv[i],"--suite")==0){
+ CHECK_ARG("--suite", ++i, argc);
+ suite_name=argv[i];
+ } else if (strcmp(argv[i],"--list-suites")==0){
+ tester_list_suites();
+ return 0;
+ } else if (strcmp(argv[i],"--list-tests")==0){
+ CHECK_ARG("--list-tests", ++i, argc);
+ suite_name = argv[i];
+ tester_list_suite_tests(suite_name);
+ return 0;
+ } else if (strcmp(argv[i], "--xml-file") == 0){
+ CHECK_ARG("--xml-file", ++i, argc);
+ xml_file = argv[i];
+ xml_enabled = 1;
+ } else if (strcmp(argv[i], "--xml") == 0){
+ xml_enabled = 1;
+ }else {
+ fprintf(stderr, "Unknown option \"%s\"\n", argv[i]);
+ return -1;
+ }
+
+ if( xml_enabled && (suite_name || test_name) ){
+ fprintf(stderr, "Cannot use both XML and specific test suite\n");
+ return -1;
+ }
+
+ /* returns number of arguments read + 1 */
+ return i - argid + 1;
+}
+
+int bc_tester_start() {
+ int ret;
+ if( xml_enabled ){
+ char * xml_tmp_file = malloc(sizeof(char) * (strlen(xml_file) + strlen(".tmp") + 1));
+ sprintf(xml_tmp_file, "%s.tmp", xml_file);
+ CU_set_output_filename(xml_tmp_file);
+ free(xml_tmp_file);
+ }
+
+ ret = tester_run_tests(suite_name, test_name);
+
+ return ret;
+}
+void bc_tester_add_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 *));
+ }
+}
+
+void bc_tester_uninit() {
+ /* Redisplay list of failed tests on end */
+ if (CU_get_number_of_failure_records()){
+ CU_basic_show_failures(CU_get_failure_list());
+ tester_printf(verbosity_info,""); /*add missing final newline*/
+ }
+ CU_cleanup_registry();
+
+ if( xml_enabled ){
+ /*create real xml file only if tester did not crash*/
+ char * xml_tmp_file = malloc(sizeof(char) * (strlen(xml_file) + strlen(".tmp-Results.xml") + 1));
+ sprintf(xml_tmp_file, "%s.tmp-Results.xml", xml_file);
+ rename(xml_tmp_file, xml_file);
+ free(xml_tmp_file);
+ }
+
+ if (test_suite != NULL) {
+ free(test_suite);
+ test_suite = NULL;
+ nb_test_suites = 0;
+ }
+}
diff --git a/tester/common/bc_tester_utils.h b/tester/common/bc_tester_utils.h
new file mode 100644
index 000000000..a8b952d02
--- /dev/null
+++ b/tester/common/bc_tester_utils.h
@@ -0,0 +1,68 @@
+/*
+ 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 .
+*/
+
+
+#ifndef TESTER_UTILS_H
+#define TESTER_UTILS_H
+
+#include "CUnit/Basic.h"
+#include
+
+extern const char *bc_tester_read_dir_prefix;
+extern const char *bc_tester_writable_dir_prefix;
+
+typedef void (*test_function_t)(void);
+typedef int (*test_suite_function_t)(const char *name);
+
+typedef struct {
+ const char *name;
+ test_function_t func;
+} test_t;
+
+typedef struct {
+ const char *name;
+ CU_InitializeFunc init_func;
+ CU_CleanupFunc cleanup_func;
+ int nb_tests;
+ test_t *tests;
+} test_suite_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define CHECK_ARG(argument, index, argc) \
+if(index >= argc) { \
+fprintf(stderr, "Missing argument for \"%s\"\n", argument); \
+return -1; \
+} \
+
+void bc_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list args)
+ , int verbosity_info, int verbosity_error);
+void bc_tester_helper(const char *name, const char* additionnal_helper);
+int bc_tester_parse_args(int argc, char** argv, int argid);
+int bc_tester_start();
+void bc_tester_add_suite(test_suite_t *suite);
+void bc_tester_uninit();
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c
index a4f19aee6..5c7b9b11d 100644
--- a/tester/flexisip_tester.c
+++ b/tester/flexisip_tester.c
@@ -31,7 +31,7 @@ static void subscribe_forking(void) {
LinphoneEvent *lev;
int expires= 600;
MSList* lcs=ms_list_append(NULL,marie->lc);
-
+
lcs=ms_list_append(lcs,pauline->lc);
lcs=ms_list_append(lcs,pauline2->lc);
@@ -39,9 +39,9 @@ static void subscribe_forking(void) {
linphone_content_set_type(content,"application");
linphone_content_set_subtype(content,"somexml");
linphone_content_set_buffer(content, liblinphone_tester_get_subscribe_content(), strlen(liblinphone_tester_get_subscribe_content()));
-
+
lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,content);
-
+
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline2->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000));
@@ -67,10 +67,10 @@ static void message_forking(void) {
char* to = linphone_address_as_string(marie->identity);
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
-
+
lcs=ms_list_append(lcs,pauline->lc);
lcs=ms_list_append(lcs,marie2->lc);
-
+
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,1000));
@@ -92,15 +92,15 @@ static void message_forking_with_unreachable_recipients(void) {
char* to = linphone_address_as_string(marie->identity);
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
-
+
lcs=ms_list_append(lcs,pauline->lc);
lcs=ms_list_append(lcs,marie2->lc);
lcs=ms_list_append(lcs,marie3->lc);
-
+
/*marie2 and marie3 go offline*/
linphone_core_set_network_reachable(marie2->lc,FALSE);
linphone_core_set_network_reachable(marie3->lc,FALSE);
-
+
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,1000));
@@ -110,14 +110,14 @@ static void message_forking_with_unreachable_recipients(void) {
/*marie 2 goes online */
linphone_core_set_network_reachable(marie2->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000));
-
+
/*wait a long time so that all transactions are expired*/
wait_for_list(lcs,NULL,0,32000);
-
+
/*marie 3 goes online now*/
linphone_core_set_network_reachable(marie3->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneMessageReceived,1,3000));
-
+
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline);
@@ -134,40 +134,40 @@ static void message_forking_with_all_recipients_unreachable(void) {
char* to = linphone_address_as_string(marie->identity);
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
-
+
lcs=ms_list_append(lcs,pauline->lc);
lcs=ms_list_append(lcs,marie2->lc);
lcs=ms_list_append(lcs,marie3->lc);
-
+
/*All marie's device go offline*/
linphone_core_set_network_reachable(marie->lc,FALSE);
linphone_core_set_network_reachable(marie2->lc,FALSE);
linphone_core_set_network_reachable(marie3->lc,FALSE);
-
+
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
-
+
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageInProgress,1,5000));
/*flexisip will accept the message with 202 after 16 seconds*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,18000));
CU_ASSERT_TRUE( marie->stat.number_of_LinphoneMessageReceived==0);
CU_ASSERT_TRUE( marie2->stat.number_of_LinphoneMessageReceived==0);
CU_ASSERT_TRUE( marie3->stat.number_of_LinphoneMessageReceived==0);
-
+
/*marie 1 goes online */
linphone_core_set_network_reachable(marie->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
-
+
/*marie 2 goes online */
linphone_core_set_network_reachable(marie2->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000));
-
+
/*wait a long time so that all transactions are expired*/
wait_for_list(lcs,NULL,0,32000);
-
+
/*marie 3 goes online now*/
linphone_core_set_network_reachable(marie3->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneMessageReceived,1,3000));
-
+
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline);
@@ -181,16 +181,16 @@ static void call_forking(void){
LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc");
MSList* lcs=ms_list_append(NULL,pauline->lc);
-
+
lcs=ms_list_append(lcs,marie->lc);
lcs=ms_list_append(lcs,marie2->lc);
lcs=ms_list_append(lcs,marie3->lc);
-
+
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
-
+
linphone_core_invite_address(pauline->lc,marie->identity);
/*pauline should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
@@ -198,22 +198,22 @@ static void call_forking(void){
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,3000));
-
+
/*marie accepts the call on its first device*/
linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000));
-
+
/*other devices should stop ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
-
+
linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
-
+
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
@@ -227,38 +227,38 @@ static void call_forking_with_urgent_reply(void){
LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc");
MSList* lcs=ms_list_append(NULL,pauline->lc);
-
+
lcs=ms_list_append(lcs,marie->lc);
lcs=ms_list_append(lcs,marie2->lc);
lcs=ms_list_append(lcs,marie3->lc);
-
+
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
-
+
CU_ASSERT_TRUE(linphone_core_media_encryption_supported(pauline->lc,LinphoneMediaEncryptionSRTP));
linphone_core_set_media_encryption(pauline->lc,LinphoneMediaEncryptionSRTP);
linphone_core_set_network_reachable(marie2->lc,FALSE);
linphone_core_set_network_reachable(marie3->lc,FALSE);
-
+
linphone_core_invite_address(pauline->lc,marie->identity);
/*pauline should hear ringback, after 5 seconds, when it will retry without SRTP*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,9000));
/*Marie should be ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
-
+
/*marie accepts the call on its first device*/
linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000));
-
+
linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
-
+
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
@@ -272,16 +272,16 @@ static void call_forking_cancelled(void){
LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc");
MSList* lcs=ms_list_append(NULL,pauline->lc);
-
+
lcs=ms_list_append(lcs,marie->lc);
lcs=ms_list_append(lcs,marie2->lc);
lcs=ms_list_append(lcs,marie3->lc);
-
+
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
-
+
linphone_core_invite_address(pauline->lc,marie->identity);
/*pauline should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
@@ -289,16 +289,16 @@ static void call_forking_cancelled(void){
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000));
-
+
/*pauline finally cancels the call*/
linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
-
+
/*all devices should stop ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
-
+
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
@@ -312,16 +312,16 @@ static void call_forking_declined(bool_t declined_globaly){
LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc");
MSList* lcs=ms_list_append(NULL,pauline->lc);
-
+
lcs=ms_list_append(lcs,marie->lc);
lcs=ms_list_append(lcs,marie2->lc);
lcs=ms_list_append(lcs,marie3->lc);
-
+
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
-
+
linphone_core_invite_address(pauline->lc,marie->identity);
/*pauline should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
@@ -329,12 +329,12 @@ static void call_forking_declined(bool_t declined_globaly){
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000));
-
+
/*marie1 finally declines the call*/
linphone_core_decline_call(marie->lc,linphone_core_get_current_call(marie->lc),
declined_globaly ? LinphoneReasonDeclined : LinphoneReasonBusy
);
-
+
if (declined_globaly){
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
/*all devices should stop ringing*/
@@ -353,7 +353,7 @@ static void call_forking_declined(bool_t declined_globaly){
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,3000));
}
-
+
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
@@ -373,40 +373,40 @@ static void call_forking_with_push_notification_single(void){
MSList* lcs;
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
-
+
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
-
+
lcs=ms_list_append(NULL,pauline->lc);
-
+
lcs=ms_list_append(lcs,marie->lc);
-
+
/*unfortunately marie gets unreachable due to crappy 3G operator or iOS bug...*/
linphone_core_set_network_reachable(marie->lc,FALSE);
-
+
linphone_core_invite_address(pauline->lc,marie->identity);
-
+
/*the server is expected to send a push notification to marie, this will wake up linphone, that will reconnect:*/
linphone_core_set_network_reachable(marie->lc,TRUE);
-
+
/*Marie shall receive the call immediately*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000));
/*pauline should hear ringback as well*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
-
+
/*marie accepts the call*/
linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,5000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000));
-
+
liblinphone_tester_check_rtcp(pauline,marie);
-
+
linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,5000));
-
+
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
ms_list_free(lcs);
@@ -416,49 +416,49 @@ static void call_forking_with_push_notification_multiple(void){
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc");
-
+
MSList* lcs=ms_list_append(NULL,pauline->lc);
-
+
lcs=ms_list_append(lcs,marie->lc);
lcs=ms_list_append(lcs,marie2->lc);
-
+
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
-
+
/*unfortunately marie gets unreachable due to crappy 3G operator or iOS bug...*/
linphone_core_set_network_reachable(marie2->lc,FALSE);
-
+
linphone_core_invite_address(pauline->lc,marie->identity);
-
+
/*marie1 will ring*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000));
/*pauline should hear ringback as well*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
-
+
/*the server is expected to send a push notification to marie2, this will wake up linphone, that will reconnect:*/
linphone_core_set_network_reachable(marie2->lc,TRUE);
-
+
/*Marie shall receive the call immediately*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,5000));
-
+
/*marie2 accepts the call*/
linphone_core_accept_call(marie2->lc,linphone_core_get_current_call(marie2->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,1000));
-
+
/*call to marie1 should be cancelled*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
-
+
liblinphone_tester_check_rtcp(pauline,marie2);
-
+
linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
-
+
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
-
+
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
@@ -470,16 +470,16 @@ static void call_forking_not_responded(void){
LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc");
MSList* lcs=ms_list_append(NULL,pauline->lc);
-
+
lcs=ms_list_append(lcs,marie->lc);
lcs=ms_list_append(lcs,marie2->lc);
lcs=ms_list_append(lcs,marie3->lc);
-
+
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
-
+
linphone_core_invite_address(pauline->lc,marie->identity);
/*pauline should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
@@ -487,14 +487,14 @@ static void call_forking_not_responded(void){
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000));
-
+
/*nobody answers, flexisip should close the call after XX seconds*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,22000));
/*all devices should stop ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
-
+
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
@@ -516,28 +516,28 @@ static void early_media_call_forking(void) {
pol.automatically_accept=1;
pol.automatically_initiate=1;
-
+
linphone_core_set_user_agent(marie1->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
-
+
linphone_core_enable_video(pauline->lc,TRUE,TRUE);
-
+
linphone_core_enable_video(marie1->lc,TRUE,TRUE);
linphone_core_set_video_policy(marie1->lc,&pol);
-
+
linphone_core_enable_video(marie2->lc,TRUE,TRUE);
linphone_core_set_video_policy(marie2->lc,&pol);
linphone_core_set_audio_port_range(marie2->lc,40200,40300);
linphone_core_set_video_port_range(marie2->lc,40400,40500);
-
+
lcs=ms_list_append(lcs,marie1->lc);
lcs=ms_list_append(lcs,marie2->lc);
lcs=ms_list_append(lcs,pauline->lc);
linphone_call_params_enable_early_media_sending(params,TRUE);
linphone_call_params_enable_video(params,TRUE);
-
+
linphone_core_invite_address_with_params(pauline->lc,marie1->identity,params);
linphone_call_params_destroy(params);
@@ -545,11 +545,11 @@ static void early_media_call_forking(void) {
CU_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingEarlyMedia,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,3000));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1);
-
+
pauline_call=linphone_core_get_current_call(pauline->lc);
marie1_call=linphone_core_get_current_call(marie1->lc);
marie2_call=linphone_core_get_current_call(marie2->lc);
-
+
/*wait a bit that streams are established*/
wait_for_list(lcs,&dummy,1,6000);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth>60
@@ -558,21 +558,21 @@ static void early_media_call_forking(void) {
&& linphone_call_get_audio_stats(marie1_call)->download_bandwidth<99);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(marie2_call)->download_bandwidth>60
&& linphone_call_get_audio_stats(marie2_call)->download_bandwidth<99);
-
+
linphone_core_accept_call(marie1->lc,linphone_core_get_current_call(marie1->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallStreamsRunning,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,3000));
-
+
/*marie2 should get her call terminated*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
-
+
/*wait a bit that streams are established*/
wait_for_list(lcs,&dummy,1,3000);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth>60
&& linphone_call_get_audio_stats(pauline_call)->download_bandwidth<99 );
CU_ASSERT_TRUE(linphone_call_get_audio_stats(marie1_call)->download_bandwidth>60
&& linphone_call_get_audio_stats(marie1_call)->download_bandwidth<99 );
-
+
linphone_core_terminate_all_calls(pauline->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallEnd,1,5000));
@@ -588,35 +588,35 @@ static void call_with_sips(void){
LinphoneCoreManager* pauline1 = linphone_core_manager_new( "pauline_sips_rc");
LinphoneCoreManager* pauline2 = linphone_core_manager_new( "pauline_tcp_rc");
MSList* lcs=ms_list_append(NULL,marie->lc);
-
+
lcs=ms_list_append(lcs,pauline1->lc);
lcs=ms_list_append(lcs,pauline2->lc);
-
+
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline1->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline2->lc,"Natted Linphone",NULL);
-
+
linphone_core_invite_address(marie->lc,pauline1->identity);
/*marie should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
/*Only the sips registered device from pauline should ring*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallIncomingReceived,1,1000));
-
+
/*pauline accepts the call */
linphone_core_accept_call(pauline1->lc,linphone_core_get_current_call(pauline1->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000));
-
+
/*pauline2 should not have ring*/
CU_ASSERT_TRUE(pauline2->stat.number_of_LinphoneCallIncomingReceived==0);
-
+
linphone_core_terminate_call(pauline1->lc,linphone_core_get_current_call(pauline1->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallEnd,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,3000));
-
+
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline1);
linphone_core_manager_destroy(pauline2);
@@ -631,11 +631,11 @@ static void call_with_sips_not_achievable(void){
LinphoneAddress *dest;
LinphoneCall *call;
const LinphoneErrorInfo *ei;
-
+
lcs=ms_list_append(lcs,pauline1->lc);
lcs=ms_list_append(lcs,pauline2->lc);
-
+
dest=linphone_address_clone(pauline1->identity);
linphone_address_set_secure(dest,TRUE);
call=linphone_core_invite_address(marie->lc,dest);
@@ -649,7 +649,7 @@ static void call_with_sips_not_achievable(void){
if (ei){
CU_ASSERT_EQUAL(linphone_error_info_get_reason(ei), LinphoneReasonTemporarilyUnavailable);
}
-
+
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline1);
linphone_core_manager_destroy(pauline2);
@@ -665,12 +665,12 @@ static void call_with_ipv6(void) {
/*calling ortp_init() here is done to have WSAStartup() done, otherwise liblinphone_tester_ipv6_available() will not work.*/
ortp_init();
-
+
if (!liblinphone_tester_ipv6_available()){
ms_warning("Call with ipv6 not tested, no ipv6 connectivity");
return;
}
-
+
belle_sip_object_enable_leak_detector(TRUE);
begin=belle_sip_object_get_object_count();
@@ -687,7 +687,7 @@ static void call_with_ipv6(void) {
/*check that the remote contact is IPv6*/
const char *contact=linphone_call_get_remote_contact(pauline_call);
LinphoneAddress *ct_addr;
-
+
CU_ASSERT_PTR_NOT_NULL(contact);
if (contact){
ct_addr=linphone_address_new(contact);
@@ -697,7 +697,7 @@ static void call_with_ipv6(void) {
}
linphone_address_destroy(ct_addr);
}
-
+
}
liblinphone_tester_check_rtcp(marie,pauline);
@@ -722,14 +722,14 @@ static void file_transfer_message_rcs_to_external_body_client(void) {
LinphoneContent* content;
FILE *file_to_send = NULL;
size_t file_size;
- char *send_filepath = ms_strdup_printf("%s/images/nowebcamCIF.jpg", liblinphone_tester_file_prefix);
- char *receive_filepath = ms_strdup_printf("%s/receive_file.dump", liblinphone_tester_writable_dir_prefix);
-
+ char *send_filepath = ms_strdup_printf("%s/images/nowebcamCIF.jpg", bc_tester_read_dir_prefix);
+ char *receive_filepath = ms_strdup_printf("%s/receive_file.dump", bc_tester_writable_dir_prefix);
+
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
reset_counters(&marie->stat);
reset_counters(&pauline->stat);
-
+
linphone_proxy_config_set_custom_header(marie->lc->default_proxy, NULL, NULL);
linphone_core_refresh_registers(marie->lc);
//TODO: remove the next two lines once linphone core will send the header automatically
@@ -780,7 +780,7 @@ static void file_transfer_message_rcs_to_external_body_client(void) {
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1);
CU_ASSERT_TRUE(compare_files(send_filepath, receive_filepath));
-
+
linphone_content_unref(content);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
@@ -793,19 +793,19 @@ static void send_file_transfer_message_using_external_body_url(LinphoneCoreManag
LinphoneChatMessageCbs *cbs;
LinphoneChatRoom *chat_room;
LinphoneChatMessage *message;
-
+
/* create a chatroom on pauline's side */
to = linphone_address_as_string(marie->identity);
chat_room = linphone_core_create_chat_room(pauline->lc,to);
-
+
message = linphone_chat_room_create_message(chat_room, NULL);
-
+
cbs = linphone_chat_message_get_callbacks(message);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
-
+
linphone_chat_message_set_external_body_url(message, "https://www.linphone.org:444//tmp/54ec58280ace9_c30709218df8eaba61d1.jpg");
linphone_chat_room_send_chat_message(chat_room, message);
-
+
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1));
if (marie->stat.last_received_chat_message) {
linphone_chat_message_download_file(marie->stat.last_received_chat_message);
@@ -821,12 +821,12 @@ static void file_transfer_message_external_body_to_external_body_client(void) {
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
reset_counters(&marie->stat);
reset_counters(&pauline->stat);
-
+
linphone_proxy_config_set_custom_header(marie->lc->default_proxy, NULL, NULL);
linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, NULL, NULL);
linphone_core_refresh_registers(marie->lc);
linphone_core_refresh_registers(pauline->lc);
-
+
send_file_transfer_message_using_external_body_url(marie, pauline);
linphone_core_manager_destroy(marie);
@@ -838,13 +838,13 @@ static void file_transfer_message_external_body_to_rcs_client(void) {
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
reset_counters(&marie->stat);
reset_counters(&pauline->stat);
-
+
linphone_proxy_config_set_custom_header(marie->lc->default_proxy, NULL, NULL);
linphone_core_refresh_registers(marie->lc);
//TODO: remove the next two lines once linphone core will send the header automatically
linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml");
linphone_core_refresh_registers(pauline->lc);
-
+
send_file_transfer_message_using_external_body_url(marie, pauline);
linphone_core_manager_destroy(marie);
diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c
index 0411af166..7173d93d3 100644
--- a/tester/liblinphone_tester.c
+++ b/tester/liblinphone_tester.c
@@ -28,7 +28,9 @@
#include
#endif
-extern int liblinphone_tester_use_log_file;
+
+static FILE * log_file = NULL;
+static OrtpLogFunc ortp_log_handler;
#ifdef ANDROID
@@ -43,7 +45,7 @@ static const char* LogDomain = "liblinphone_tester";
int main(int argc, char** argv);
-void linphone_android_log_handler(int prio, const char *fmt, va_list args) {
+void liblinphone_android_log_handler(int prio, const char *fmt, va_list args) {
char str[4096];
char *current;
char *next;
@@ -63,17 +65,17 @@ void linphone_android_log_handler(int prio, const char *fmt, va_list args) {
}
}
-static void linphone_android_ortp_log_handler(OrtpLogLevel lev, const char *fmt, va_list args) {
+static void liblinphone_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;
+ 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);
+ liblinphone_android_log_handler(prio, fmt, args);
}
void cunit_android_trace_handler(int level, const char *fmt, va_list args) {
@@ -121,7 +123,6 @@ JNIEXPORT void JNICALL Java_org_linphone_tester_Tester_keepAccounts(JNIEnv *env,
JNIEXPORT void JNICALL Java_org_linphone_tester_Tester_clearAccounts(JNIEnv *env, jclass c) {
liblinphone_tester_clear_accounts();
}
-
#endif /* ANDROID */
#ifdef __QNX__
@@ -130,46 +131,71 @@ static void liblinphone_tester_qnx_log_handler(OrtpLogLevel lev, const char *fmt
}
#endif /* __QNX__ */
-
-
-void helper(const char *name) {
- liblinphone_tester_fprintf(stderr,"%s --help\n"
- "\t\t\t--verbose\n"
- "\t\t\t--silent\n"
- "\t\t\t--list-suites\n"
- "\t\t\t--list-tests \n"
- "\t\t\t--config \n"
- "\t\t\t--domain \n"
- "\t\t\t--auth-domain \n"
- "\t\t\t--suite \n"
- "\t\t\t--test \n"
- "\t\t\t--dns-hosts \n"
- "\t\t\t--log-file