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

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


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

154 155 156 157 158
typedef enum RefreshTestType{
	NoRefresh,
	AutoRefresh,
	ManualRefresh
}RefreshTestType;
159

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

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

174 175 176 177 178
	content.type="application";
	content.subtype="somexml";
	content.data=(char*)subscribe_content;
	content.size=strlen(subscribe_content);
	
179
	lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,&content);
180 181 182 183 184 185
	
	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));

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

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

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 268 269 270 271
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);
}

272
static void subscribe_test_terminated_by_subscriber(void){
273
	subscribe_test_with_args(TRUE,NoRefresh);
274 275 276
}

static void subscribe_test_terminated_by_notifier(void){
277
	subscribe_test_with_args(FALSE,NoRefresh);
278 279 280 281 282 283
}

/* 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){
284 285 286
	subscribe_test_with_args(TRUE,AutoRefresh);
}

287 288 289 290
static void subscribe_test_with_custom_header(void){
	subscribe_test_with_args2(TRUE,NoRefresh);
}

291 292
static void subscribe_test_manually_refreshed(void){
	subscribe_test_with_args(TRUE,ManualRefresh);
293 294
}

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

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

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

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

static void publish_without_expires(){
	publish_test_with_args(TRUE,-1);
348 349 350
}

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

362 363
test_suite_t event_test_suite = {
	"Event",
364 365
	NULL,
	NULL,
366 367
	sizeof(event_tests) / sizeof(event_tests[0]),
	event_tests
368 369
};