blob: 7625a6973fe884d00fdbb95d8f9253b42cb338be [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*********************************************************************************************************
2* Software License Agreement (BSD License) *
3* Author: Sebastien Decugis <sdecugis@freediameter.net> *
4* *
5* Copyright (c) 2013, WIDE Project and NICT *
6* All rights reserved. *
7* *
8* Redistribution and use of this software in source and binary forms, with or without modification, are *
9* permitted provided that the following conditions are met: *
10* *
11* * Redistributions of source code must retain the above *
12* copyright notice, this list of conditions and the *
13* following disclaimer. *
14* *
15* * Redistributions in binary form must reproduce the above *
16* copyright notice, this list of conditions and the *
17* following disclaimer in the documentation and/or other *
18* materials provided with the distribution. *
19* *
20* * Neither the name of the WIDE Project or NICT nor the *
21* names of its contributors may be used to endorse or *
22* promote products derived from this software without *
23* specific prior written permission of WIDE Project and *
24* NICT. *
25* *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
34*********************************************************************************************************/
35
36#include "tests.h"
37
38#define Define_cb( __int, __extra ) \
39int cb_##__int( struct msg ** msg, struct avp * avp, struct session * session, void * opaque, enum disp_action * action ) \
40{ \
41 CHECK( 1, msg ? 1 : 0 ); \
42 CHECK( 1, action ? 1 : 0 ); \
43 CHECK( sess, session ); \
44 if (opaque) { \
45 CHECK( 1, opaque == g_opaque ? 1 : 0 ); \
46 } \
47 *action = DISP_ACT_CONT; \
48 cbcalled[__int] += 1; \
49 do { \
50 __extra ; \
51 } while (0); \
52 return 0; \
53}
54
55#define NB_CB 10
56char cbcalled[NB_CB];
57struct session * sess;
58void * g_opaque = (void *)"test";
59
60/* cb_0 */ Define_cb( 0, );
61/* cb_1 */ Define_cb( 1, );
62/* cb_2 */ Define_cb( 2, );
63/* cb_3 */ Define_cb( 3, );
64/* cb_4 */ Define_cb( 4, );
65/* cb_5 */ Define_cb( 5, );
66/* cb_6 */ Define_cb( 6, return 12345 );
67/* cb_7 */ Define_cb( 7, { CHECK( 1, avp ? 1 : 0 ); } );
68/* cb_8 */ Define_cb( 8, { CHECK( 0, fd_msg_free( *msg ) ); *msg = NULL; } );
69/* cb_9 */ Define_cb( 9, *action = DISP_ACT_SEND );
70/* max: cb_<NB_CB - 1> */
71
72/* Create a new message containing what we want */
73struct msg * new_msg(int appid, struct dict_object * cmd, struct dict_object * avp1, struct dict_object * avp2, int val)
74{
75 struct msg *new;
76 struct avp *avp;
77 union avp_value value;
78 struct msg_hdr * msg_hdr = NULL;
79
80 CHECK( 0, fd_msg_new ( cmd, 0, &new ) );
81 CHECK( 0, fd_msg_hdr ( new, &msg_hdr ) );
82 msg_hdr->msg_appl = appid;
83
84 if (avp1) {
85 CHECK( 0, fd_msg_avp_new ( avp1, 0, &avp ) );
86 value.u32 = 0;
87 CHECK( 0, fd_msg_avp_setvalue ( avp, &value ) );
88 CHECK( 0, fd_msg_avp_add ( new, MSG_BRW_LAST_CHILD, avp ) );
89 }
90
91 if (avp2) {
92 CHECK( 0, fd_msg_avp_new ( avp2, 0, &avp ) );
93 value.u32 = val;
94 CHECK( 0, fd_msg_avp_setvalue ( avp, &value ) );
95 CHECK( 0, fd_msg_avp_add ( new, MSG_BRW_LAST_CHILD, avp ) );
96 }
97
98 return new;
99}
100
101/* Main test routine */
102int main(int argc, char *argv[])
103{
104 struct dict_object * app1, * app2;
105 struct dict_object * cmd1, * cmd2;
106 struct dict_object * avp1, * avp2; /* avp2 is enumerated; they are both unsigned32 types */
107 struct dict_object * enu1, * enu2;
108 struct msg * msg = NULL, *error;
109 enum disp_action action;
110 struct disp_hdl * hdl[NB_CB];
111 struct disp_when when;
112 char * ec, *em;
113
114 /* First, initialize the daemon modules */
115 INIT_FD();
116
117 /* Create a dummy session, we don't use it anyway */
118 #define DUMMY_SID "test.disp"
119 CHECK( 0, fd_sess_new( &sess, DUMMY_SID, CONSTSTRLEN(DUMMY_SID), NULL, 0 ) );
120
121 memset(&when, 0xff, sizeof(when)); /* check that we don't use un-initialized parts */
122
123 /* Initialize dictionary objects */
124 {
125 struct dict_object * enutype;
126 struct dict_application_data app1_data = { 1, "Application test 1" };
127 struct dict_application_data app2_data = { 2, "Application test 2" };
128 struct dict_cmd_data cmd1_data = { 1, "Command test 1 (req)", CMD_FLAG_REQUEST, CMD_FLAG_REQUEST };
129 struct dict_cmd_data cmd2_data = { 1, "Command test 2 (ans)", CMD_FLAG_REQUEST, 0 };
130 struct dict_type_data type_data = { AVP_TYPE_UNSIGNED32, "Type test", NULL, NULL };
131 struct dict_avp_data avp1_data = { 10001, 0, "AVP test 1", 0, 0, AVP_TYPE_UNSIGNED32 };
132 struct dict_avp_data avp2_data = { 10002, 0, "AVP test 2", 0, 0, AVP_TYPE_UNSIGNED32 };
133 struct dict_enumval_data enu1_data = { "ENU test 1", { .u32 = 1 }};
134 struct dict_enumval_data enu2_data = { "ENU test 2", { .u32 = 2 }};
135
136 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_APPLICATION, &app1_data, NULL, &app1 ) );
137 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_APPLICATION, &app2_data, NULL, &app2 ) );
138 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_COMMAND, &cmd1_data, NULL, &cmd1 ) );
139 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_COMMAND, &cmd2_data, NULL, &cmd2 ) );
140 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_TYPE, &type_data, NULL, &enutype ) );
141 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp1_data, NULL, &avp1 ) );
142 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp2_data, enutype, &avp2 ) );
143 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &enu1_data, enutype, &enu1 ) );
144 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &enu2_data, enutype, &enu2 ) );
145 }
146
147 /* Register first handler, very simple test */
148 {
149 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, NULL, NULL, &hdl[0] ) );
150 CHECK( 1, hdl[0] ? 1 : 0 );
151 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
152 CHECK( NULL, hdl[0] );
153 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, NULL, NULL, &hdl[0] ) );
154
155 /* Check this handler is called for a message */
156 msg = new_msg( 0, cmd1, avp1, NULL, 0 );
157 memset(cbcalled, 0, sizeof(cbcalled));
158 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
159 CHECK( 1, cbcalled[0] );
160 CHECK( DISP_ACT_CONT, action );
161
162 /* Delete the message */
163 CHECK( 0, fd_msg_free( msg ) );
164 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
165 }
166
167 /* Handlers for applications */
168 {
169 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
170 when.app = app1;
171 CHECK( 0, fd_disp_register( cb_1, DISP_HOW_APPID, &when, NULL, &hdl[1] ) );
172 when.app = app2;
173 CHECK( 0, fd_disp_register( cb_2, DISP_HOW_APPID, &when, NULL, &hdl[2] ) );
174 when.avp = avp2;
175 CHECK( 0, fd_disp_register( cb_3, DISP_HOW_APPID, &when, NULL, &hdl[3] ) );
176 when.avp = avp1;
177 CHECK( 0, fd_disp_register( cb_4, DISP_HOW_APPID, &when, NULL, &hdl[4] ) );
178
179 /* Check the callbacks are called as appropriate */
180 memset(cbcalled, 0, sizeof(cbcalled));
181 msg = new_msg( 0, cmd1, avp1, NULL, 0 );
182 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
183 CHECK( 1, cbcalled[0] );
184 CHECK( 0, cbcalled[1] );
185 CHECK( 0, cbcalled[2] );
186 CHECK( 0, cbcalled[3] );
187 CHECK( 0, cbcalled[4] );
188 CHECK( DISP_ACT_CONT, action );
189 CHECK( 0, fd_msg_free( msg ) );
190
191 memset(cbcalled, 0, sizeof(cbcalled));
192 msg = new_msg( 1, cmd1, avp1, NULL, 0 );
193 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
194 CHECK( 1, cbcalled[0] );
195 CHECK( 1, cbcalled[1] );
196 CHECK( 0, cbcalled[2] );
197 CHECK( 0, cbcalled[3] );
198 CHECK( 0, cbcalled[4] );
199 CHECK( DISP_ACT_CONT, action );
200 CHECK( 0, fd_msg_free( msg ) );
201
202 memset(cbcalled, 0, sizeof(cbcalled));
203 msg = new_msg( 2, cmd1, avp1, NULL, 0 );
204 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
205 CHECK( 1, cbcalled[0] );
206 CHECK( 0, cbcalled[1] );
207 CHECK( 1, cbcalled[2] );
208 CHECK( 1, cbcalled[3] );
209 CHECK( 1, cbcalled[4] );
210 CHECK( DISP_ACT_CONT, action );
211 CHECK( 0, fd_msg_free( msg ) );
212
213 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
214 CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
215 CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
216 CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
217 CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
218 }
219
220 /* Handlers for commands */
221 {
222 when.app = NULL;
223 when.command = NULL;
224 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
225 CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_CC, &when, NULL, &hdl[1] ) );
226 when.command = cmd1;
227 CHECK( 0, fd_disp_register( cb_1, DISP_HOW_CC, &when, NULL, &hdl[1] ) ); /* cmd1 */
228 when.app = app2;
229 CHECK( 0, fd_disp_register( cb_2, DISP_HOW_CC, &when, NULL, &hdl[2] ) ); /* app2 + cmd1 */
230 when.command = cmd2;
231 when.app = NULL;
232 when.avp = avp1;
233 CHECK( 0, fd_disp_register( cb_3, DISP_HOW_CC, &when, NULL, &hdl[3] ) ); /* cmd2 (avp1 ignored) */
234
235 /* Check the callbacks are called as appropriate */
236 memset(cbcalled, 0, sizeof(cbcalled));
237 msg = new_msg( 0, cmd1, avp1, NULL, 0 );
238 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
239 CHECK( 1, cbcalled[0] );
240 CHECK( 1, cbcalled[1] );
241 CHECK( 0, cbcalled[2] );
242 CHECK( 0, cbcalled[3] );
243 CHECK( DISP_ACT_CONT, action );
244 CHECK( 0, fd_msg_free( msg ) );
245
246 memset(cbcalled, 0, sizeof(cbcalled));
247 msg = new_msg( 2, cmd1, avp1, NULL, 0 );
248 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
249 CHECK( 1, cbcalled[0] );
250 CHECK( 1, cbcalled[1] );
251 CHECK( 1, cbcalled[2] );
252 CHECK( 0, cbcalled[3] );
253 CHECK( DISP_ACT_CONT, action );
254 CHECK( 0, fd_msg_free( msg ) );
255
256 memset(cbcalled, 0, sizeof(cbcalled));
257 msg = new_msg( 2, cmd2, avp1, NULL, 0 );
258 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
259 CHECK( 1, cbcalled[0] );
260 CHECK( 0, cbcalled[1] );
261 CHECK( 0, cbcalled[2] );
262 CHECK( 1, cbcalled[3] );
263 CHECK( DISP_ACT_CONT, action );
264 CHECK( 0, fd_msg_free( msg ) );
265
266 memset(cbcalled, 0, sizeof(cbcalled));
267 msg = new_msg( 1, cmd2, NULL, avp2, 0 );
268 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
269 CHECK( 1, cbcalled[0] );
270 CHECK( 0, cbcalled[1] );
271 CHECK( 0, cbcalled[2] );
272 CHECK( 1, cbcalled[3] );
273 CHECK( DISP_ACT_CONT, action );
274 CHECK( 0, fd_msg_free( msg ) );
275
276 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
277 CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
278 CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
279 CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
280 }
281
282 /* Handlers for AVPs */
283 {
284 when.app = NULL;
285 when.command = NULL;
286 when.avp = NULL;
287
288 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) ); /* all */
289 CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP, &when, NULL, &hdl[1] ) );
290
291 when.avp = avp1;
292 CHECK( 0, fd_disp_register( cb_1, DISP_HOW_AVP, &when, NULL, &hdl[1] ) ); /* avp1 */
293
294 when.command = cmd1;
295 CHECK( 0, fd_disp_register( cb_2, DISP_HOW_AVP, &when, NULL, &hdl[2] ) ); /* avp1 + cmd1 */
296
297 when.command = NULL;
298 when.app = app1;
299 CHECK( 0, fd_disp_register( cb_3, DISP_HOW_AVP, &when, NULL, &hdl[3] ) ); /* avp1 + app1 */
300
301 when.command = cmd1;
302 CHECK( 0, fd_disp_register( cb_4, DISP_HOW_AVP, &when, NULL, &hdl[4] ) ); /* avp1 + cmd1 + app1 */
303
304 when.app = NULL;
305 when.command = NULL;
306 when.avp = avp2;
307 when.value = enu1;
308 CHECK( 0, fd_disp_register( cb_5, DISP_HOW_AVP, &when, NULL, &hdl[5] ) ); /* avp2 */
309
310 when.value = enu2;
311 CHECK( 0, fd_disp_register( cb_7, DISP_HOW_AVP, &when, NULL, &hdl[6] ) ); /* avp2 */
312
313
314
315 /* Check the callbacks are called as appropriate */
316 memset(cbcalled, 0, sizeof(cbcalled));
317 msg = new_msg( 0, cmd1, NULL, NULL, 0 );
318 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
319 CHECK( 1, cbcalled[0] );
320 CHECK( 0, cbcalled[1] );
321 CHECK( 0, cbcalled[2] );
322 CHECK( 0, cbcalled[3] );
323 CHECK( 0, cbcalled[4] );
324 CHECK( 0, cbcalled[5] );
325 CHECK( DISP_ACT_CONT, action );
326 CHECK( 0, fd_msg_free( msg ) );
327
328 memset(cbcalled, 0, sizeof(cbcalled));
329 msg = new_msg( 0, cmd1, avp1, NULL, 0 );
330 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
331 CHECK( 1, cbcalled[0] );
332 CHECK( 1, cbcalled[1] );
333 CHECK( 1, cbcalled[2] );
334 CHECK( 0, cbcalled[3] );
335 CHECK( 0, cbcalled[4] );
336 CHECK( 0, cbcalled[5] );
337 CHECK( DISP_ACT_CONT, action );
338 CHECK( 0, fd_msg_free( msg ) );
339
340 memset(cbcalled, 0, sizeof(cbcalled));
341 msg = new_msg( 1, cmd2, avp1, NULL, 0 );
342 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
343 CHECK( 1, cbcalled[0] );
344 CHECK( 1, cbcalled[1] );
345 CHECK( 0, cbcalled[2] );
346 CHECK( 1, cbcalled[3] );
347 CHECK( 0, cbcalled[4] );
348 CHECK( 0, cbcalled[5] );
349 CHECK( DISP_ACT_CONT, action );
350 CHECK( 0, fd_msg_free( msg ) );
351
352 memset(cbcalled, 0, sizeof(cbcalled));
353 msg = new_msg( 1, cmd1, avp1, NULL, 0 );
354 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
355 CHECK( 1, cbcalled[0] );
356 CHECK( 1, cbcalled[1] );
357 CHECK( 1, cbcalled[2] );
358 CHECK( 1, cbcalled[3] );
359 CHECK( 1, cbcalled[4] );
360 CHECK( 0, cbcalled[5] );
361 CHECK( DISP_ACT_CONT, action );
362 CHECK( 0, fd_msg_free( msg ) );
363
364 memset(cbcalled, 0, sizeof(cbcalled));
365 msg = new_msg( 1, cmd1, avp1, avp2, 0 );
366 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
367 CHECK( 1, cbcalled[0] );
368 CHECK( 1, cbcalled[1] );
369 CHECK( 1, cbcalled[2] );
370 CHECK( 1, cbcalled[3] );
371 CHECK( 1, cbcalled[4] );
372 CHECK( 1, cbcalled[5] );
373 CHECK( 1, cbcalled[7] );
374 CHECK( DISP_ACT_CONT, action );
375 CHECK( 0, fd_msg_free( msg ) );
376
377 memset(cbcalled, 0, sizeof(cbcalled));
378 msg = new_msg( 1, cmd1, NULL, avp2, 1 );
379 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
380 CHECK( 1, cbcalled[0] );
381 CHECK( 0, cbcalled[1] );
382 CHECK( 0, cbcalled[2] );
383 CHECK( 0, cbcalled[3] );
384 CHECK( 0, cbcalled[4] );
385 CHECK( 1, cbcalled[5] );
386 CHECK( 1, cbcalled[7] );
387 CHECK( DISP_ACT_CONT, action );
388 CHECK( 0, fd_msg_free( msg ) );
389
390 memset(cbcalled, 0, sizeof(cbcalled));
391 msg = new_msg( 1, cmd1, NULL, avp2, 2 );
392 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
393 CHECK( 1, cbcalled[0] );
394 CHECK( 0, cbcalled[1] );
395 CHECK( 0, cbcalled[2] );
396 CHECK( 0, cbcalled[3] );
397 CHECK( 0, cbcalled[4] );
398 CHECK( 1, cbcalled[5] );
399 CHECK( 1, cbcalled[7] );
400 CHECK( DISP_ACT_CONT, action );
401 CHECK( 0, fd_msg_free( msg ) );
402
403 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
404 CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
405 CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
406 CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
407 CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
408 CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
409 CHECK( 0, fd_disp_unregister( &hdl[6], NULL ) );
410 }
411
412 /* Handlers for enum values */
413 {
414 when.app = NULL;
415 when.command = NULL;
416 when.avp = NULL;
417 when.value = NULL;
418
419 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) ); /* all */
420 CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) );
421 when.value = enu1;
422 CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) );
423 when.avp = avp1;
424 CHECK( EINVAL, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) );
425 when.avp = avp2;
426 CHECK( 0, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) ); /* avp2, enu1 */
427
428 when.command = cmd1;
429 CHECK( 0, fd_disp_register( cb_2, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[2] ) ); /* avp2, enu1 + cmd1 */
430
431 when.command = NULL;
432 when.app = app1;
433 when.value = enu2;
434 CHECK( 0, fd_disp_register( cb_3, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[3] ) ); /* avp2, enu2 + app1 */
435
436 /* Check the callbacks are called as appropriate */
437 memset(cbcalled, 0, sizeof(cbcalled));
438 msg = new_msg( 0, cmd1, avp1, NULL, 0 );
439 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
440 CHECK( 1, cbcalled[0] );
441 CHECK( 0, cbcalled[1] );
442 CHECK( 0, cbcalled[2] );
443 CHECK( 0, cbcalled[3] );
444 CHECK( DISP_ACT_CONT, action );
445 CHECK( 0, fd_msg_free( msg ) );
446
447 memset(cbcalled, 0, sizeof(cbcalled));
448 msg = new_msg( 1, cmd2, avp1, avp2, 0 );
449 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
450 CHECK( 1, cbcalled[0] );
451 CHECK( 0, cbcalled[1] );
452 CHECK( 0, cbcalled[2] );
453 CHECK( 0, cbcalled[3] );
454 CHECK( DISP_ACT_CONT, action );
455 CHECK( 0, fd_msg_free( msg ) );
456
457 memset(cbcalled, 0, sizeof(cbcalled));
458 msg = new_msg( 1, cmd2, avp1, avp2, 1 );
459 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
460 CHECK( 1, cbcalled[0] );
461 CHECK( 1, cbcalled[1] );
462 CHECK( 0, cbcalled[2] );
463 CHECK( 0, cbcalled[3] );
464 CHECK( DISP_ACT_CONT, action );
465 CHECK( 0, fd_msg_free( msg ) );
466
467 memset(cbcalled, 0, sizeof(cbcalled));
468 msg = new_msg( 1, cmd2, avp1, avp2, 2 );
469 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
470 CHECK( 1, cbcalled[0] );
471 CHECK( 0, cbcalled[1] );
472 CHECK( 0, cbcalled[2] );
473 CHECK( 1, cbcalled[3] );
474 CHECK( DISP_ACT_CONT, action );
475 CHECK( 0, fd_msg_free( msg ) );
476
477 memset(cbcalled, 0, sizeof(cbcalled));
478 msg = new_msg( 1, cmd1, avp1, avp2, 1 );
479 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
480 CHECK( 1, cbcalled[0] );
481 CHECK( 1, cbcalled[1] );
482 CHECK( 1, cbcalled[2] );
483 CHECK( 0, cbcalled[3] );
484 CHECK( DISP_ACT_CONT, action );
485 CHECK( 0, fd_msg_free( msg ) );
486
487 memset(cbcalled, 0, sizeof(cbcalled));
488 msg = new_msg( 1, cmd2, avp1, avp2, 1 );
489 {
490 struct avp *avp;
491 union avp_value value;
492 CHECK( 0, fd_msg_avp_new ( avp2, 0, &avp ) );
493 value.u32 = 2;
494 CHECK( 0, fd_msg_avp_setvalue ( avp, &value ) );
495 CHECK( 0, fd_msg_avp_add ( msg, MSG_BRW_LAST_CHILD, avp ) );
496 }
497 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
498 CHECK( 1, cbcalled[0] );
499 CHECK( 1, cbcalled[1] );
500 CHECK( 0, cbcalled[2] );
501 CHECK( 1, cbcalled[3] );
502 CHECK( DISP_ACT_CONT, action );
503 CHECK( 0, fd_msg_free( msg ) );
504
505 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
506 CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
507 CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
508 CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
509 }
510
511 /* Test behavior of handlers */
512 {
513 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
514 CHECK( 0, fd_disp_register( cb_1, DISP_HOW_ANY, &when, NULL, &hdl[1] ) );
515 CHECK( 0, fd_disp_register( cb_6, DISP_HOW_ANY, &when, NULL, &hdl[2] ) );
516 CHECK( 0, fd_disp_register( cb_2, DISP_HOW_ANY, &when, NULL, &hdl[3] ) );
517 CHECK( 0, fd_disp_register( cb_3, DISP_HOW_ANY, &when, NULL, &hdl[4] ) );
518
519 memset(cbcalled, 0, sizeof(cbcalled));
520 msg = new_msg( 1, cmd1, avp1, avp2, 1 );
521 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
522 CHECK( 1, cbcalled[0] );
523 CHECK( 1, cbcalled[1] );
524 CHECK( 1, cbcalled[6] );
525 CHECK( 0, cbcalled[2] );
526 CHECK( 0, cbcalled[3] );
527 CHECK( 0, msg ? 1 : 0);
528 CHECK( 1, em ? 1 : 0);
529 CHECK( 0, fd_msg_free( error ) );
530
531 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
532 CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
533 CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
534 CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
535 CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
536
537 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
538 CHECK( 0, fd_disp_register( cb_1, DISP_HOW_ANY, &when, NULL, &hdl[1] ) );
539 CHECK( 0, fd_disp_register( cb_8, DISP_HOW_ANY, &when, NULL, &hdl[2] ) );
540 CHECK( 0, fd_disp_register( cb_2, DISP_HOW_ANY, &when, NULL, &hdl[3] ) );
541 CHECK( 0, fd_disp_register( cb_3, DISP_HOW_ANY, &when, NULL, &hdl[4] ) );
542
543 memset(cbcalled, 0, sizeof(cbcalled));
544 msg = new_msg( 1, cmd1, avp1, avp2, 1 );
545 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
546 CHECK( 1, cbcalled[0] );
547 CHECK( 1, cbcalled[1] );
548 CHECK( 1, cbcalled[8] );
549 CHECK( 0, cbcalled[2] );
550 CHECK( 0, cbcalled[3] );
551 CHECK( NULL, msg );
552 CHECK( NULL, em );
553
554 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
555 CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
556 CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
557 CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
558 CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
559
560 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
561 CHECK( 0, fd_disp_register( cb_1, DISP_HOW_ANY, &when, NULL, &hdl[1] ) );
562 CHECK( 0, fd_disp_register( cb_9, DISP_HOW_ANY, &when, NULL, &hdl[2] ) );
563 CHECK( 0, fd_disp_register( cb_2, DISP_HOW_ANY, &when, NULL, &hdl[3] ) );
564 CHECK( 0, fd_disp_register( cb_3, DISP_HOW_ANY, &when, NULL, &hdl[4] ) );
565
566 memset(cbcalled, 0, sizeof(cbcalled));
567 msg = new_msg( 1, cmd1, avp1, avp2, 1 );
568 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
569 CHECK( 1, cbcalled[0] );
570 CHECK( 1, cbcalled[1] );
571 CHECK( 1, cbcalled[9] );
572 CHECK( 0, cbcalled[2] );
573 CHECK( 0, cbcalled[3] );
574 CHECK( DISP_ACT_SEND, action );
575 CHECK( 0, fd_msg_free( msg ) );
576
577 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
578 CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
579 CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
580 CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
581 CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
582 }
583
584 /* Test order of handlers */
585 {
586 when.app = app2;
587 when.command = cmd2;
588 when.avp = avp2;
589 when.value = enu2;
590
591 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, &when, NULL, &hdl[0] ) );
592 CHECK( 0, fd_disp_register( cb_1, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[1] ) );
593 CHECK( 0, fd_disp_register( cb_2, DISP_HOW_AVP, &when, NULL, &hdl[2] ) );
594 CHECK( 0, fd_disp_register( cb_3, DISP_HOW_CC, &when, NULL, &hdl[3] ) );
595 CHECK( 0, fd_disp_register( cb_4, DISP_HOW_APPID, &when, NULL, &hdl[4] ) );
596
597 memset(cbcalled, 0, sizeof(cbcalled));
598 msg = new_msg( 2, cmd2, avp1, avp2, 2 );
599 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
600 CHECK( 1, cbcalled[0] );
601 CHECK( 1, cbcalled[1] );
602 CHECK( 1, cbcalled[2] );
603 CHECK( 1, cbcalled[3] );
604 CHECK( 1, cbcalled[4] );
605 CHECK( 0, cbcalled[9] );
606 CHECK( 0, fd_msg_free( msg ) );
607
608 CHECK( 0, fd_disp_register( cb_9, DISP_HOW_ANY, &when, NULL, &hdl[5] ) );
609 memset(cbcalled, 0, sizeof(cbcalled));
610 msg = new_msg( 2, cmd2, avp1, avp2, 2 );
611 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
612 CHECK( 1, cbcalled[0] );
613 CHECK( 0, cbcalled[1] );
614 CHECK( 0, cbcalled[2] );
615 CHECK( 0, cbcalled[3] );
616 CHECK( 0, cbcalled[4] );
617 CHECK( 1, cbcalled[9] );
618 CHECK( 0, fd_msg_free( msg ) );
619 CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
620
621 CHECK( 0, fd_disp_register( cb_9, DISP_HOW_AVP_ENUMVAL, &when, NULL, &hdl[5] ) );
622 memset(cbcalled, 0, sizeof(cbcalled));
623 msg = new_msg( 2, cmd2, avp1, avp2, 2 );
624 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
625 CHECK( 1, cbcalled[0] );
626 CHECK( 1, cbcalled[1] );
627 CHECK( 1, cbcalled[2] );
628 CHECK( 0, cbcalled[3] );
629 CHECK( 0, cbcalled[4] );
630 CHECK( 1, cbcalled[9] );
631 CHECK( 0, fd_msg_free( msg ) );
632 CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
633
634 CHECK( 0, fd_disp_register( cb_9, DISP_HOW_AVP, &when, NULL, &hdl[5] ) );
635 memset(cbcalled, 0, sizeof(cbcalled));
636 msg = new_msg( 2, cmd2, avp1, avp2, 2 );
637 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
638 CHECK( 1, cbcalled[0] );
639 CHECK( 1, cbcalled[1] );
640 CHECK( 1, cbcalled[2] );
641 CHECK( 0, cbcalled[3] );
642 CHECK( 0, cbcalled[4] );
643 CHECK( 1, cbcalled[9] );
644 CHECK( 0, fd_msg_free( msg ) );
645 CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
646
647 CHECK( 0, fd_disp_register( cb_9, DISP_HOW_CC, &when, NULL, &hdl[5] ) );
648 memset(cbcalled, 0, sizeof(cbcalled));
649 msg = new_msg( 2, cmd2, avp1, avp2, 2 );
650 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
651 CHECK( 1, cbcalled[0] );
652 CHECK( 1, cbcalled[1] );
653 CHECK( 1, cbcalled[2] );
654 CHECK( 1, cbcalled[3] );
655 CHECK( 0, cbcalled[4] );
656 CHECK( 1, cbcalled[9] );
657 CHECK( 0, fd_msg_free( msg ) );
658 CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
659
660 CHECK( 0, fd_disp_register( cb_9, DISP_HOW_APPID, &when, NULL, &hdl[5] ) );
661 memset(cbcalled, 0, sizeof(cbcalled));
662 msg = new_msg( 2, cmd2, avp1, avp2, 2 );
663 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
664 CHECK( 1, cbcalled[0] );
665 CHECK( 1, cbcalled[1] );
666 CHECK( 1, cbcalled[2] );
667 CHECK( 1, cbcalled[3] );
668 CHECK( 1, cbcalled[4] );
669 CHECK( 1, cbcalled[9] );
670 CHECK( 0, fd_msg_free( msg ) );
671 CHECK( 0, fd_disp_unregister( &hdl[5], NULL ) );
672
673 CHECK( 0, fd_disp_unregister( &hdl[0], NULL ) );
674 CHECK( 0, fd_disp_unregister( &hdl[1], NULL ) );
675 CHECK( 0, fd_disp_unregister( &hdl[2], NULL ) );
676 CHECK( 0, fd_disp_unregister( &hdl[3], NULL ) );
677 CHECK( 0, fd_disp_unregister( &hdl[4], NULL ) );
678 }
679
680 /* Test application support advertisement */
681 {
682 struct dict_object * vnd;
683 struct dict_vendor_data vnd_data = { 1, "Vendor test" };
684 struct fd_app * app;
685
686 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_VENDOR, &vnd_data, NULL, &vnd ) );
687
688 CHECK( EINVAL, fd_disp_app_support ( vnd, NULL, 1, 0 ) );
689 CHECK( EINVAL, fd_disp_app_support ( app1, NULL, 0, 0 ) );
690 CHECK( 0, fd_disp_app_support ( app1, NULL, 1, 0 ) );
691 CHECK( 0, fd_disp_app_support ( app1, NULL, 0, 1 ) );
692 CHECK( 0, fd_disp_app_support ( app2, vnd, 1, 0 ) );
693
694 app = (struct fd_app *)(fd_g_config->cnf_apps.next);
695 CHECK( 1, app->appid );
696 CHECK( 1, app->flags.auth );
697 CHECK( 1, app->flags.acct );
698 app = (struct fd_app *)(fd_g_config->cnf_apps.prev);
699 CHECK( 2, app->appid );
700 CHECK( 1, app->flags.auth );
701 CHECK( 0, app->flags.acct );
702
703 #if 0
704 fd_log_debug("%s", fd_conf_dump(FD_DUMP_TEST_PARAMS));
705 #endif
706 }
707
708 /* Test opaque pointer management */
709 {
710 void * ptr;
711 CHECK( 0, fd_disp_register( cb_0, DISP_HOW_ANY, NULL, g_opaque, &hdl[0] ) );
712
713 /* Check this handler is called for a message */
714 msg = new_msg( 0, cmd1, avp1, NULL, 0 );
715 memset(cbcalled, 0, sizeof(cbcalled));
716 CHECK( 0, fd_msg_dispatch ( &msg, sess, &action, &ec, &em, &error ) );
717 CHECK( 1, cbcalled[0] );
718 CHECK( DISP_ACT_CONT, action );
719
720 /* Delete the message */
721 CHECK( 0, fd_msg_free( msg ) );
722 CHECK( 0, fd_disp_unregister( &hdl[0], &ptr ) );
723 CHECK( 1, ptr == g_opaque ? 1 : 0 );
724 }
725
726 /* That's all for the tests yet */
727 PASSTEST();
728}
729