eventapi_tester.c 14.6 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 "linphonecore.h"
#include "private.h"
23
#include "lpconfig.h"
24 25 26 27 28 29 30
#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
31 32 33 34 35 36 37 38
const char *liblinphone_tester_get_subscribe_content(void){
	return subscribe_content;
}

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

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

void linphone_subscription_state_change(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
52 53
	stats* counters = get_stats(lc);
	LinphoneCoreManager *mgr=get_manager(lc);
54
	LinphoneContent* content;
55 56
	const LinphoneAddress* from_addr = linphone_event_get_from(lev);
	char* from = linphone_address_as_string(from_addr);
57 58 59
	content = linphone_core_create_content(lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml2");
60
	linphone_content_set_buffer(content,notify_content,strlen(notify_content));
61

62 63 64
	ms_message("Subscription state [%s] from [%s]",linphone_subscription_state_to_string(state),from);
	ms_free(from);

65 66 67 68 69
	switch(state){
		case LinphoneSubscriptionNone:
		break;
		case LinphoneSubscriptionIncomingReceived:
			counters->number_of_LinphoneSubscriptionIncomingReceived++;
70
			mgr->lev=lev;
71 72 73 74
			if (!mgr->decline_subscribe)
				linphone_event_accept_subscription(lev);
			else
				linphone_event_deny_subscription(lev, LinphoneReasonDeclined);
75
		break;
76
		case LinphoneSubscriptionOutgoingInit:
77 78 79 80 81 82 83
			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
84
			if (linphone_event_get_subscription_dir(lev)==LinphoneSubscriptionIncoming){
85
				mgr->lev=lev;
86
				linphone_event_notify(lev,content);
87
			}
88 89 90
		break;
		case LinphoneSubscriptionTerminated:
			counters->number_of_LinphoneSubscriptionTerminated++;
91
			mgr->lev=NULL;
92 93 94
		break;
		case LinphoneSubscriptionError:
			counters->number_of_LinphoneSubscriptionError++;
95
			mgr->lev=NULL;
96
		break;
97 98 99 100
		case LinphoneSubscriptionExpiring:
			counters->number_of_LinphoneSubscriptionExpiring++;
			mgr->lev=NULL;
		break;
101
	}
102
	linphone_content_unref(content);
103 104
}

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

125 126
}

127
static void subscribe_test_declined(void) {
Simon Morlat's avatar
Simon Morlat committed
128
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
129
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
130
	LinphoneContent* content;
131 132
	LinphoneEvent *lev;
	const LinphoneErrorInfo *ei;
133 134
	MSList* lcs=ms_list_append(NULL,marie->lc);
	lcs=ms_list_append(lcs,pauline->lc);
135

136 137 138
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
139
	linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content));
140

141
	pauline->decline_subscribe=TRUE;
142 143

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

146 147 148
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
	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*/
149
	ei=linphone_event_get_error_info(lev);
150
	BC_ASSERT_PTR_NOT_NULL(ei);
151
	if (ei){
152 153
		BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),603, int, "%d");
		BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(ei));
154
	}
155
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
156 157

	linphone_content_unref(content);
158
	linphone_event_unref(lev);
159 160 161
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
162

163 164 165 166 167
typedef enum RefreshTestType{
	NoRefresh,
	AutoRefresh,
	ManualRefresh
}RefreshTestType;
168

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

177 178
	lcs=ms_list_append(lcs,pauline->lc);

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

183 184 185
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
186
	linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content));
187 188

	lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,content);
189 190 191 192 193

	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
	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));
194

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

198
	if (refresh_type==AutoRefresh){
199
		wait_for_list(lcs,NULL,0,6000);
200
		BC_ASSERT_EQUAL(linphone_event_get_subscription_state(pauline->lev), LinphoneSubscriptionActive, int, "%d");
201
	}else if (refresh_type==ManualRefresh){
202
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
203
		linphone_event_update_subscribe(lev,NULL);
204
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,2000));
205
	}
206

207 208 209
	if (terminated_by_subscriber){
		linphone_event_terminate(lev);
	}else{
210
		BC_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
211 212
		linphone_event_terminate(pauline->lev);
	}
213

214 215
	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));
216 217

	linphone_content_unref(content);
218 219 220 221
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

222 223
static void subscribe_test_with_args2(bool_t terminated_by_subscriber, RefreshTestType refresh_type) {
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
224
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
225
	LinphoneContent* content;
226 227 228
	LinphoneEvent *lev;
	int expires= refresh_type!=NoRefresh ? 4 : 600;
	MSList* lcs=ms_list_append(NULL,marie->lc);
229

230 231 232 233 234 235
	lcs=ms_list_append(lcs,pauline->lc);

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

236 237 238
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
239
	linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content));
240

241 242 243
	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");
244 245
	linphone_event_send_subscribe(lev,content);

246 247
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
248

249 250 251 252 253
	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");
	}
254 255
	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));
256 257

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

260 261
	if (refresh_type==AutoRefresh){
		wait_for_list(lcs,NULL,0,6000);
262
		BC_ASSERT_EQUAL(linphone_event_get_subscription_state(pauline->lev), LinphoneSubscriptionActive, int, "%d");
263
	}else if (refresh_type==ManualRefresh){
264
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
265
		linphone_event_update_subscribe(lev,NULL);
266
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,5000));
267 268 269 270 271
	}

	if (terminated_by_subscriber){
		linphone_event_terminate(lev);
	}else{
272
		BC_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
273 274
		linphone_event_terminate(pauline->lev);
	}
275

276 277
	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));
278 279

	linphone_content_unref(content);
280 281 282 283
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

284
static void subscribe_test_terminated_by_subscriber(void){
285
	subscribe_test_with_args(TRUE,NoRefresh);
286 287 288
}

static void subscribe_test_terminated_by_notifier(void){
289
	subscribe_test_with_args(FALSE,NoRefresh);
290 291
}

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

299 300 301 302
static void subscribe_test_with_custom_header(void){
	subscribe_test_with_args2(TRUE,NoRefresh);
}

303 304
static void subscribe_test_manually_refreshed(void){
	subscribe_test_with_args(TRUE,ManualRefresh);
305 306
}

Simon Morlat's avatar
Simon Morlat committed
307
static void publish_test_with_args(bool_t refresh, int expires){
308
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
309
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
310
	LinphoneContent* content;
311 312 313 314
	LinphoneEvent *lev;
	MSList* lcs=ms_list_append(NULL,marie->lc);
	lcs=ms_list_append(lcs,pauline->lc);

315 316 317
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
318
	linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content));
319

320
	lp_config_set_int(marie->lc->config,"sip","refresh_generic_publish",refresh);
321

Simon Morlat's avatar
Simon Morlat committed
322
	lev=linphone_core_create_publish(marie->lc,pauline->identity,"dodo",expires);
323
	linphone_event_add_custom_header(lev,"CustomHeader","someValue");
324
	linphone_event_send_publish(lev,content);
325
	linphone_event_ref(lev);
326

327 328
	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));
329

330
	if (!refresh){
331
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishExpiring,1,5000));
332
		linphone_event_update_publish(lev,content);
333 334
		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));
335
	}else{
336

337 338 339
	}

	linphone_event_terminate(lev);
340

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

343
	linphone_event_unref(lev);
344 345

	linphone_content_unref(content);
346 347 348 349
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

350
static void publish_test(void){
Simon Morlat's avatar
Simon Morlat committed
351
	publish_test_with_args(TRUE,5);
352 353
}

354
static void publish_no_auto_test(void){
Simon Morlat's avatar
Simon Morlat committed
355 356 357
	publish_test_with_args(FALSE,5);
}

358
static void publish_without_expires(void){
Simon Morlat's avatar
Simon Morlat committed
359
	publish_test_with_args(TRUE,-1);
360 361 362
}

test_t event_tests[] = {
363 364 365 366 367 368 369 370 371
	TEST_NO_TAG("Subscribe declined", subscribe_test_declined),
	TEST_NO_TAG("Subscribe terminated by subscriber", subscribe_test_terminated_by_subscriber),
	TEST_NO_TAG("Subscribe with custom headers", subscribe_test_with_custom_header),
	TEST_NO_TAG("Subscribe refreshed", subscribe_test_refreshed),
	TEST_NO_TAG("Subscribe manually refreshed", subscribe_test_manually_refreshed),
	TEST_NO_TAG("Subscribe terminated by notifier", subscribe_test_terminated_by_notifier),
	TEST_NO_TAG("Publish", publish_test),
	TEST_NO_TAG("Publish without expires", publish_without_expires),
	TEST_NO_TAG("Publish without automatic refresh",publish_no_auto_test)
372 373
};

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