From 10d1411f876763f3c7f691abafef02c2535b522c Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer <gautier.pelloux-prayer@belledonne-communications.com> Date: Tue, 10 Jun 2014 15:50:41 +0200 Subject: [PATCH] Quality reporting: separate unit tests in a different file and fix mid term session report --- build/android/liblinphone_tester.mk | 11 +- coreapi/quality_reporting.c | 56 ++++---- mediastreamer2 | 2 +- tester/Makefile.am | 9 +- tester/call_tester.c | 120 +---------------- tester/liblinphone_tester.c | 22 +--- tester/liblinphone_tester.h | 6 + tester/quality_reporting_tester.c | 198 ++++++++++++++++++++++++++++ tester/tester.c | 30 ++++- 9 files changed, 270 insertions(+), 184 deletions(-) create mode 100644 tester/quality_reporting_tester.c diff --git a/build/android/liblinphone_tester.mk b/build/android/liblinphone_tester.mk index 8e5221e20e..e9a2c87189 100644 --- a/build/android/liblinphone_tester.mk +++ b/build/android/liblinphone_tester.mk @@ -12,21 +12,22 @@ common_SRC_FILES := \ stun_tester.c \ flexisip_tester.c \ tester.c \ - remote_provisioning_tester.c - + remote_provisioning_tester.c \ + quality_reporting_tester.c + common_C_INCLUDES += \ $(LOCAL_PATH) \ $(LOCAL_PATH)/../include \ $(LOCAL_PATH)/../coreapi \ $(LOCAL_PATH)/../oRTP/include \ - $(LOCAL_PATH)/../mediastreamer2/include + $(LOCAL_PATH)/../mediastreamer2/include include $(CLEAR_VARS) -LOCAL_MODULE := liblinphone_tester +LOCAL_MODULE := liblinphone_tester LOCAL_MODULE_FILENAME := liblinphone_tester-$(TARGET_ARCH_ABI) -LOCAL_SRC_FILES += $(common_SRC_FILES) +LOCAL_SRC_FILES += $(common_SRC_FILES) LOCAL_C_INCLUDES = $(common_C_INCLUDES) LOCAL_CFLAGS = -DIN_LINPHONE LOCAL_LDLIBS := -llog diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 1cd9c91525..52c60f4466 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -321,16 +321,19 @@ static int send_report(const LinphoneCall* call, reporting_session_report_t * re in that case, we abort the report since it's not useful data*/ if (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0 || report->info.remote_addr.ip == NULL || strlen(report->info.remote_addr.ip) == 0) { - ms_warning("QualityReporting: Trying to submit a %s too early (call duration: %d sec) and IP could " + ms_warning("QualityReporting[%p]: Trying to submit a %s too early (call duration: %d sec) but %s IP could " "not be retrieved so dropping this report" + , report , report_event - , linphone_call_get_duration(call)); + , linphone_call_get_duration(call) + , (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0) ? "local" : "remote"); return 1; } addr = linphone_address_new(linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy)); if (addr == NULL) { - ms_warning("QualityReporting: Asked to submit reporting statistics but no collector address found"); + ms_warning("QualityReporting[%p]: Asked to submit reporting statistics but no collector address found" + , report); return 2; } @@ -383,33 +386,32 @@ static const SalStreamDescription * get_media_stream_for_desc(const SalMediaDesc } } } - - ms_warning("QualityReporting: Could not find the associated stream of type %d", sal_stream_type); return NULL; } static void update_ip(LinphoneCall * call, int stats_type) { SalStreamType sal_stream_type = (stats_type == LINPHONE_CALL_STATS_AUDIO) ? SalAudio : SalVideo; - if (media_report_enabled(call,stats_type)) { - const SalStreamDescription * local_desc = get_media_stream_for_desc(call->localdesc, sal_stream_type); - const SalStreamDescription * remote_desc = get_media_stream_for_desc(sal_call_get_remote_media_description(call->op), sal_stream_type); + const SalStreamDescription * local_desc = get_media_stream_for_desc(call->localdesc, sal_stream_type); + const SalStreamDescription * remote_desc = get_media_stream_for_desc(sal_call_get_remote_media_description(call->op), sal_stream_type); - /*local info are always up-to-date and correct*/ - if (local_desc != NULL) { + if (local_desc != NULL) { + /*since this function might be called for video stream AFTER it has been uninitialized, local description might + be invalid. In any other case, IP/port should be always filled and valid*/ + if (local_desc->rtp_addr != NULL && strlen(local_desc->rtp_addr) > 0) { call->log->reporting.reports[stats_type]->info.local_addr.port = local_desc->rtp_port; STR_REASSIGN(call->log->reporting.reports[stats_type]->info.local_addr.ip, ms_strdup(local_desc->rtp_addr)); } + } - if (remote_desc != NULL) { - /*port is always stored in stream description struct*/ - call->log->reporting.reports[stats_type]->info.remote_addr.port = remote_desc->rtp_port; + if (remote_desc != NULL) { + /*port is always stored in stream description struct*/ + call->log->reporting.reports[stats_type]->info.remote_addr.port = remote_desc->rtp_port; - /*for IP it can be not set if we are using a direct route*/ - if (remote_desc->rtp_addr != NULL && strlen(remote_desc->rtp_addr) > 0) { - STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(remote_desc->rtp_addr)); - } else { - STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(sal_call_get_remote_media_description(call->op)->addr)); - } + /*for IP it can be not set if we are using a direct route*/ + if (remote_desc->rtp_addr != NULL && strlen(remote_desc->rtp_addr) > 0) { + STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(remote_desc->rtp_addr)); + } else { + STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(sal_call_get_remote_media_description(call->op)->addr)); } } } @@ -650,18 +652,12 @@ void linphone_reporting_call_state_updated(LinphoneCall *call){ bool_t enabled=media_report_enabled(call, LINPHONE_CALL_STATS_VIDEO); switch (state){ case LinphoneCallStreamsRunning: - if (enabled!=call->log->reporting.was_video_running){ - if (enabled){ - linphone_reporting_update_ip(call); - }else{ - ms_message("Send midterm report with status %d", - send_report(call, call->log->reporting.reports[LINPHONE_CALL_STATS_VIDEO], "VQSessionReport") - ); - } - }else{ - linphone_reporting_update_ip(call); + linphone_reporting_update_ip(call); + if (!enabled && call->log->reporting.was_video_running){ + ms_message("Send midterm report with status %d", + send_report(call, call->log->reporting.reports[LINPHONE_CALL_STATS_VIDEO], "VQSessionReport") + ); } - call->log->reporting.was_video_running=enabled; break; case LinphoneCallEnd: diff --git a/mediastreamer2 b/mediastreamer2 index 7bf89d4302..24427ed565 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 7bf89d4302afb266bb359d7af8c16907ae8c327e +Subproject commit 24427ed565a93f523b44b43ed9b2d20f8cea5385 diff --git a/tester/Makefile.am b/tester/Makefile.am index 46ffb12cd9..afa7f77a92 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -20,7 +20,8 @@ liblinphonetester_la_SOURCES = tester.c \ eventapi_tester.c \ flexisip_tester.c \ stun_tester.c \ - remote_provisioning_tester.c + remote_provisioning_tester.c \ + quality_reporting_tester.c liblinphonetester_la_LDFLAGS= -no-undefined liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS) @@ -32,14 +33,14 @@ if !BUILD_IOS noinst_PROGRAMS = liblinphone_tester -liblinphone_tester_SOURCES = liblinphone_tester.c -liblinphone_tester_LDADD = $(top_builddir)/coreapi/liblinphone.la liblinphonetester.la +liblinphone_tester_SOURCES = liblinphone_tester.c +liblinphone_tester_LDADD = $(top_builddir)/coreapi/liblinphone.la liblinphonetester.la endif test: liblinphone_tester - ./liblinphone_tester --config $(abs_srcdir) + ./liblinphone_tester --config $(abs_srcdir) else !BUILD_CUNIT_TESTS diff --git a/tester/call_tester.c b/tester/call_tester.c index b8a66f82e1..534065a7a9 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -2171,120 +2171,6 @@ static void call_rejected_without_403_because_wrong_credentials_no_auth_req_cb() call_rejected_because_wrong_credentials_with_params("tester-no-403",FALSE); } -void create_call_for_quality_reporting_tests( - LinphoneCoreManager* marie, - LinphoneCoreManager* pauline, - LinphoneCall** call_marie, - LinphoneCall** call_pauline) { - CU_ASSERT_TRUE(call(pauline,marie)); - *call_marie = linphone_core_get_current_call(marie->lc); - *call_pauline = linphone_core_get_current_call(pauline->lc); - CU_ASSERT_PTR_NOT_NULL(*call_marie); - CU_ASSERT_PTR_NOT_NULL(*call_pauline); -} - -static void quality_reporting_not_used_without_config() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; - - create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); - - // marie has stats collection enabled since pauline has not - CU_ASSERT_TRUE(linphone_proxy_config_quality_reporting_enabled(call_marie->dest_proxy)); - CU_ASSERT_FALSE(linphone_proxy_config_quality_reporting_enabled(call_pauline->dest_proxy)); - - CU_ASSERT_EQUAL(strcmp("sip:collector@sip.example.org", - linphone_proxy_config_get_quality_reporting_collector(call_marie->dest_proxy)), 0); - - // this field should be already filled - CU_ASSERT_PTR_NOT_NULL(call_marie->log->reporting.reports[0]->info.local_addr.ip); - CU_ASSERT_PTR_NULL(call_pauline->log->reporting.reports[0]->info.local_addr.ip); - - // but not this one since it is updated at the end of call - CU_ASSERT_PTR_NULL(call_marie->log->reporting.reports[0]->dialog_id); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} -static void quality_reporting_not_sent_if_call_not_started() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCallLog* out_call_log; - LinphoneCall* out_call; - - linphone_core_set_max_calls(pauline->lc,0); - out_call = linphone_core_invite(marie->lc,"pauline"); - linphone_call_ref(out_call); - - CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1, 10000)); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1); - - if (ms_list_size(linphone_core_get_call_logs(marie->lc))>0) { - CU_ASSERT_PTR_NOT_NULL(out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data)); - CU_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted); - } - linphone_call_unref(out_call); - - // wait a few time... - wait_for(marie->lc,NULL,NULL,0); - // since the callee was busy, there should be no publish to do - CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} -static void quality_reporting_at_call_termination() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; - - create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); - - linphone_core_terminate_all_calls(marie->lc); - - // now dialog id should be filled - CU_ASSERT_PTR_NOT_NULL(call_marie->log->reporting.reports[0]->dialog_id); - - CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallReleased,1, 10000)); - CU_ASSERT_TRUE(wait_for_until(pauline->lc,NULL,&pauline->stat.number_of_LinphoneCallReleased,1, 10000)); - - CU_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); - CU_ASSERT_PTR_NULL(linphone_core_get_current_call(pauline->lc)); - - - // PUBLISH submission to the collector should be ok - CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1)); - CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishOk,1)); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - -static void quality_reporting_interval_report() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; - - create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); - linphone_proxy_config_set_quality_reporting_interval(call_marie->dest_proxy, 3); - - CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc)); - CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); - - // PUBLISH submission to the collector should be ok - CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,3,25000)); - CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,3,25000)); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - - #ifdef VIDEO_ENABLED /*this is call forking with early media managed at client side (not by flexisip server)*/ static void multiple_early_media(void) { @@ -2362,7 +2248,7 @@ static void multiple_early_media(void) { info=linphone_core_create_info_message(marie1->lc); linphone_call_send_info_message(marie1_call,info); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_inforeceived,1,2000)); - + linphone_core_terminate_all_calls(pauline->lc); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallEnd,1,2000)); @@ -2438,10 +2324,6 @@ test_t call_tests[] = { { "Call established with rejected incoming RE-INVITE", call_established_with_rejected_incoming_reinvite }, { "Call established with rejected RE-INVITE in error", call_established_with_rejected_reinvite_with_error}, { "Call redirected by callee", call_redirect}, - { "Quality reporting not used if no config", quality_reporting_not_used_without_config}, - { "Quality reporting session report not sent if call did not start", quality_reporting_not_sent_if_call_not_started}, - { "Quality reporting session report sent if call ended normally", quality_reporting_at_call_termination}, - { "Quality reporting interval report if interval is configured", quality_reporting_interval_report}, { "Call with specified codec bitrate", call_with_specified_codec_bitrate} }; diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index 825e16727d..b11cbefaf9 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -147,7 +147,7 @@ return -1; \ int main (int argc, char *argv[]) { - int i,j; + int i; int ret; const char *suite_name=NULL; const char *test_name=NULL; @@ -189,10 +189,7 @@ int main (int argc, char *argv[]) CHECK_ARG("--suite", ++i, argc); suite_name=argv[i]; } else if (strcmp(argv[i],"--list-suites")==0){ - for(j=0;j<liblinphone_tester_nb_test_suites();j++) { - suite_name = liblinphone_tester_test_suite_name(j); - fprintf(stdout, "%s\n", suite_name); - } + liblinphone_tester_list_suites(); return 0; } else if (strcmp(argv[i],"--list-tests")==0){ CHECK_ARG("--list-tests", ++i, argc); @@ -206,21 +203,6 @@ int main (int argc, char *argv[]) } } - // Check arguments - if(suite_name != NULL) { - if(liblinphone_tester_test_suite_index(suite_name) == -1) { - fprintf(stderr, "Suite \"%s\" not found\n", suite_name); - return -1; - } - if(test_name != NULL) { - if(liblinphone_tester_test_index(suite_name, test_name) == -1) { - fprintf(stderr, "Test \"%s\" not found. Available tests are:\n", test_name); - liblinphone_tester_list_suite_tests(suite_name); - return -1; - } - } - } - ret = liblinphone_tester_run_tests(suite_name, test_name); liblinphone_tester_uninit(); return ret; diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 088f3a8e53..3d1cbc9532 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -57,12 +57,14 @@ extern test_suite_t event_test_suite; extern test_suite_t flexisip_test_suite; extern test_suite_t stun_test_suite; extern test_suite_t remote_provisioning_test_suite; +extern test_suite_t quality_reporting_test_suite; extern int liblinphone_tester_nb_test_suites(void); extern int liblinphone_tester_nb_tests(const char *suite_name); extern const char * liblinphone_tester_test_suite_name(int suite_index); extern int liblinphone_tester_test_suite_index(const char *suite_name); +extern void liblinphone_tester_list_suites(); extern void liblinphone_tester_list_suite_tests(const char *suite_name); extern const char * liblinphone_tester_test_name(const char *suite_name, int test_index); extern int liblinphone_tester_test_index(const char *suite_name, const char *test_name); @@ -229,6 +231,10 @@ bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value); bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms); bool_t wait_for_until(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value,int timout_ms); +bool_t call_with_params(LinphoneCoreManager* caller_mgr + ,LinphoneCoreManager* callee_mgr + , const LinphoneCallParams *caller_params + , const LinphoneCallParams *callee_params); bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr); stats * get_stats(LinphoneCore *lc); LinphoneCoreManager *get_manager(LinphoneCore *lc); diff --git a/tester/quality_reporting_tester.c b/tester/quality_reporting_tester.c new file mode 100644 index 0000000000..f098df204e --- /dev/null +++ b/tester/quality_reporting_tester.c @@ -0,0 +1,198 @@ +/* + 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 <stdio.h> +#include "CUnit/Basic.h" +#include "linphonecore.h" +#include "private.h" +#include "liblinphone_tester.h" + +void create_call_for_quality_reporting_tests( + LinphoneCoreManager* marie, + LinphoneCoreManager* pauline, + LinphoneCall** call_marie, + LinphoneCall** call_pauline) { + CU_ASSERT_TRUE(call(pauline,marie)); + *call_marie = linphone_core_get_current_call(marie->lc); + *call_pauline = linphone_core_get_current_call(pauline->lc); + CU_ASSERT_PTR_NOT_NULL(*call_marie); + CU_ASSERT_PTR_NOT_NULL(*call_pauline); +} + +static void quality_reporting_not_used_without_config() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + + create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); + + // marie has stats collection enabled since pauline has not + CU_ASSERT_TRUE(linphone_proxy_config_quality_reporting_enabled(call_marie->dest_proxy)); + CU_ASSERT_FALSE(linphone_proxy_config_quality_reporting_enabled(call_pauline->dest_proxy)); + + CU_ASSERT_EQUAL(strcmp("sip:collector@sip.example.org", + linphone_proxy_config_get_quality_reporting_collector(call_marie->dest_proxy)), 0); + + // this field should be already filled + CU_ASSERT_PTR_NOT_NULL(call_marie->log->reporting.reports[0]->info.local_addr.ip); + + // but not this one since it is updated at the end of call + CU_ASSERT_PTR_NULL(call_marie->log->reporting.reports[0]->dialog_id); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} +static void quality_reporting_not_sent_if_call_not_started() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCallLog* out_call_log; + LinphoneCall* out_call; + + linphone_core_set_max_calls(pauline->lc,0); + out_call = linphone_core_invite(marie->lc,"pauline"); + linphone_call_ref(out_call); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1, 10000)); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1); + + if (ms_list_size(linphone_core_get_call_logs(marie->lc))>0) { + out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data); + CU_ASSERT_PTR_NOT_NULL(out_call_log); + CU_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted); + } + linphone_call_unref(out_call); + + // wait a few time... + wait_for_until(marie->lc,NULL,NULL,0,1000); + + // since the callee was busy, there should be no publish to do + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} +static void quality_reporting_at_call_termination() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + + create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); + + linphone_core_terminate_all_calls(marie->lc); + + // now dialog id should be filled + CU_ASSERT_PTR_NOT_NULL(call_marie->log->reporting.reports[0]->dialog_id); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallReleased,1, 10000)); + CU_ASSERT_TRUE(wait_for_until(pauline->lc,NULL,&pauline->stat.number_of_LinphoneCallReleased,1, 10000)); + + CU_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); + CU_ASSERT_PTR_NULL(linphone_core_get_current_call(pauline->lc)); + + + // PUBLISH submission to the collector should be ok + CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1)); + CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishOk,1)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void quality_reporting_interval_report() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + + create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); + linphone_proxy_config_set_quality_reporting_interval(call_marie->dest_proxy, 3); + + CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc)); + CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); + + // PUBLISH submission to the collector should be ok + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,3,25000)); + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,3,25000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void quality_reporting_session_report_if_video_stopped() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + LinphoneCallParams* pauline_params; + LinphoneCallParams* marie_params; + + linphone_core_enable_video_capture(marie->lc, TRUE); + linphone_core_enable_video_display(marie->lc, FALSE); + linphone_core_enable_video_capture(pauline->lc, TRUE); + linphone_core_enable_video_display(pauline->lc, FALSE); + marie_params=linphone_core_create_default_call_parameters(marie->lc); + linphone_call_params_enable_video(marie_params,TRUE); + pauline_params=linphone_core_create_default_call_parameters(pauline->lc); + linphone_call_params_enable_video(pauline_params,TRUE); + CU_ASSERT_TRUE(call_with_params(pauline,marie,pauline_params,marie_params)); + call_marie=linphone_core_get_current_call(marie->lc); + call_pauline=linphone_core_get_current_call(pauline->lc); + + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,NULL,0,3000)); + CU_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); + + /*remove video*/ + linphone_call_params_enable_video(pauline_params,FALSE); + linphone_core_update_call(pauline->lc,call_pauline,pauline_params); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,5000)); + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,5000)); + + CU_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); + + linphone_core_terminate_all_calls(marie->lc); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,2,5000)); + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,2,5000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + + +test_t quality_reporting_tests[] = { + { "Not used if no config", quality_reporting_not_used_without_config}, + { "Call term session report not sent if call did not start", quality_reporting_not_sent_if_call_not_started}, + { "Call term session report sent if call ended normally", quality_reporting_at_call_termination}, + { "Interval report if interval is configured", quality_reporting_interval_report}, + { "Session report sent if video stopped during call", quality_reporting_session_report_if_video_stopped}, +}; + +test_suite_t quality_reporting_test_suite = { + "QualityReporting", + NULL, + NULL, + sizeof(quality_reporting_tests) / sizeof(quality_reporting_tests[0]), + quality_reporting_tests +}; diff --git a/tester/tester.c b/tester/tester.c index 1f1c8d7252..268a0f3027 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -291,6 +291,13 @@ int liblinphone_tester_test_suite_index(const char *suite_name) { return -1; } +void liblinphone_tester_list_suites() { + int j; + for(j=0;j<liblinphone_tester_nb_test_suites();j++) { + fprintf(stdout, "%s\n", liblinphone_tester_test_suite_name(j)); + } +} + void liblinphone_tester_list_suite_tests(const char *suite_name) { int j; for( j = 0; j < liblinphone_tester_nb_tests(suite_name); j++) { @@ -358,6 +365,7 @@ void liblinphone_tester_init(void) { add_test_suite(&event_test_suite); add_test_suite(&flexisip_test_suite); add_test_suite(&remote_provisioning_test_suite); + add_test_suite(&quality_reporting_test_suite); } void liblinphone_tester_uninit(void) { @@ -382,13 +390,25 @@ int liblinphone_tester_run_tests(const char *suite_name, const char *test_name) if (suite_name){ CU_pSuite suite; CU_basic_set_mode(CU_BRM_VERBOSE); - suite=CU_get_suite_by_name(suite_name, CU_get_registry()); - if (test_name) { + 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); - CU_ErrorCode err= CU_basic_run_test(suite, test); - if (err != CUE_SUCCESS) ms_error("CU_basic_run_test error %d", err); - } else + if (!test) { + ms_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 sentisitive + liblinphone_tester_list_suite_tests(suite->pName); + return -2; + } else { + CU_ErrorCode err= CU_basic_run_test(suite, test); + if (err != CUE_SUCCESS) ms_error("CU_basic_run_test error %d", err); + } + } else { CU_basic_run_suite(suite); + } } else { #if HAVE_CU_CURSES -- GitLab