eventapi_tester.c 14 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 42
	BC_ASSERT_PTR_NOT_NULL_FATAL(content);
	BC_ASSERT_TRUE(strcmp(notify_content,(const char*)linphone_content_get_buffer(content))==0);
43
	mgr=get_manager(lc);
44
	mgr->stat.number_of_NotifyReceived++;
45 46 47
}

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

58 59 60
	ms_message("Subscription state [%s] from [%s]",linphone_subscription_state_to_string(state),from);
	ms_free(from);

61 62 63 64 65
	switch(state){
		case LinphoneSubscriptionNone:
		break;
		case LinphoneSubscriptionIncomingReceived:
			counters->number_of_LinphoneSubscriptionIncomingReceived++;
66
			mgr->lev=lev;
67 68 69 70
			if (!mgr->decline_subscribe)
				linphone_event_accept_subscription(lev);
			else
				linphone_event_deny_subscription(lev, LinphoneReasonDeclined);
71
		break;
72
		case LinphoneSubscriptionOutgoingInit:
73 74 75 76 77 78 79
			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
80
			if (linphone_event_get_subscription_dir(lev)==LinphoneSubscriptionIncoming){
81
				mgr->lev=lev;
82
				linphone_event_notify(lev,content);
83
			}
84 85 86
		break;
		case LinphoneSubscriptionTerminated:
			counters->number_of_LinphoneSubscriptionTerminated++;
87
			mgr->lev=NULL;
88 89 90
		break;
		case LinphoneSubscriptionError:
			counters->number_of_LinphoneSubscriptionError++;
91
			mgr->lev=NULL;
92
		break;
93 94 95 96
		case LinphoneSubscriptionExpiring:
			counters->number_of_LinphoneSubscriptionExpiring++;
			mgr->lev=NULL;
		break;
97
	}
98
	linphone_content_unref(content);
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
		case LinphonePublishOk:
110
			/*make sure custom header access API is working*/
111 112
			BC_ASSERT_PTR_NOT_NULL(linphone_event_get_custom_header(ev,"From"));
			counters->number_of_LinphonePublishOk++;
113
			break;
114 115 116 117 118 119
		case LinphonePublishError: counters->number_of_LinphonePublishError++; break;
		case LinphonePublishExpiring: counters->number_of_LinphonePublishExpiring++; break;
		case LinphonePublishCleared: counters->number_of_LinphonePublishCleared++;break;
		default:
		break;
	}
120

121 122
}

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;
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
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
135
	linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content));
136

137
	pauline->decline_subscribe=TRUE;
138 139

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

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

	linphone_content_unref(content);
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;
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
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
182
	linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content));
183 184

	lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,content);
185 186 187 188 189

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

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

194
	if (refresh_type==AutoRefresh){
195
		wait_for_list(lcs,NULL,0,6000);
196
		BC_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
197
	}else if (refresh_type==ManualRefresh){
198
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
199
		linphone_event_update_subscribe(lev,NULL);
200
		BC_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
		BC_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
207 208
		linphone_event_terminate(pauline->lev);
	}
209

210 211
	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));
212 213

	linphone_content_unref(content);
214 215 216 217
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

218 219 220
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");
221
	LinphoneContent* content;
222 223 224
	LinphoneEvent *lev;
	int expires= refresh_type!=NoRefresh ? 4 : 600;
	MSList* lcs=ms_list_append(NULL,marie->lc);
225

226 227 228 229 230 231
	lcs=ms_list_append(lcs,pauline->lc);

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

232 233 234
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
235
	linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content));
236

237 238 239
	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");
240 241
	linphone_event_send_subscribe(lev,content);

242 243
	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));
244

245
	/*check good receipt of custom headers*/
246 247 248 249 250
	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");

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

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

255 256
	if (refresh_type==AutoRefresh){
		wait_for_list(lcs,NULL,0,6000);
257
		BC_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
258
	}else if (refresh_type==ManualRefresh){
259
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
260
		linphone_event_update_subscribe(lev,NULL);
261
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,5000));
262 263 264 265 266
	}

	if (terminated_by_subscriber){
		linphone_event_terminate(lev);
	}else{
267
		BC_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
268 269
		linphone_event_terminate(pauline->lev);
	}
270

271 272
	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));
273 274

	linphone_content_unref(content);
275 276 277 278
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

279
static void subscribe_test_terminated_by_subscriber(void){
280
	subscribe_test_with_args(TRUE,NoRefresh);
281 282 283
}

static void subscribe_test_terminated_by_notifier(void){
284
	subscribe_test_with_args(FALSE,NoRefresh);
285 286
}

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

294 295 296 297
static void subscribe_test_with_custom_header(void){
	subscribe_test_with_args2(TRUE,NoRefresh);
}

298 299
static void subscribe_test_manually_refreshed(void){
	subscribe_test_with_args(TRUE,ManualRefresh);
300 301
}

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

310 311 312
	content = linphone_core_create_content(marie->lc);
	linphone_content_set_type(content,"application");
	linphone_content_set_subtype(content,"somexml");
313
	linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content));
314

315
	lp_config_set_int(marie->lc->config,"sip","refresh_generic_publish",refresh);
316

Simon Morlat's avatar
Simon Morlat committed
317
	lev=linphone_core_create_publish(marie->lc,pauline->identity,"dodo",expires);
318
	linphone_event_add_custom_header(lev,"CustomHeader","someValue");
319
	linphone_event_send_publish(lev,content);
320
	linphone_event_ref(lev);
321

322 323
	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));
324

325
	if (!refresh){
326
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishExpiring,1,5000));
327
		linphone_event_update_publish(lev,content);
328 329
		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));
330
	}else{
331

332 333 334
	}

	linphone_event_terminate(lev);
335

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

338
	linphone_event_unref(lev);
339 340

	linphone_content_unref(content);
341 342 343 344 345
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

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

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

static void publish_without_expires(){
	publish_test_with_args(TRUE,-1);
355 356 357
}

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

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