eventapi_tester.c 13 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 42
	CU_ASSERT_PTR_NOT_NULL_FATAL(content);
	CU_ASSERT_TRUE(strcmp(notify_content,(const char*)content->data)==0);
43 44
	LinphoneCoreManager *mgr=get_manager(lc);
	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={0};
51 52 53 54 55 56 57 58 59 60 61
	
	content.type="application";
	content.subtype="somexml2";
	content.data=(void*)notify_content;
	content.size=strlen(notify_content);
	
	switch(state){
		case LinphoneSubscriptionNone:
		break;
		case LinphoneSubscriptionIncomingReceived:
			counters->number_of_LinphoneSubscriptionIncomingReceived++;
62
			mgr->lev=lev;
63 64 65 66
			if (!mgr->decline_subscribe)
				linphone_event_accept_subscription(lev);
			else
				linphone_event_deny_subscription(lev, LinphoneReasonDeclined);
67
		break;
68
		case LinphoneSubscriptionOutgoingInit:
69 70 71 72 73 74 75
			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
76
			if (linphone_event_get_subscription_dir(lev)==LinphoneSubscriptionIncoming){
77
				mgr->lev=lev;
78
				linphone_event_notify(lev,&content);
79
			}
80 81 82
		break;
		case LinphoneSubscriptionTerminated:
			counters->number_of_LinphoneSubscriptionTerminated++;
83
			mgr->lev=NULL;
84 85 86
		break;
		case LinphoneSubscriptionError:
			counters->number_of_LinphoneSubscriptionError++;
87
			mgr->lev=NULL;
88
		break;
89 90 91 92
		case LinphoneSubscriptionExpiring:
			counters->number_of_LinphoneSubscriptionExpiring++;
			mgr->lev=NULL;
		break;
93 94 95
	}
}

96 97 98 99
void linphone_publish_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state){
	stats* counters = get_stats(lc);
	switch(state){
		case LinphonePublishProgress: counters->number_of_LinphonePublishProgress++; break;
100 101 102 103 104
		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;
105 106 107 108 109 110 111 112 113
		case LinphonePublishError: counters->number_of_LinphonePublishError++; break;
		case LinphonePublishExpiring: counters->number_of_LinphonePublishExpiring++; break;
		case LinphonePublishCleared: counters->number_of_LinphonePublishCleared++;break;
		default:
		break;
	}
	
}

114
static void subscribe_test_declined(void) {
Simon Morlat's avatar
Simon Morlat committed
115 116
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
117
	LinphoneContent content={0};
118 119
	LinphoneEvent *lev;
	const LinphoneErrorInfo *ei;
120 121
	MSList* lcs=ms_list_append(NULL,marie->lc);
	lcs=ms_list_append(lcs,pauline->lc);
122 123


124 125 126 127 128 129 130
	content.type="application";
	content.subtype="somexml";
	content.data=(char*)subscribe_content;
	content.size=strlen(subscribe_content);
	
	pauline->decline_subscribe=TRUE;
	
131 132
	lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",600,&content);
	linphone_event_ref(lev);
133 134 135
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000));
136
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionError,1,21000));/*yes flexisip may wait 20 secs in case of forking*/
137 138 139 140 141 142
	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));
	}
143 144
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
	
145
	linphone_event_unref(lev);
146 147 148
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
149

150 151 152 153 154
typedef enum RefreshTestType{
	NoRefresh,
	AutoRefresh,
	ManualRefresh
}RefreshTestType;
155

156
static void subscribe_test_with_args(bool_t terminated_by_subscriber, RefreshTestType refresh_type) {
Simon Morlat's avatar
Simon Morlat committed
157 158
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
159
	LinphoneContent content={0};
160
	LinphoneEvent *lev;
161
	int expires= refresh_type!=NoRefresh ? 4 : 600;
162
	MSList* lcs=ms_list_append(NULL,marie->lc);
163
	
164 165
	lcs=ms_list_append(lcs,pauline->lc);

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

170 171 172 173 174
	content.type="application";
	content.subtype="somexml";
	content.data=(char*)subscribe_content;
	content.size=strlen(subscribe_content);
	
175
	lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,&content);
176 177 178 179 180 181
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000));
	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));

182 183
	/*make sure marie receives first notification before terminating*/
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000));
184
	
185
	if (refresh_type==AutoRefresh){
186 187
		wait_for_list(lcs,NULL,0,6000);
		CU_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
188 189 190
	}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
191
		CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,2000));
192
	}
193

194 195 196
	if (terminated_by_subscriber){
		linphone_event_terminate(lev);
	}else{
197
		CU_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
198 199 200 201 202
		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));
203 204 205 206 207
	
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

208 209 210 211 212 213 214 215 216 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 242 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
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));
	CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000));
	
	/*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);
}

268
static void subscribe_test_terminated_by_subscriber(void){
269
	subscribe_test_with_args(TRUE,NoRefresh);
270 271 272
}

static void subscribe_test_terminated_by_notifier(void){
273
	subscribe_test_with_args(FALSE,NoRefresh);
274 275 276 277 278 279
}

/* 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){
280 281 282
	subscribe_test_with_args(TRUE,AutoRefresh);
}

283 284 285 286
static void subscribe_test_with_custom_header(void){
	subscribe_test_with_args2(TRUE,NoRefresh);
}

287 288
static void subscribe_test_manually_refreshed(void){
	subscribe_test_with_args(TRUE,ManualRefresh);
289 290
}

Simon Morlat's avatar
Simon Morlat committed
291
static void publish_test_with_args(bool_t refresh, int expires){
292 293
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
294
	LinphoneContent content={0};
295 296 297 298 299 300 301 302 303 304
	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);
	
305
	lp_config_set_int(marie->lc->config,"sip","refresh_generic_publish",refresh);
306

Simon Morlat's avatar
Simon Morlat committed
307
	lev=linphone_core_create_publish(marie->lc,pauline->identity,"dodo",expires);
308 309
	linphone_event_add_custom_header(lev,"CustomHeader","someValue");
	linphone_event_send_publish(lev,&content);
310 311 312
	linphone_event_ref(lev);
	
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000));
313
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
314 315 316 317 318
	
	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));
319
		CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
320 321 322 323 324 325
	}else{
		
	}

	linphone_event_terminate(lev);
	
326
	CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishCleared,1,3000));
327 328 329 330 331 332 333 334
	
	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
335
	publish_test_with_args(TRUE,5);
336 337 338
}

static void publish_no_auto_test(){
Simon Morlat's avatar
Simon Morlat committed
339 340 341 342 343
	publish_test_with_args(FALSE,5);
}

static void publish_without_expires(){
	publish_test_with_args(TRUE,-1);
344 345 346
}

test_t event_tests[] = {
347 348
	{ "Subscribe declined"	,	subscribe_test_declined 	},
	{ "Subscribe terminated by subscriber", subscribe_test_terminated_by_subscriber },
349
	{ "Subscribe with custom headers", subscribe_test_with_custom_header },
350
	{ "Subscribe refreshed", subscribe_test_refreshed },
351
	{ "Subscribe manually refreshed", subscribe_test_manually_refreshed },
352 353
	{ "Subscribe terminated by notifier", subscribe_test_terminated_by_notifier },
	{ "Publish", publish_test },
Simon Morlat's avatar
Simon Morlat committed
354
	{ "Publish without expires", publish_without_expires },
355
	{ "Publish without automatic refresh",publish_no_auto_test }
356 357
};

358 359
test_suite_t event_test_suite = {
	"Event",
360 361
	NULL,
	NULL,
362 363
	sizeof(event_tests) / sizeof(event_tests[0]),
	event_tests
364 365
};