eventapi_tester.c 24.7 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
#include "linphone/core.h"
#include "linphone/lpconfig.h"
23
#include <linphone/event.h>
24
#include "liblinphone_tester.h"
Benjamin REIS's avatar
Benjamin REIS committed
25
#include "tester_utils.h"
26 27 28 29

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

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

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

38
void linphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content){
39
	LinphoneCoreManager *mgr;
40
	const char * ua = linphone_event_get_custom_header(lev, "User-Agent");
41
	if (!BC_ASSERT_PTR_NOT_NULL(content)) return;
42
	if (!linphone_content_is_multipart(content) && (!ua ||  !strstr(ua, "flexisip"))) { /*disable check for full presence server support*/
43
		/*hack to disable content checking for list notify */
44
		BC_ASSERT_STRING_EQUAL(linphone_content_get_string_buffer(content), notify_content);
Ghislain MARY's avatar
Ghislain MARY committed
45
	}
46
	mgr = get_manager(lc);
47
	mgr->stat.number_of_NotifyReceived++;
48 49
}

50 51 52 53 54 55 56 57
void linphone_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content) {
	LinphoneCoreManager *mgr = get_manager(lc);
	if (!mgr->decline_subscribe)
		linphone_event_accept_subscription(lev);
	else
		linphone_event_deny_subscription(lev, LinphoneReasonDeclined);
}

58
void linphone_subscription_state_change(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
59 60
	stats* counters = get_stats(lc);
	LinphoneCoreManager *mgr=get_manager(lc);
61
	LinphoneContent* content;
62 63
	const LinphoneAddress* from_addr = linphone_event_get_from(lev);
	char* from = linphone_address_as_string(from_addr);
64 65 66
	content = linphone_core_create_content(lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml2");
67
	linphone_content_set_buffer(content,(const uint8_t *)notify_content,strlen(notify_content));
68

69 70 71
	ms_message("Subscription state [%s] from [%s]",linphone_subscription_state_to_string(state),from);
	ms_free(from);

72 73 74 75 76
	switch(state){
		case LinphoneSubscriptionNone:
		break;
		case LinphoneSubscriptionIncomingReceived:
			counters->number_of_LinphoneSubscriptionIncomingReceived++;
77
			mgr->lev=lev;
78
		break;
79 80
		case LinphoneSubscriptionOutgoingProgress:
			counters->number_of_LinphoneSubscriptionOutgoingProgress++;
81 82 83 84 85 86
		break;
		case LinphoneSubscriptionPending:
			counters->number_of_LinphoneSubscriptionPending++;
		break;
		case LinphoneSubscriptionActive:
			counters->number_of_LinphoneSubscriptionActive++;
Simon Morlat's avatar
Simon Morlat committed
87
			if (linphone_event_get_subscription_dir(lev)==LinphoneSubscriptionIncoming){
88
				mgr->lev=lev;
89
				if(strcmp(linphone_event_get_name(lev), "conference") == 0) {
90
					// TODO : Get LocalConfEventHandler and call handler->subscribeReceived(lev)
91 92 93
				} else {
					linphone_event_notify(lev,content);
				}
94
			}
95 96 97
		break;
		case LinphoneSubscriptionTerminated:
			counters->number_of_LinphoneSubscriptionTerminated++;
98
			mgr->lev=NULL;
99 100 101
		break;
		case LinphoneSubscriptionError:
			counters->number_of_LinphoneSubscriptionError++;
102
			mgr->lev=NULL;
103
		break;
104 105 106 107
		case LinphoneSubscriptionExpiring:
			counters->number_of_LinphoneSubscriptionExpiring++;
			mgr->lev=NULL;
		break;
108
	}
109
	linphone_content_unref(content);
110 111
}

112 113
void linphone_publish_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state){
	stats* counters = get_stats(lc);
114 115 116 117
	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);
118 119
	switch(state){
		case LinphonePublishProgress: counters->number_of_LinphonePublishProgress++; break;
120
		case LinphonePublishOk:
121
			/*make sure custom header access API is working*/
122 123
			BC_ASSERT_PTR_NOT_NULL(linphone_event_get_custom_header(ev,"From"));
			counters->number_of_LinphonePublishOk++;
124
			break;
125 126 127 128 129 130
		case LinphonePublishError: counters->number_of_LinphonePublishError++; break;
		case LinphonePublishExpiring: counters->number_of_LinphonePublishExpiring++; break;
		case LinphonePublishCleared: counters->number_of_LinphonePublishCleared++;break;
		default:
		break;
	}
131

132 133
}

134
static void subscribe_test_declined(void) {
Simon Morlat's avatar
Simon Morlat committed
135
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
136
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
137
	LinphoneContent* content;
138 139
	LinphoneEvent *lev;
	const LinphoneErrorInfo *ei;
140 141
	bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);
	lcs=bctbx_list_append(lcs,pauline->lc);
142

143 144 145
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
146
	linphone_content_set_buffer(content,(const uint8_t *)subscribe_content,strlen(subscribe_content));
147

148
	pauline->decline_subscribe=TRUE;
149 150

	lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",600,content);
151
	linphone_event_ref(lev);
152

153
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,1,1000));
154 155
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionError,1,21000));/*yes flexisip may wait 20 secs in case of forking*/
156
	ei=linphone_event_get_error_info(lev);
157
	BC_ASSERT_PTR_NOT_NULL(ei);
158
	if (ei){
159 160
		BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),603, int, "%d");
		BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(ei));
161
	}
162
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
163

164
	bctbx_list_free(lcs);
165
	linphone_content_unref(content);
166
	linphone_event_unref(lev);
167 168 169
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
170

171 172 173 174 175
typedef enum RefreshTestType{
	NoRefresh,
	AutoRefresh,
	ManualRefresh
}RefreshTestType;
176

177
static void subscribe_test_with_args(bool_t terminated_by_subscriber, RefreshTestType refresh_type) {
Simon Morlat's avatar
Simon Morlat committed
178
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
179
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
180
	LinphoneContent* content;
181
	LinphoneEvent *lev;
182
	int expires= refresh_type!=NoRefresh ? 4 : 600;
183
	bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);
184

185
	lcs=bctbx_list_append(lcs,pauline->lc);
186

187
	if (refresh_type==ManualRefresh){
188
		lp_config_set_int(linphone_core_get_config(marie->lc),"sip","refresh_generic_subscribe",0);
189
	}
190

191 192 193
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
194
	linphone_content_set_buffer(content,(const uint8_t *)subscribe_content,strlen(subscribe_content));
195 196

	lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,content);
197
	linphone_event_ref(lev);
198
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,1,1000));
199 200 201
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,3000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,1000));
202

203
	/*make sure marie receives first notification before terminating*/
204
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000));
205

206
	if (refresh_type==AutoRefresh){
207
		wait_for_list(lcs,NULL,0,6000);
208 209 210 211
		BC_ASSERT_PTR_NOT_NULL(pauline->lev);
		if (pauline->lev){
			BC_ASSERT_EQUAL(linphone_event_get_subscription_state(pauline->lev), LinphoneSubscriptionActive, int, "%d");
		}
212
	}else if (refresh_type==ManualRefresh){
213
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
214
		linphone_event_update_subscribe(lev,NULL);
215
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,2000));
216
	}
217

218 219 220
	if (terminated_by_subscriber){
		linphone_event_terminate(lev);
	}else{
221
		BC_ASSERT_PTR_NOT_NULL(pauline->lev);
222 223
		linphone_event_terminate(pauline->lev);
	}
224

225 226
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
227

228
	bctbx_list_free(lcs);
229
	linphone_event_unref(lev);
230
	linphone_content_unref(content);
231 232 233 234
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

235 236
static void subscribe_test_with_args2(bool_t terminated_by_subscriber, RefreshTestType refresh_type) {
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
237
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
238
	LinphoneContent* content;
239 240
	LinphoneEvent *lev;
	int expires= refresh_type!=NoRefresh ? 4 : 600;
241
	bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);
242

243
	lcs=bctbx_list_append(lcs,pauline->lc);
244 245

	if (refresh_type==ManualRefresh){
246
		lp_config_set_int(linphone_core_get_config(marie->lc),"sip","refresh_generic_subscribe",0);
247 248
	}

249 250 251
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
252
	linphone_content_set_buffer(content,(const uint8_t *)subscribe_content,strlen(subscribe_content));
253

254 255 256
	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");
257 258
	linphone_event_send_subscribe(lev,content);

259
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,1,1000));
260
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
261

262 263 264 265 266
	if (pauline->stat.number_of_LinphoneSubscriptionIncomingReceived == 1) {
		/*check good receipt of custom headers*/
		BC_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header"),"pouet");
		BC_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header2"),"pimpon");
	}
267 268
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,5000));
269 270

	/*make sure marie receives first notification before terminating*/
271 272
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,5000));

273 274
	if (refresh_type==AutoRefresh){
		wait_for_list(lcs,NULL,0,6000);
275
		BC_ASSERT_EQUAL(linphone_event_get_subscription_state(pauline->lev), LinphoneSubscriptionActive, int, "%d");
276
	}else if (refresh_type==ManualRefresh){
277
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
278
		linphone_event_update_subscribe(lev,NULL);
279
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,5000));
280 281 282 283 284
	}

	if (terminated_by_subscriber){
		linphone_event_terminate(lev);
	}else{
285
		BC_ASSERT_PTR_NOT_NULL(pauline->lev);
286 287
		linphone_event_terminate(pauline->lev);
	}
288

289 290
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
291 292

	linphone_content_unref(content);
293 294
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
295
	bctbx_list_free(lcs);
296 297
}

298
static void subscribe_test_terminated_by_subscriber(void){
299
	subscribe_test_with_args(TRUE,NoRefresh);
300 301 302
}

static void subscribe_test_terminated_by_notifier(void){
303
	subscribe_test_with_args(FALSE,NoRefresh);
304 305
}

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

313 314 315 316
static void subscribe_test_with_custom_header(void){
	subscribe_test_with_args2(TRUE,NoRefresh);
}

317 318
static void subscribe_test_manually_refreshed(void){
	subscribe_test_with_args(TRUE,ManualRefresh);
319 320
}

321
static void subscribe_loosing_dialog(void) {
322 323 324 325 326 327
#ifdef WIN32
	/*Unfortunately this test doesn't work on windows due to the way closed TCP ports behave.
	 * Unlike linux and macOS, released TCP port don't send an ICMP error (or maybe at least for a period of time.
	 * This prevents this test from working, see comments below*/
	ms_warning("subscribe_loosing_dialog() skipped on windows.");
#else
328 329 330 331 332 333 334 335 336 337 338 339
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
	LinphoneContent* content;
	LinphoneEvent *lev;
	int expires= 4;
	bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);

	lcs=bctbx_list_append(lcs,pauline->lc);

	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
340
	linphone_content_set_buffer(content,(const uint8_t *)subscribe_content,strlen(subscribe_content));
341 342 343 344 345 346 347 348 349

	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);

	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,1,1000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));

Benjamin REIS's avatar
Benjamin REIS committed
350

351 352 353 354 355 356 357 358 359 360 361 362 363 364
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,5000));

	/*make sure marie receives first notification before terminating*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,5000));

	/* now pauline looses internet connection and reboots */
	linphone_core_set_network_reachable(pauline->lc, FALSE);
	/*let expire the incoming subscribe received by pauline */
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
	lcs = bctbx_list_remove(lcs, pauline->lc);
	linphone_core_manager_destroy(pauline);
	pauline = linphone_core_manager_new( "pauline_tcp_rc");
	lcs = bctbx_list_append(lcs, pauline->lc);
Benjamin REIS's avatar
Benjamin REIS committed
365

366 367 368
	/* Marie will retry the subscription.
	 * She will first receive a 503 Service unavailable from flexisip thanks the ICMP error returned by the no longer existing Pauline.
	 * Then she will forge a new SUBSCRIBE in order to restart a new dialog, and this one will reach the new Pauline.*/
369 370 371 372
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,2,8000));
	/*and get it accepted again*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,5000));
373 374
	BC_ASSERT_PTR_NOT_NULL(pauline->lev);
	if (pauline->lev) BC_ASSERT_EQUAL(linphone_event_get_subscription_state(pauline->lev), LinphoneSubscriptionActive, int, "%d");
Benjamin REIS's avatar
Benjamin REIS committed
375

376 377
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,2,5000));
	linphone_event_terminate(lev);
Benjamin REIS's avatar
Benjamin REIS committed
378

379 380 381 382 383 384 385 386

	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,5000));

	linphone_content_unref(content);
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
	bctbx_list_free(lcs);
387
#endif
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
}

static void subscribe_with_io_error(void) {
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
	LinphoneContent* content;
	LinphoneEvent *lev;
	int expires= 4;
	bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);

	lcs=bctbx_list_append(lcs,pauline->lc);

	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
403
	linphone_content_set_buffer(content,(const uint8_t *)subscribe_content,strlen(subscribe_content));
404 405 406 407 408 409 410 411 412

	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);

	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,1,1000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));

Benjamin REIS's avatar
Benjamin REIS committed
413

414 415 416 417 418 419 420
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,5000));

	/*make sure marie receives first notification before terminating*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,5000));

	/* now marie gets network errors when refreshing*/
421
	sal_set_send_error(linphone_core_get_sal(marie->lc), -1);
Benjamin REIS's avatar
Benjamin REIS committed
422

423 424
	/*marie will retry the subscription*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,2,8000));
425
	sal_set_send_error(linphone_core_get_sal(marie->lc), 0);
Benjamin REIS's avatar
Benjamin REIS committed
426

427 428 429 430 431 432
	/*and get it accepted again*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,10000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,2,5000));
	BC_ASSERT_EQUAL(linphone_event_get_subscription_state(pauline->lev), LinphoneSubscriptionActive, int, "%d");
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,2,5000));
	linphone_event_terminate(lev);
Benjamin REIS's avatar
Benjamin REIS committed
433

434 435 436 437 438 439 440 441 442 443

	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,5000));

	linphone_content_unref(content);
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
	bctbx_list_free(lcs);
}

444 445 446 447 448 449 450 451 452 453 454 455 456
static void subscribe_not_timely_responded(void) {
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
	LinphoneContent* content;
	LinphoneEvent *lev;
	int expires= 4;
	bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);

	lcs=bctbx_list_append(lcs,pauline->lc);

	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
457
	linphone_content_set_buffer(content,(const uint8_t *)subscribe_content,strlen(subscribe_content));
458 459 460 461 462 463 464 465 466

	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);

	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,1,1000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));

Benjamin REIS's avatar
Benjamin REIS committed
467

468 469 470 471 472 473 474 475 476 477
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,5000));

	/*make sure marie receives first notification before terminating*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,5000));

	/* now pauline is no longer scheduled (simulating a very big latency in the network) */
	lcs = bctbx_list_remove(lcs, pauline->lc);
	/*marie's dialog will expire while the SUBSCRIBE refresh is in progress*/
	wait_for_list(lcs, NULL, 0, 8000);
Benjamin REIS's avatar
Benjamin REIS committed
478

479 480 481 482 483 484 485 486 487 488 489 490
	lcs = bctbx_list_append(lcs, pauline->lc);
	wait_for_list(lcs, NULL, 0, 3000);
	linphone_event_terminate(lev);
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,5000));

	linphone_content_unref(content);
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
	bctbx_list_free(lcs);
}

491

492
static void publish_test_with_args(bool_t refresh, int expires){
493
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
494
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
495
	LinphoneContent* content;
496
	LinphoneEvent *lev;
497 498
	bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);
	lcs=bctbx_list_append(lcs,pauline->lc);
499

500 501 502
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
503
	linphone_content_set_buffer(content,(const uint8_t *)subscribe_content,strlen(subscribe_content));
504

505
	lp_config_set_int(linphone_core_get_config(marie->lc),"sip","refresh_generic_publish",refresh);
506

507
	lev=linphone_core_create_publish(marie->lc,pauline->identity,"dodo",expires);
508
	linphone_event_add_custom_header(lev,"CustomHeader","someValue");
509
	linphone_event_ref(lev);
510
	linphone_event_send_publish(lev,content);
Benjamin REIS's avatar
Benjamin REIS committed
511

512

513 514
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
515

516
	if (!refresh){
517
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishExpiring,1,5000));
518
		linphone_event_update_publish(lev,content);
519 520
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000));
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
521
	}else{
522

523 524 525
	}

	linphone_event_terminate(lev);
526

527
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishCleared,1,3000));
528

529
	linphone_event_unref(lev);
530 531

	linphone_content_unref(content);
532 533 534 535
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

536
static void publish_test(void){
537
	publish_test_with_args(TRUE,5);
538 539
}

540
static void publish_no_auto_test(void){
541 542 543
	publish_test_with_args(FALSE,5);
}

544
static void publish_without_expires(void){
545
	publish_test_with_args(TRUE,-1);
546 547
}

548 549 550 551 552
static void out_of_dialog_notify(void){
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
	LinphoneContent* content;
	LinphoneEvent *lev;
553 554
	bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc);
	lcs=bctbx_list_append(lcs,pauline->lc);
555 556 557 558

	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
559
	linphone_content_set_buffer(content,(const uint8_t *)notify_content,strlen(notify_content));
560 561 562 563 564

	lev = linphone_core_create_notify(marie->lc,pauline->identity,"dodo");
	linphone_event_ref(lev);
	linphone_event_add_custom_header(lev,"CustomHeader","someValue");
	linphone_event_notify(lev,content);
Benjamin REIS's avatar
Benjamin REIS committed
565

566 567 568 569 570 571 572 573 574 575 576

	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_NotifyReceived,1,3000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,3000));

	linphone_event_unref(lev);

	linphone_content_unref(content);
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

577
test_t event_tests[] = {
578
	TEST_ONE_TAG("Subscribe declined", subscribe_test_declined, "presence"),
jehan's avatar
jehan committed
579
	TEST_ONE_TAG("Subscribe terminated by subscriber", subscribe_test_terminated_by_subscriber, "presence"),
580
	TEST_ONE_TAG("Subscribe with custom headers", subscribe_test_with_custom_header, "presence"),
jehan's avatar
jehan committed
581
	TEST_ONE_TAG("Subscribe refreshed", subscribe_test_refreshed, "presence"),
582 583
	TEST_ONE_TAG("Subscribe loosing dialog", subscribe_loosing_dialog, "presence"),
	TEST_ONE_TAG("Subscribe with io error", subscribe_with_io_error, "presence"),
jehan's avatar
jehan committed
584
	TEST_ONE_TAG("Subscribe manually refreshed", subscribe_test_manually_refreshed, "presence"),
585
	TEST_ONE_TAG("Subscribe terminated by notifier", subscribe_test_terminated_by_notifier, "presence"),
586
	TEST_ONE_TAG("Subscribe not timely responded", subscribe_not_timely_responded, "presence"),
587 588
	TEST_ONE_TAG("Publish", publish_test, "presence"),
	TEST_ONE_TAG("Publish without expires", publish_without_expires, "presence"),
589 590
	TEST_ONE_TAG("Publish without automatic refresh",publish_no_auto_test, "presence"),
	TEST_ONE_TAG("Out of dialog notify", out_of_dialog_notify, "presence")
591 592
};

593
test_suite_t event_test_suite = {"Event", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
594
								 sizeof(event_tests) / sizeof(event_tests[0]), event_tests};