forked from mirrors/linphone-iphone
278 lines
8.6 KiB
C
278 lines
8.6 KiB
C
/*
|
|
liblinphone_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 "linphone/core.h"
|
|
#include "private.h"
|
|
#include "liblinphone_tester.h"
|
|
|
|
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
|
|
#pragma GCC diagnostic push
|
|
#endif
|
|
#ifdef _MSC_VER
|
|
#pragma warning(disable : 4996)
|
|
#else
|
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
|
#endif
|
|
|
|
#ifdef HAVE_GTK
|
|
#include <gtk/gtk.h>
|
|
#endif
|
|
|
|
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
|
|
#pragma GCC diagnostic pop
|
|
#endif
|
|
|
|
|
|
static FILE * log_file = NULL;
|
|
|
|
#ifdef __ANDROID__
|
|
|
|
#include <android/log.h>
|
|
#include <jni.h>
|
|
#define CALLBACK_BUFFER_SIZE 1024
|
|
|
|
static JNIEnv *current_env = NULL;
|
|
static jobject current_obj = 0;
|
|
static const char* LogDomain = "liblinphone_tester";
|
|
|
|
int main(int argc, char** argv);
|
|
|
|
void liblinphone_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 liblinphone_android_ortp_log_handler(const char *domain, 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;
|
|
}
|
|
liblinphone_android_log_handler(prio, fmt, args);
|
|
}
|
|
|
|
static void liblinphone_android_bctbx_log_handler(const char *domain, BctbxLogLevel lev, const char *fmt, va_list args) {
|
|
int prio;
|
|
switch(lev){
|
|
case BCTBX_LOG_DEBUG: prio = ANDROID_LOG_DEBUG; break;
|
|
case BCTBX_LOG_MESSAGE: prio = ANDROID_LOG_INFO; break;
|
|
case BCTBX_LOG_WARNING: prio = ANDROID_LOG_WARN; break;
|
|
case BCTBX_LOG_ERROR: prio = ANDROID_LOG_ERROR; break;
|
|
case BCTBX_LOG_FATAL: prio = ANDROID_LOG_FATAL; break;
|
|
default: prio = ANDROID_LOG_DEFAULT; break;
|
|
}
|
|
liblinphone_android_log_handler(prio, fmt, args);
|
|
}
|
|
|
|
void bcunit_android_trace_handler(int level, const char *fmt, va_list args) {
|
|
char buffer[CALLBACK_BUFFER_SIZE];
|
|
jstring javaString;
|
|
jclass cls;
|
|
jmethodID method;
|
|
jint javaLevel = level;
|
|
JNIEnv *env = current_env;
|
|
if(env == NULL) return;
|
|
vsnprintf(buffer, CALLBACK_BUFFER_SIZE, fmt, args);
|
|
javaString = (*env)->NewStringUTF(env, buffer);
|
|
cls = (*env)->GetObjectClass(env, current_obj);
|
|
method = (*env)->GetMethodID(env, cls, "printLog", "(ILjava/lang/String;)V");
|
|
(*env)->CallVoidMethod(env, current_obj, method, javaLevel, javaString);
|
|
(*env)->DeleteLocalRef(env,javaString);
|
|
(*env)->DeleteLocalRef(env,cls);
|
|
}
|
|
|
|
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);
|
|
(*env)->ReleaseStringUTFChars(env, string, rawString);
|
|
}
|
|
current_env = env;
|
|
current_obj = obj;
|
|
bc_set_trace_handler(bcunit_android_trace_handler);
|
|
ret = main(argc, argv);
|
|
current_env = NULL;
|
|
bc_set_trace_handler(NULL);
|
|
for (i=0; i<argc; i++) {
|
|
free(argv[i]);
|
|
}
|
|
free(argv);
|
|
return ret;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_linphone_tester_Tester_keepAccounts(JNIEnv *env, jclass c, jboolean keep) {
|
|
liblinphone_tester_keep_accounts((int)keep);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_linphone_tester_Tester_clearAccounts(JNIEnv *env, jclass c) {
|
|
liblinphone_tester_clear_accounts();
|
|
}
|
|
#endif /* __ANDROID__ */
|
|
|
|
static void log_handler(int lev, const char *fmt, va_list args) {
|
|
#ifdef _WIN32
|
|
vfprintf(lev == ORTP_ERROR ? stderr : stdout, fmt, args);
|
|
fprintf(lev == ORTP_ERROR ? stderr : stdout, "\n");
|
|
#else
|
|
va_list cap;
|
|
va_copy(cap,args);
|
|
#ifdef __ANDROID__
|
|
/* IMPORTANT: needed by liblinphone tester to retrieve suite list...*/
|
|
bcunit_android_trace_handler(lev == ORTP_ERROR, fmt, cap);
|
|
#else
|
|
/* Otherwise, we must use stdio to avoid log formatting (for autocompletion etc.) */
|
|
vfprintf(lev == ORTP_ERROR ? stderr : stdout, fmt, cap);
|
|
fprintf(lev == ORTP_ERROR ? stderr : stdout, "\n");
|
|
#endif
|
|
va_end(cap);
|
|
#endif
|
|
bctbx_logv(ORTP_LOG_DOMAIN, lev, fmt, args);
|
|
}
|
|
|
|
void liblinphone_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args)) {
|
|
if (! log_file) {
|
|
#if defined(__ANDROID__)
|
|
linphone_core_set_log_handler(liblinphone_android_ortp_log_handler);
|
|
bctbx_set_log_handler(liblinphone_android_bctbx_log_handler);
|
|
#endif
|
|
}
|
|
|
|
if (ftester_printf == NULL) ftester_printf = log_handler;
|
|
bc_tester_init(ftester_printf, ORTP_MESSAGE, ORTP_ERROR, "rcfiles");
|
|
liblinphone_tester_add_suites();
|
|
}
|
|
|
|
int liblinphone_tester_set_log_file(const char *filename) {
|
|
if (log_file) {
|
|
fclose(log_file);
|
|
}
|
|
log_file = fopen(filename, "w");
|
|
if (!log_file) {
|
|
ms_error("Cannot open file [%s] for writing logs because [%s]", filename, strerror(errno));
|
|
return -1;
|
|
}
|
|
ms_message("Redirecting traces to file [%s]", filename);
|
|
linphone_core_set_log_file(log_file);
|
|
return 0;
|
|
}
|
|
|
|
|
|
#if !TARGET_OS_IPHONE && !(defined(LINPHONE_WINDOWS_PHONE) || defined(LINPHONE_WINDOWS_UNIVERSAL))
|
|
|
|
static const char* liblinphone_helper =
|
|
"\t\t\t--verbose\n"
|
|
"\t\t\t--silent\n"
|
|
"\t\t\t--log-file <output log file path>\n"
|
|
"\t\t\t--domain <test sip domain>\n"
|
|
"\t\t\t--auth-domain <test auth domain>\n"
|
|
"\t\t\t--dns-hosts </etc/hosts -like file to used to override DNS names (default: tester_hosts)>\n"
|
|
"\t\t\t--keep-recorded-files\n"
|
|
"\t\t\t--disable-leak-detector\n"
|
|
"\t\t\t--disable-tls-support\n"
|
|
"\t\t\t--no-ipv6 (turn off IPv6 in LinphoneCore, tests requiring IPv6 will be skipped)\n"
|
|
"\t\t\t--show-account-manager-logs (show temporary test account creation logs)\n"
|
|
;
|
|
|
|
int main (int argc, char *argv[])
|
|
{
|
|
int i;
|
|
int ret;
|
|
|
|
#ifdef HAVE_GTK
|
|
gtk_init(&argc, &argv);
|
|
#if !GLIB_CHECK_VERSION(2,32,0) // backward compatibility with Debian 6 and CentOS 6
|
|
g_thread_init(NULL);
|
|
#endif
|
|
gdk_threads_init();
|
|
#endif
|
|
|
|
liblinphone_tester_init(NULL);
|
|
linphone_core_set_log_level(ORTP_ERROR);
|
|
|
|
for(i = 1; i < argc; ++i) {
|
|
if (strcmp(argv[i], "--verbose") == 0) {
|
|
linphone_core_set_log_level(ORTP_MESSAGE);
|
|
} else if (strcmp(argv[i], "--silent") == 0) {
|
|
linphone_core_set_log_level(ORTP_FATAL);
|
|
} else if (strcmp(argv[i],"--log-file")==0){
|
|
CHECK_ARG("--log-file", ++i, argc);
|
|
if (liblinphone_tester_set_log_file(argv[i]) < 0) return -2;
|
|
} else if (strcmp(argv[i],"--domain")==0){
|
|
CHECK_ARG("--domain", ++i, argc);
|
|
test_domain=argv[i];
|
|
} else if (strcmp(argv[i],"--auth-domain")==0){
|
|
CHECK_ARG("--auth-domain", ++i, argc);
|
|
auth_domain=argv[i];
|
|
}else if (strcmp(argv[i],"--dns-hosts")==0){
|
|
CHECK_ARG("--dns-hosts", ++i, argc);
|
|
userhostsfile=argv[i];
|
|
} else if (strcmp(argv[i],"--keep-recorded-files")==0){
|
|
liblinphone_tester_keep_recorded_files(TRUE);
|
|
} else if (strcmp(argv[i],"--disable-leak-detector")==0){
|
|
liblinphone_tester_disable_leak_detector(TRUE);
|
|
} else if (strcmp(argv[i],"--disable-tls-support")==0){
|
|
liblinphone_tester_tls_support_disabled = TRUE;
|
|
} else if (strcmp(argv[i],"--no-ipv6")==0){
|
|
liblinphonetester_ipv6 = FALSE;
|
|
} else if (strcmp(argv[i],"--show-account-manager-logs")==0){
|
|
liblinphonetester_show_account_manager_logs=TRUE;
|
|
} else {
|
|
int bret = bc_tester_parse_args(argc, argv, i);
|
|
if (bret>0) {
|
|
i += bret - 1;
|
|
continue;
|
|
} else if (bret<0) {
|
|
bc_tester_helper(argv[0], liblinphone_helper);
|
|
}
|
|
return bret;
|
|
}
|
|
}
|
|
|
|
ret = bc_tester_start(argv[0]);
|
|
liblinphone_tester_uninit();
|
|
return ret;
|
|
}
|
|
|
|
|
|
#endif
|