Commit 93493976 authored by Simon Morlat's avatar Simon Morlat

tester automatically creates unique accounts on flexisip server before running...

tester automatically creates unique accounts on flexisip server before running tests. This allows several developer to run the test suite simultaneously !
parent b06019c5
......@@ -201,6 +201,37 @@ int linphone_address_get_port(const LinphoneAddress *u) {
return sal_address_get_port(u);
}
/**
* Set the password encoded in the address.
* It is used for basic authentication (not recommended).
* @param addr the LinphoneAddress
* @param passwd the password to set.
**/
void linphone_address_set_password(LinphoneAddress *addr, const char *passwd){
sal_address_set_password(addr,passwd);
}
/**
* Get the password encoded in the address.
* It is used for basic authentication (not recommended).
* @param addr the address
* @return the password, if any, NULL otherwise.
**/
const char *linphone_address_get_password(const LinphoneAddress *addr){
return sal_address_get_password(addr);
}
/**
* Set a header into the address.
* Headers appear in the URI with '?', such as <sip:test@linphone.org?SomeHeader=SomeValue>.
* @param addr the address
* @param header_name the header name
* @param header_value the header value
**/
void linphone_address_set_header(LinphoneAddress *addr, const char *header_name, const char *header_value){
sal_address_set_header(addr,header_name,header_value);
}
LinphoneAddress * linphone_core_create_address(LinphoneCore *lc, const char *address) {
return linphone_address_new(address);
}
......
......@@ -117,6 +117,14 @@ void sal_address_set_username(SalAddress *addr, const char *username){
SAL_ADDRESS_SET(addr,user,username);
}
void sal_address_set_password(SalAddress *addr, const char *passwd){
SAL_ADDRESS_SET(addr,user_password,passwd);
}
const char* sal_address_get_password(const SalAddress *addr){
SAL_ADDRESS_GET(addr,user_password);
}
void sal_address_set_domain(SalAddress *addr, const char *host){
SAL_ADDRESS_SET(addr,host,host);
}
......@@ -180,6 +188,10 @@ void sal_address_set_uri_params(SalAddress *addr, const char *params){
belle_sip_parameters_set(parameters,params);
}
void sal_address_set_header(SalAddress *addr, const char *header_name, const char *header_value){
belle_sip_uri_set_header(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(addr)),header_name, header_value);
}
void sal_address_set_transport(SalAddress* addr,SalTransport transport){
if (!sal_address_is_secure(addr)){
SAL_ADDRESS_SET(addr,transport_param,sal_transport_to_string(transport));
......
......@@ -1077,6 +1077,10 @@ unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size){
return belle_sip_random_bytes(ret,size);
}
char *sal_get_random_token(int size){
return belle_sip_random_token(ms_malloc(size),size);
}
unsigned int sal_get_random(void){
unsigned int ret=0;
belle_sip_random_bytes((unsigned char*)&ret,4);
......
......@@ -103,6 +103,7 @@ belle_sip_header_contact_t* sal_op_create_contact(SalOp *op){
belle_sip_header_address_set_uri(BELLE_SIP_HEADER_ADDRESS(contact_header),contact_uri);
}
belle_sip_uri_set_user_password(contact_uri,NULL);
belle_sip_uri_set_secure(contact_uri,sal_op_is_secure(op));
if (op->privacy!=SalPrivacyNone){
belle_sip_uri_set_user(contact_uri,NULL);
......
......@@ -6048,6 +6048,8 @@ void sip_config_uninit(LinphoneCore *lc)
if (i>=20) ms_warning("Cannot complete unregistration, giving up");
}
config->proxies=ms_list_free_with_data(config->proxies,(void (*)(void*)) _linphone_proxy_config_release);
config->deleted_proxies=ms_list_free_with_data(config->deleted_proxies,(void (*)(void*)) _linphone_proxy_config_release);
/*no longuer need to write proxy config if not changedlinphone_proxy_config_write_to_config_file(lc->config,NULL,i);*/ /*mark the end */
......
......@@ -400,6 +400,9 @@ LINPHONE_PUBLIC void linphone_address_set_transport(LinphoneAddress *uri,Linphon
LINPHONE_PUBLIC char *linphone_address_as_string(const LinphoneAddress *u);
LINPHONE_PUBLIC char *linphone_address_as_string_uri_only(const LinphoneAddress *u);
LINPHONE_PUBLIC bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2);
LINPHONE_PUBLIC void linphone_address_set_password(LinphoneAddress *addr, const char *passwd);
LINPHONE_PUBLIC const char *linphone_address_get_password(const LinphoneAddress *addr);
LINPHONE_PUBLIC void linphone_address_set_header(LinphoneAddress *addr, const char *header_name, const char *header_value);
LINPHONE_PUBLIC void linphone_address_destroy(LinphoneAddress *u);
/**
......@@ -477,6 +480,8 @@ enum _LinphoneIceState{
**/
typedef enum _LinphoneIceState LinphoneIceState;
LINPHONE_PUBLIC const char *linphone_ice_state_to_string(LinphoneIceState state);
/**
* Enum describing uPnP states.
* @ingroup initializing
......
......@@ -641,6 +641,24 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
return 0;
}
const char *linphone_ice_state_to_string(LinphoneIceState state){
switch(state){
case LinphoneIceStateFailed:
return "IceStateFailed";
case LinphoneIceStateHostConnection:
return "IceStateHostConnection";
case LinphoneIceStateInProgress:
return "IceStateInProgress";
case LinphoneIceStateNotActivated:
return "IceStateNotActivated";
case LinphoneIceStateReflexiveConnection:
return "IceStateReflexiveConnection";
case LinphoneIceStateRelayConnection:
return "IceStateRelayConnection";
}
return "invalid";
}
void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
{
IceCheckList *audio_check_list;
......@@ -699,6 +717,8 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed;
}
}
ms_message("Call [%p] New ICE state: audio: [%s] video: [%s]", call,
linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state));
}
void _update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session)
......
......@@ -110,6 +110,9 @@ void sal_address_set_transport_name(SalAddress* addr,const char* transport);
void sal_address_set_params(SalAddress *addr, const char *params);
void sal_address_set_uri_params(SalAddress *addr, const char *params);
bool_t sal_address_is_ipv6(SalAddress *addr);
void sal_address_set_password(SalAddress *addr, const char *passwd);
const char *sal_address_get_password(const SalAddress *addr);
void sal_address_set_header(SalAddress *addr, const char *header_name, const char *header_value);
Sal * sal_init();
void sal_uninit(Sal* sal);
......@@ -755,6 +758,7 @@ LINPHONE_PUBLIC bool_t sal_dns_srv_enabled(const Sal *sal);
LINPHONE_PUBLIC void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_file);
LINPHONE_PUBLIC const char *sal_get_dns_user_hosts_file(const Sal *sal);
unsigned int sal_get_random(void);
char *sal_get_random_token(int size);
unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size);
belle_sip_source_t * sal_create_timer(Sal *sal, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name);
void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer);
......
......@@ -25,7 +25,8 @@ liblinphonetester_la_SOURCES = tester.c \
log_collection_tester.c \
transport_tester.c \
player_tester.c \
dtmf_tester.c
dtmf_tester.c \
accountmanager.c
liblinphonetester_la_LDFLAGS= -no-undefined
liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS)
......
/*
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 "liblinphone_tester.h"
#include "private.h"
struct _Account{
LinphoneAddress *identity;
LinphoneAddress *modified_identity;
char *password;
int created;
int done;
int auth_requested;
};
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);
obj->password=sal_get_random_token(8);
obj->modified_identity=linphone_address_clone(identity);
modified_username=ms_strdup_printf("%s_%s",linphone_address_get_username(identity), unique_id);
linphone_address_set_username(obj->modified_identity, modified_username);
ms_free(modified_username);
belle_sip_object_inhibit_leak_detector(FALSE);
return obj;
};
void account_destroy(Account *obj){
linphone_address_unref(obj->identity);
linphone_address_unref(obj->modified_identity);
ms_free(obj->password);
ms_free(obj);
}
struct _AccountManager{
char *unique_id;
MSList *accounts;
};
typedef struct _AccountManager AccountManager;
static AccountManager *the_am=NULL;
AccountManager *account_manager_get(void){
if (the_am==NULL){
the_am=ms_new0(AccountManager,1);
the_am->unique_id=sal_get_random_token(6);
}
return the_am;
}
void account_manager_destroy(void){
if (the_am){
ms_free(the_am->unique_id);
ms_list_free_with_data(the_am->accounts,(void(*)(void*))account_destroy);
ms_free(the_am);
}
the_am=NULL;
}
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)){
return a;
}
}
return NULL;
}
static void account_created_on_server_cb(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const char *info){
Account *account=(Account*)linphone_core_get_user_data(lc);
switch(state){
case LinphoneRegistrationOk:
account->created=1;
break;
case LinphoneRegistrationCleared:
account->done=1;
break;
default:
break;
}
}
static void account_created_auth_requested_cb(LinphoneCore *lc, const char *username, const char *realm, const char *domain){
Account *account=(Account*)linphone_core_get_user_data(lc);
account->auth_requested=1;
}
void account_create_on_server(Account *account, const LinphoneProxyConfig *refcfg){
LinphoneCoreVTable vtable={0};
LinphoneCore *lc;
LinphoneAddress *tmp_identity=linphone_address_clone(account->modified_identity);
LinphoneProxyConfig *cfg;
LinphoneAuthInfo *ai;
char *tmp;
LinphoneAddress *server_addr;
vtable.registration_state_changed=account_created_on_server_cb;
vtable.auth_info_requested=account_created_auth_requested_cb;
lc=configure_lc_from(&vtable,NULL,NULL,account);
cfg=linphone_core_create_proxy_config(lc);
linphone_address_set_password(tmp_identity,account->password);
linphone_address_set_header(tmp_identity,"X-Create-Account","yes");
tmp=linphone_address_as_string(tmp_identity);
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_transport(server_addr,LinphoneTransportTcp); /*use tcp for account creation*/
tmp=linphone_address_as_string(server_addr);
linphone_proxy_config_set_server_addr(cfg,tmp);
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));
}
linphone_proxy_config_stop_refreshing(cfg); /*so that op is destroyed; we need to remove the X-create-account*/
linphone_proxy_config_edit(cfg);
tmp=linphone_address_as_string(account->modified_identity);
linphone_proxy_config_set_identity(cfg,tmp); /*remove the X-Create-Account header*/
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));
}
linphone_core_remove_proxy_config(lc,cfg);
linphone_proxy_config_unref(cfg);
if (wait_for_until(lc,NULL,&account->done,1,3000)==FALSE){
ms_error("Account creation could not clean the registration context.");
}
linphone_core_destroy(lc);
}
LinphoneAddress *account_manager_check_account(AccountManager *m, LinphoneProxyConfig *cfg){
LinphoneCore *lc=linphone_proxy_config_get_core(cfg);
const char *identity=linphone_proxy_config_get_identity(cfg);
LinphoneAddress *id_addr=linphone_address_new(identity);
Account *account=account_manager_get_account(m,id_addr);
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);
create_account=TRUE;
m->accounts=ms_list_append(m->accounts,account);
}
tmp=linphone_address_as_string(account->modified_identity);
linphone_proxy_config_set_identity(cfg,tmp);
ms_free(tmp);
if (create_account){
account_create_on_server(account,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);
linphone_address_unref(id_addr);
return account->modified_identity;
}
void linphone_core_manager_check_accounts(LinphoneCoreManager *m){
const MSList *it;
AccountManager *am=account_manager_get();
for(it=linphone_core_get_proxy_config_list(m->lc);it!=NULL;it=it->next){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig *)it->data;
LinphoneAddress *modified_identity=account_manager_check_account(am,cfg);
if (m->identity){
linphone_address_unref(m->identity);
}
m->identity=linphone_address_ref(modified_identity);
}
}
......@@ -206,9 +206,6 @@ bool_t call_with_params2(LinphoneCoreManager* caller_mgr
CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params));
}
/*linphone_core_invite(caller_mgr->lc,"pauline");*/
did_received_call = wait_for(callee_mgr->lc
,caller_mgr->lc
,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived
......@@ -641,7 +638,7 @@ static void simple_call_compatibility_mode(void) {
CU_ASSERT_TRUE (wait_for(lc_marie,lc_marie,&stat_marie->number_of_LinphoneRegistrationOk,1));
linphone_core_invite(lc_marie,"pauline");
linphone_core_invite_address(lc_marie,pauline->identity);
CU_ASSERT_TRUE (wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallIncomingReceived,1));
CU_ASSERT_TRUE(linphone_core_inc_invite_pending(lc_pauline));
......@@ -674,7 +671,7 @@ static void cancelled_call(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
LinphoneCall* out_call = linphone_core_invite(pauline->lc,"marie");
LinphoneCall* out_call = linphone_core_invite_address(pauline->lc,marie->identity);
linphone_call_ref(out_call);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1));
......@@ -730,7 +727,7 @@ static void call_failed_because_of_codecs(void) {
disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1);
disable_all_audio_codecs_except_one(pauline->lc,"pcma",-1);
out_call = linphone_core_invite(pauline->lc,"marie");
out_call = linphone_core_invite_address(pauline->lc,marie->identity);
linphone_call_ref(out_call);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1));
......@@ -801,7 +798,7 @@ static void cancelled_ringing_call(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
LinphoneCall* out_call = linphone_core_invite(pauline->lc,"marie");
LinphoneCall* out_call = linphone_core_invite_address(pauline->lc,marie->identity);
linphone_call_ref(out_call);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallIncomingReceived,1));
......@@ -823,7 +820,7 @@ static void early_declined_call(void) {
LinphoneCall* out_call;
linphone_core_set_max_calls(marie->lc,0);
out_call = linphone_core_invite(pauline->lc,"marie");
out_call = linphone_core_invite_address(pauline->lc,marie->identity);
linphone_call_ref(out_call);
/*wait until flexisip transfers the busy...*/
......@@ -943,7 +940,7 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee
linphone_core_iterate(callee->lc);
}
ms_usleep(20000);
}while(!liblinphone_tester_clock_elapsed(&ts,5000));
}while(!liblinphone_tester_clock_elapsed(&ts,10000));
}
/*make sure encryption mode are preserved*/
......@@ -980,7 +977,6 @@ static void _call_with_ice_base(LinphoneCoreManager* pauline,LinphoneCoreManager
CU_ASSERT_TRUE(call(pauline,marie));
if (callee_with_ice && caller_with_ice) {
check_ice(pauline,marie,LinphoneIceStateHostConnection);
/*wait for the ICE reINVITE to complete*/
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2));
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
......@@ -1631,7 +1627,7 @@ static void video_call_with_ice_no_matching_audio_codecs(void) {
linphone_core_set_firewall_policy(pauline->lc, LinphonePolicyUseIce);
linphone_core_set_stun_server(pauline->lc, "stun.linphone.org");
out_call = linphone_core_invite(marie->lc, "pauline");
out_call = linphone_core_invite_address(marie->lc, pauline->identity);
linphone_call_ref(out_call);
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallOutgoingInit, 1));
......@@ -2822,7 +2818,7 @@ static void call_established_with_rejected_reinvite_with_error(void) {
static void call_rejected_because_wrong_credentials_with_params(const char* user_agent,bool_t enable_auth_req_cb) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneAuthInfo* good_auth_info=linphone_auth_info_clone((LinphoneAuthInfo*)(linphone_core_get_auth_info_list(marie->lc)->data));
LinphoneAuthInfo* good_auth_info=linphone_auth_info_clone(linphone_core_find_auth_info(marie->lc,NULL,linphone_address_get_username(marie->identity),NULL));
LinphoneAuthInfo* wrong_auth_info=linphone_auth_info_clone(good_auth_info);
bool_t result=FALSE;
linphone_auth_info_set_passwd(wrong_auth_info,"passecretdutout");
......@@ -2855,7 +2851,7 @@ static void call_rejected_because_wrong_credentials_with_params(const char* user
/*to make sure unregister will work*/
linphone_core_clear_all_auth_info(marie->lc);
linphone_core_add_auth_info(marie->lc,good_auth_info);
linphone_auth_info_destroy(good_auth_info);
linphone_core_manager_destroy(marie);
}
......
......@@ -205,6 +205,15 @@ hashed-passwords=false
# Default value: false
new-auth-on-407=false
# Enable a feature useful for automatic tests, allowing a client
# to create a temporary account in the password database in memory.
# This MUST not be used for production as it is a real security
# hole.
# Default value: false
enable-test-accounts-creation=true
##
## ...
##
......
......@@ -278,6 +278,9 @@ void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatMessage *msg,
void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreManager* callee);
void liblinphone_tester_clock_start(MSTimeSpec *start);
bool_t liblinphone_tester_clock_elapsed(const MSTimeSpec *start, int value_ms);
void linphone_core_manager_check_accounts(LinphoneCoreManager *m);
void account_manager_destroy(void);
LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file, void* user_data);
#ifdef ANDROID
void cunit_android_trace_handler(int level, const char *fmt, va_list args) ;
#endif
......
......@@ -25,8 +25,6 @@
#include "CUnit/CUCurses.h"
#endif
static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file, void* user_data);
static test_suite_t **test_suite = NULL;
static int nb_test_suites = 0;
......@@ -108,7 +106,7 @@ void reset_counters( stats* counters) {
memset(counters,0,sizeof(stats));
}
static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file, void* user_data) {
LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file, void* user_data) {
LinphoneCore* lc;
LpConfig* config = NULL;
char *filepath = NULL;
......@@ -252,6 +250,7 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f
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);
linphone_core_manager_check_accounts(mgr);
/*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));
......@@ -545,6 +544,7 @@ int liblinphone_tester_run_tests(const char *suite_name, const char *test_name)
}
CU_cleanup_registry();
account_manager_destroy();
return ret;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment