eventapi_tester.c 13.5 KB
Newer Older
1
/*
Simon Morlat's avatar
Simon Morlat committed
2 3
    liblinphone_tester - liblinphone test suite
    Copyright (C) 2013  Belledonne Communications SARL
4 5 6

    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
Simon Morlat's avatar
Simon Morlat committed
7
    the Free Software Foundation, either version 2 of the License, or
8 9 10 11 12 13 14 15 16 17 18
    (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/>.
*/

Simon Morlat's avatar
Simon Morlat committed
19

20 21 22 23
#include <stdio.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "private.h"
24
#include "lpconfig.h"
25 26 27 28 29 30 31
#include <event.h>
#include "liblinphone_tester.h"


static const char *subscribe_content="<somexml>blabla</somexml>";
static const char *notify_content="<somexml2>blabla</somexml2>";

Simon Morlat's avatar
Simon Morlat committed
32 33 34 35 36 37 38 39
const char *liblinphone_tester_get_subscribe_content(void){
	return subscribe_content;
}

const char *liblinphone_tester_get_notify_content(void){
	return notify_content;
}

40
void linphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content){
41
	LinphoneCoreManager *mgr;
42 43
	CU_ASSERT_PTR_NOT_NULL_FATAL(content);
	CU_ASSERT_TRUE(strcmp(notify_content,(const char*)content->data)==0);
44
	mgr=get_manager(lc);
45
	mgr->stat.number_of_NotifyReceived++;
46 47 48
}

void linphone_subscription_state_change(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
49 50
	stats* counters = get_stats(lc);
	LinphoneCoreManager *mgr=get_manager(lc);
51
	LinphoneContent content={0};
52 53
	const LinphoneAddress* from_addr = linphone_event_get_from(lev);
	char* from = linphone_address_as_string(from_addr);
54 55 56 57 58
	content.type="application";
	content.subtype="somexml2";
	content.data=(void*)notify_content;
	content.size=strlen(notify_content);
	
59 60 61
	ms_message("Subscription state [%s] from [%s]",linphone_subscription_state_to_string(state),from);
	ms_free(from);

62 63 64 65 66
	switch(state){
		case LinphoneSubscriptionNone:
		break;
		case LinphoneSubscriptionIncomingReceived:
			counters->number_of_LinphoneSubscriptionIncomingReceived++;
67
			mgr->lev=lev;
68 69 70 71
			if (!mgr->decline_subscribe)
				linphone_event_accept_subscription(lev);
			else
				linphone_event_deny_subscription(lev, LinphoneReasonDeclined);
72
		break;
73
		case LinphoneSubscriptionOutgoingInit:
74 75 76 77 78 79 80
			counters->number_of_LinphoneSubscriptionOutgoingInit++;
		break;
		case LinphoneSubscriptionPending:
			counters->number_of_LinphoneSubscriptionPending++;
		break;
		case LinphoneSubscriptionActive:
			counters->number_of_LinphoneSubscriptionActive++;
Simon Morlat's avatar
Simon Morlat committed
81
			if (linphone_event_get_subscription_dir(lev)==LinphoneSubscriptionIncoming){
82
				mgr->lev=lev;
83
				linphone_event_notify(lev,&content);
84
			}
85 86 87
		break;
		case LinphoneSubscriptionTerminated:
			counters->number_of_LinphoneSubscriptionTerminated++;
88
			mgr->lev=NULL;
89 90 91
		break;
		case LinphoneSubscriptionError:
			counters->number_of_LinphoneSubscriptionError++;
92
			mgr->lev=NULL;
93
		break;
94 95 96 97
		case LinphoneSubscriptionExpiring:
			counters->number_of_LinphoneSubscriptionExpiring++;
			mgr->lev=NULL;
		break;
98 99 100
	}
}

101 102
void linphone_publish_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state){
	stats* counters = get_stats(lc);
103 104 105 106
	const LinphoneAddress* from_addr = linphone_event_get_from(ev);
	char* from = linphone_address_as_string(from_addr);
	ms_message("Publish state [%s] from [%s]",linphone_publish_state_to_string(state),from);
	ms_free(from);
107 108
	switch(state){
		case LinphonePublishProgress: counters->number_of_LinphonePublishProgress++; break;
109 110 111 112 113
		case LinphonePublishOk: 
			/*make sure custom header access API is working*/
			CU_ASSERT_PTR_NOT_NULL(linphone_event_get_custom_header(ev,"From"));
			counters->number_of_LinphonePublishOk++; 
			break;
114 115 116 117 118 119 120 121 122
		case LinphonePublishError: counters->number_of_LinphonePublishError++; break;
		case LinphonePublishExpiring: counters->number_of_LinphonePublishExpiring++; break;
		case LinphonePublishCleared: counters->number_of_LinphonePublishCleared++;break;
		default:
		break;
	}
	
}

123
static void subscribe_test_declined(void) {
Simon Morlat's avatar
Simon Morlat committed
124 125
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
126
	LinphoneContent content={0};
127 128
	LinphoneEvent *lev;
	const LinphoneErrorInfo *ei;
129 130
	MSList* lcs=ms_list_append(NULL,marie->lc);
	lcs=ms_list_append(lcs,pauline->lc);
131 132


133 134 135 136 137 138 139
	content.type="application";
	content.subtype="somexml";
	content.data=(char*)subscribe_content;
	content.size=strlen(subscribe_content);
	
	pauline->decline_subscribe=TRUE;
	
140 141
	lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",600,&content);
	linphone_event_ref(lev);
142 143
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
144
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
145
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionError,1,21000));/*yes flexisip may wait 20 secs in case of forking*/
146 147 148 149 150 151
	ei=linphone_event_get_error_info(lev);
	CU_ASSERT_PTR_NOT_NULL(ei);
	if (ei){
		CU_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),603);
		CU_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(ei));
	}
152 153
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
	
154
	linphone_event_unref(lev);
155 156 157
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
158

159 160 161 162 163
typedef enum RefreshTestType{
	NoRefresh,
	AutoRefresh,
	ManualRefresh
}RefreshTestType;
164

165
static void subscribe_test_with_args(bool_t terminated_by_subscriber, RefreshTestType refresh_type) {
Simon Morlat's avatar
Simon Morlat committed
166 167
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
168
	LinphoneContent content={0};
169
	LinphoneEvent *lev;
170
	int expires= refresh_type!=NoRefresh ? 4 : 600;
171
	MSList* lcs=ms_list_append(NULL,marie->lc);
172
	
173 174
	lcs=ms_list_append(lcs,pauline->lc);

175 176 177
	if (refresh_type==ManualRefresh){
		lp_config_set_int(marie->lc->config,"sip","refresh_generic_subscribe",0);
	}
178

179 180 181 182 183
	content.type="application";
	content.subtype="somexml";
	content.data=(char*)subscribe_content;
	content.size=strlen(subscribe_content);
	
184
	lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,&content);
185 186
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
187 188
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,3000));
189 190
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,1000));

191 192
	/*make sure marie receives first notification before terminating*/
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000));
193
	
194
	if (refresh_type==AutoRefresh){
195 196
		wait_for_list(lcs,NULL,0,6000);
		CU_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
197 198 199
	}else if (refresh_type==ManualRefresh){
		CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
		linphone_event_update_subscribe(lev,NULL);
Simon Morlat's avatar
Simon Morlat committed
200
		CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,2000));
201
	}
202

203 204 205
	if (terminated_by_subscriber){
		linphone_event_terminate(lev);
	}else{
206
		CU_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
207 208 209 210 211
		linphone_event_terminate(pauline->lev);
	}
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
212 213 214 215 216
	
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
static void subscribe_test_with_args2(bool_t terminated_by_subscriber, RefreshTestType refresh_type) {
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
	LinphoneContent content={0};
	LinphoneEvent *lev;
	int expires= refresh_type!=NoRefresh ? 4 : 600;
	MSList* lcs=ms_list_append(NULL,marie->lc);
	
	lcs=ms_list_append(lcs,pauline->lc);

	if (refresh_type==ManualRefresh){
		lp_config_set_int(marie->lc->config,"sip","refresh_generic_subscribe",0);
	}

	content.type="application";
	content.subtype="somexml";
	content.data=(char*)subscribe_content;
	content.size=strlen(subscribe_content);
	
	lev=linphone_core_create_subscribe(marie->lc,pauline->identity,"dodo",expires);
	linphone_event_add_custom_header(lev,"My-Header","pouet");
	linphone_event_add_custom_header(lev,"My-Header2","pimpon");
	linphone_event_send_subscribe(lev,&content);
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
242
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
	
	/*check good receipt of custom headers*/
	CU_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header"),"pouet");
	CU_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header2"),"pimpon");
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,1000));
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,1000));

	/*make sure marie receives first notification before terminating*/
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000));
	
	if (refresh_type==AutoRefresh){
		wait_for_list(lcs,NULL,0,6000);
		CU_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
	}else if (refresh_type==ManualRefresh){
		CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
		linphone_event_update_subscribe(lev,NULL);
		CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,2000));
	}

	if (terminated_by_subscriber){
		linphone_event_terminate(lev);
	}else{
		CU_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
		linphone_event_terminate(pauline->lev);
	}
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
	
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

277
static void subscribe_test_terminated_by_subscriber(void){
278
	subscribe_test_with_args(TRUE,NoRefresh);
279 280 281
}

static void subscribe_test_terminated_by_notifier(void){
282
	subscribe_test_with_args(FALSE,NoRefresh);
283 284 285 286 287 288
}

/* Caution: this test does not really check that the subscribe are refreshed, because the core is not managing the expiration of 
 * unrefreshed subscribe dialogs. So it is just checking that it is not crashing.
 */
static void subscribe_test_refreshed(void){
289 290 291
	subscribe_test_with_args(TRUE,AutoRefresh);
}

292 293 294 295
static void subscribe_test_with_custom_header(void){
	subscribe_test_with_args2(TRUE,NoRefresh);
}

296 297
static void subscribe_test_manually_refreshed(void){
	subscribe_test_with_args(TRUE,ManualRefresh);
298 299
}

Simon Morlat's avatar
Simon Morlat committed
300
static void publish_test_with_args(bool_t refresh, int expires){
301 302
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
303
	LinphoneContent content={0};
304 305 306 307 308 309 310 311 312 313
	LinphoneEvent *lev;
	MSList* lcs=ms_list_append(NULL,marie->lc);
	lcs=ms_list_append(lcs,pauline->lc);


	content.type="application";
	content.subtype="somexml";
	content.data=(char*)subscribe_content;
	content.size=strlen(subscribe_content);
	
314
	lp_config_set_int(marie->lc->config,"sip","refresh_generic_publish",refresh);
315

Simon Morlat's avatar
Simon Morlat committed
316
	lev=linphone_core_create_publish(marie->lc,pauline->identity,"dodo",expires);
317 318
	linphone_event_add_custom_header(lev,"CustomHeader","someValue");
	linphone_event_send_publish(lev,&content);
319 320 321
	linphone_event_ref(lev);
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000));
322
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
323 324 325 326 327
	
	if (!refresh){
		CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishExpiring,1,5000));
		linphone_event_update_publish(lev,&content);
		CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000));
328
		CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
329 330 331 332 333 334
	}else{
		
	}

	linphone_event_terminate(lev);
	
335
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishCleared,1,3000));
336 337 338 339 340 341 342 343
	
	linphone_event_unref(lev);
	
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

static void publish_test(){
Simon Morlat's avatar
Simon Morlat committed
344
	publish_test_with_args(TRUE,5);
345 346 347
}

static void publish_no_auto_test(){
Simon Morlat's avatar
Simon Morlat committed
348 349 350 351 352
	publish_test_with_args(FALSE,5);
}

static void publish_without_expires(){
	publish_test_with_args(TRUE,-1);
353 354 355
}

test_t event_tests[] = {
356 357
	{ "Subscribe declined"	,	subscribe_test_declined 	},
	{ "Subscribe terminated by subscriber", subscribe_test_terminated_by_subscriber },
358
	{ "Subscribe with custom headers", subscribe_test_with_custom_header },
359
	{ "Subscribe refreshed", subscribe_test_refreshed },
360
	{ "Subscribe manually refreshed", subscribe_test_manually_refreshed },
361 362
	{ "Subscribe terminated by notifier", subscribe_test_terminated_by_notifier },
	{ "Publish", publish_test },
Simon Morlat's avatar
Simon Morlat committed
363
	{ "Publish without expires", publish_without_expires },
364
	{ "Publish without automatic refresh",publish_no_auto_test }
365 366
};

367 368
test_suite_t event_test_suite = {
	"Event",
369 370
	NULL,
	NULL,
371 372
	sizeof(event_tests) / sizeof(event_tests[0]),
	event_tests
373 374
};