Navigation


source: freeDiameter/freeDiameter/tests/testsess.c @ 639:95a784729cac

Last change on this file since 639:95a784729cac was 639:95a784729cac, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 2 years ago

Added new opaque pointer to fd_sess_handler_create and fd_disp_register for usability. Bumped API version number.

File size: 11.8 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Sebastien Decugis <sdecugis@nict.go.jp>                                                        *
4*                                                                                                        *
5* Copyright (c) 2010, 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 TEST_DIAM_ID    "testsess.myid"
39#define TEST_OPT        "suffix"
40#define TEST_SID        TEST_DIAM_ID ";1234;5678;" TEST_OPT
41
42#define TEST_EYEC       0x7e57e1ec
43struct mystate {
44        int     eyec;   /* TEST_EYEC */
45        char *  sid;    /* the session with which the data was registered */
46        int  *  freed;  /* location where to write the freed status */
47        void *  opaque; /* if opaque was provided, this is the value we expect */
48};
49
50static void mycleanup( struct mystate * data, char * sid, void * opaque )
51{
52        /* sanity */
53        CHECK( 1, sid ? 1 : 0 );
54        CHECK( 1, data? 1 : 0 );
55        CHECK( TEST_EYEC, data->eyec );
56        CHECK( 0, strcmp(sid, data->sid) );
57        if (data->freed)
58                *(data->freed) += 1;
59        if (data->opaque) {
60                CHECK( 1, opaque == data->opaque ? 1 : 0 ); 
61        }
62        /* Now, free the data */
63        free(data->sid);
64        free(data);
65}
66
67static __inline__ struct mystate * new_state(char * sid, int *freed) 
68{
69        struct mystate *new;
70        new = malloc(sizeof(struct mystate));
71        CHECK( 1, new ? 1 : 0 );
72        memset(new, 0, sizeof(struct mystate));
73        new->eyec = TEST_EYEC;
74        new->sid = strdup(sid);
75        CHECK( 1, new->sid ? 1 : 0 );
76        new->freed = freed;
77        return new;
78}
79
80void * g_opaque = (void *)"test";
81       
82
83/* Main test routine */
84int main(int argc, char *argv[])
85{
86        struct session_handler * hdl1, *hdl2;
87        struct session *sess1, *sess2, *sess3;
88        char *str1, *str2;
89        int new;
90       
91        /* First, initialize the daemon modules */
92        INIT_FD();
93       
94        /* Test functions related to handlers (simple situation) */
95        {
96                void * testptr = NULL;
97                CHECK( 0, fd_sess_handler_create ( &hdl1, mycleanup, NULL ) );
98                CHECK( 0, fd_sess_handler_create ( &hdl2, mycleanup, NULL ) );
99                CHECK( 0, fd_sess_handler_destroy( &hdl2, &testptr ) );
100                CHECK( 1, testptr == NULL ? 1 : 0 );
101                CHECK( 0, fd_sess_handler_create ( &hdl2, mycleanup, g_opaque ) );
102                #if 0
103                fd_sess_dump_hdl(0, hdl1);
104                fd_sess_dump_hdl(0, hdl2);
105                #endif
106        }
107       
108        /* Test Session Id generation (fd_sess_new) */
109        {
110                /* DiamId is provided, not opt */
111                CHECK( 0, fd_sess_new( &sess1, TEST_DIAM_ID, NULL, 0 ) );
112                CHECK( 0, fd_sess_new( &sess2, TEST_DIAM_ID, NULL, 0 ) );
113                #if 0
114                fd_sess_dump(0, sess1);
115                fd_sess_dump(0, sess2);
116                #endif
117               
118                /* Check both string start with the diameter Id, but are different */
119                CHECK( 0, fd_sess_getsid(sess1, &str1) );
120                CHECK( 0, strncmp(str1, TEST_DIAM_ID ";", strlen(TEST_DIAM_ID) + 1) );
121                CHECK( 0, fd_sess_getsid(sess2, &str2) );
122                CHECK( 0, strncmp(str2, TEST_DIAM_ID ";", strlen(TEST_DIAM_ID) + 1) );
123                CHECK( 1, strcmp(str1, str2) ? 1 : 0 );
124                CHECK( 0, fd_sess_destroy( &sess1 ) );
125                CHECK( 0, fd_sess_destroy( &sess2 ) );
126               
127                /* diamId and opt */
128                CHECK( 0, fd_sess_new( &sess1, TEST_DIAM_ID, TEST_OPT, 0 ) );
129                CHECK( 0, fd_sess_new( &sess2, TEST_DIAM_ID, TEST_OPT, strlen(TEST_OPT) - 1 ) );
130                #if 0
131                fd_sess_dump(0, sess1);
132                fd_sess_dump(0, sess2);
133                #endif
134               
135                CHECK( 0, fd_sess_getsid(sess1, &str1) );
136                CHECK( 0, strncmp(str1, TEST_DIAM_ID ";", strlen(TEST_DIAM_ID) + 1) );
137                CHECK( 0, strcmp(str1 + strlen(str1) - strlen(TEST_OPT) - 1, ";" TEST_OPT) );
138               
139                CHECK( 0, fd_sess_getsid(sess2, &str2) );
140                CHECK( 0, strncmp(str2, TEST_DIAM_ID ";", strlen(TEST_DIAM_ID) + 1) );
141                CHECK( 0, strncmp(str2 + strlen(str2) - strlen(TEST_OPT), ";" TEST_OPT, strlen(TEST_OPT)) );
142               
143                CHECK( 1, strcmp(str1, str2) ? 1 : 0 );
144                CHECK( 0, fd_sess_destroy( &sess1 ) );
145                CHECK( 0, fd_sess_destroy( &sess2 ) );
146               
147                /* Now, only opt is provided */
148                CHECK( 0, fd_sess_new( &sess1, NULL, TEST_SID, 0 ) );
149                CHECK( EALREADY, fd_sess_new( &sess2, NULL, TEST_SID, 0 ) );
150                CHECK( sess2, sess1 );
151                CHECK( EALREADY, fd_sess_new( &sess3, NULL, TEST_SID, strlen(TEST_SID) ) );
152                CHECK( sess3, sess1 );
153                CHECK( 0, fd_sess_new( &sess2, NULL, TEST_SID, strlen(TEST_SID) - 1 ) );
154                #if 0
155                fd_sess_dump(0, sess1);
156                fd_sess_dump(0, sess2);
157                #endif
158                CHECK( 0, fd_sess_getsid(sess1, &str1) );
159                CHECK( 0, fd_sess_getsid(sess2, &str2) );
160                CHECK( 0, strncmp( str1, str2, strlen(TEST_SID) - 1 ) );
161                CHECK( 0, strcmp( str1, TEST_SID ) );
162               
163                CHECK( 0, fd_sess_destroy( &sess2 ) );
164                CHECK( 0, fd_sess_destroy( &sess1 ) );
165        }
166               
167        /* Test fd_sess_fromsid */
168        {
169                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
170                CHECK( 1, new ? 1 : 0 );
171               
172                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess2, &new ) );
173                CHECK( 0, new );
174                CHECK( sess1, sess2 );
175               
176                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess3, NULL ) );
177                CHECK( sess1, sess3 );
178               
179                CHECK( 0, fd_sess_destroy( &sess1 ) );
180        }
181       
182        /* Test fd_sess_reclaim */
183        {
184                struct mystate *tms;
185               
186                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
187                CHECK( 1, new ? 1 : 0 );
188               
189                CHECK( 0, fd_sess_reclaim( &sess1 ) );
190                CHECK( NULL, sess1 );
191               
192                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
193                CHECK( 1, new ? 1 : 0 );
194               
195                tms = new_state(TEST_SID, NULL);
196                CHECK( 0, fd_sess_state_store ( hdl1, sess1, &tms ) );
197               
198                CHECK( 0, fd_sess_reclaim( &sess1 ) );
199                CHECK( NULL, sess1 );
200               
201                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
202                CHECK( 0, new );
203               
204                CHECK( 0, fd_sess_destroy( &sess1 ) );
205               
206                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
207                CHECK( 1, new ? 1 : 0 );
208               
209                CHECK( 0, fd_sess_destroy( &sess1 ) );
210        }
211       
212        /* Test timeout function */
213        {
214                struct timespec timeout;
215               
216                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
217                CHECK( 1, new ? 1 : 0 );
218               
219                CHECK( 0, clock_gettime(CLOCK_REALTIME, &timeout) );
220                CHECK( 0, fd_sess_settimeout( sess1, &timeout) );
221                timeout.tv_sec = 0;
222                timeout.tv_nsec= 50000000; /* 50 ms */
223                CHECK( 0, nanosleep(&timeout, NULL) );
224               
225                CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
226                CHECK( 1, new ? 1 : 0 );
227               
228                CHECK( 0, clock_gettime(CLOCK_REALTIME, &timeout) );
229                timeout.tv_sec += 2678500; /* longer that SESS_DEFAULT_LIFETIME */
230                CHECK( 0, fd_sess_settimeout( sess1, &timeout) );
231               
232                /* Create a second session */
233                CHECK( 0, fd_sess_new( &sess2, TEST_DIAM_ID, NULL, 0 ) );
234               
235                /* We don't really have away to verify the expiry list is in proper order automatically here... */
236               
237                CHECK( 0, fd_sess_destroy( &sess2 ) );
238                CHECK( 0, fd_sess_destroy( &sess1 ) );
239        }
240       
241       
242        /* Test states operations */
243        {
244                struct mystate * ms[6], *tms;
245                int freed[6];
246                struct timespec timeout;
247                void * testptr = NULL;
248               
249                /* Create three sessions */
250                CHECK( 0, fd_sess_new( &sess1, TEST_DIAM_ID, NULL, 0 ) );
251                CHECK( 0, fd_sess_new( &sess2, TEST_DIAM_ID, NULL, 0 ) );
252                CHECK( 0, fd_sess_new( &sess3, TEST_DIAM_ID, NULL, 0 ) );
253               
254                /* Create 2 states */
255                CHECK( 0, fd_sess_getsid(sess1, &str1) );
256                freed[0] = 0;
257                ms[0] = new_state(str1, &freed[0]);
258                ms[1] = new_state(str1, NULL);
259
260                tms = ms[0]; /* save a copy */
261                CHECK( 0, fd_sess_state_store ( hdl1, sess1, &ms[0] ) );
262                CHECK( NULL, ms[0] );
263                CHECK( EINVAL, fd_sess_state_store ( hdl1, sess1, NULL ) );
264                CHECK( EALREADY, fd_sess_state_store ( hdl1, sess1, &ms[1] ) );
265                CHECK( 1, ms[1] ? 1 : 0 );
266               
267                #if 0
268                fd_sess_dump(0, sess1);
269                #endif
270               
271                CHECK( 0, fd_sess_state_retrieve( hdl1, sess1, &ms[0] ) );
272                CHECK( tms, ms[0] );
273                CHECK( 0, freed[0] );
274               
275                CHECK( 0, fd_sess_state_retrieve( hdl1, sess2, &tms ) );
276                CHECK( NULL, tms );
277               
278                mycleanup(ms[0], str1, NULL);
279                mycleanup(ms[1], str1, NULL);
280               
281                /* Now create 6 states */
282                memset(&freed[0], 0, sizeof(freed));
283                CHECK( 0, fd_sess_getsid(sess1, &str1) );
284                ms[0] = new_state(str1, &freed[0]);
285                ms[1] = new_state(str1, &freed[1]);
286                CHECK( 0, fd_sess_getsid(sess2, &str1) );
287                ms[2] = new_state(str1, &freed[2]);
288                ms[3] = new_state(str1, &freed[3]);
289                CHECK( 0, fd_sess_getsid(sess3, &str1) );
290                ms[4] = new_state(str1, &freed[4]);
291                ms[5] = new_state(str1, &freed[5]);
292                ms[5]->opaque = g_opaque;
293                str2 = strdup(str1);
294                CHECK( 1, str2 ? 1 : 0 );
295               
296                /* Store the six states */
297                CHECK( 0, fd_sess_state_store ( hdl1, sess1, &ms[0] ) );
298                CHECK( 0, fd_sess_state_store ( hdl2, sess1, &ms[1] ) );
299                CHECK( 0, fd_sess_state_store ( hdl1, sess2, &ms[2] ) );
300                CHECK( 0, fd_sess_state_store ( hdl2, sess2, &ms[3] ) );
301                CHECK( 0, fd_sess_state_store ( hdl1, sess3, &ms[4] ) );
302                CHECK( 0, fd_sess_state_store ( hdl2, sess3, &ms[5] ) );
303               
304                #if 0
305                fd_sess_dump(0, sess1);
306                fd_sess_dump(0, sess2);
307                fd_sess_dump(0, sess3);
308                #endif
309               
310                /* Destroy session 3 */
311                CHECK( 0, fd_sess_destroy( &sess3 ) );
312                CHECK( 0, freed[0] );
313                CHECK( 0, freed[1] );
314                CHECK( 0, freed[2] );
315                CHECK( 0, freed[3] );
316                CHECK( 1, freed[4] );
317                CHECK( 1, freed[5] );
318               
319                /* Destroy handler 2 */
320                CHECK( 0, fd_sess_handler_destroy( &hdl2, &testptr ) );
321                CHECK( 0, freed[0] );
322                CHECK( 1, freed[1] );
323                CHECK( 0, freed[2] );
324                CHECK( 1, freed[3] );
325                CHECK( 1, freed[4] );
326                CHECK( 1, freed[5] );
327                CHECK( 1, testptr == g_opaque ? 1 : 0 );
328               
329                #if 1
330                fd_sess_dump(0, sess1);
331                fd_sess_dump(0, sess2);
332                #endif
333               
334                /* Create again session 3, check that no data is associated to it */
335                CHECK( 0, fd_sess_fromsid( str2, strlen(str2), &sess3, &new ) );
336                CHECK( 1, new ? 1 : 0 );
337                CHECK( 0, fd_sess_state_retrieve( hdl1, sess3, &tms ) );
338                CHECK( NULL, tms );
339                CHECK( 0, fd_sess_destroy( &sess3 ) );
340                free(str2);
341               
342                /* Timeout does call cleanups */
343                CHECK( 0, clock_gettime(CLOCK_REALTIME, &timeout) );
344                CHECK( 0, fd_sess_settimeout( sess2, &timeout) );
345                #if 1
346                fd_sess_dump(0, sess1);
347                fd_sess_dump(0, sess2);
348                #endif
349                timeout.tv_sec = 0;
350                timeout.tv_nsec= 50000000; /* 50 ms */
351                CHECK( 0, nanosleep(&timeout, NULL) );
352                CHECK( 0, freed[0] );
353                CHECK( 1, freed[1] );
354                CHECK( 1, freed[2] );
355                CHECK( 1, freed[3] );
356                CHECK( 1, freed[4] );
357                CHECK( 1, freed[5] );
358               
359                /* Check the last data can still be retrieved */
360                CHECK( 0, fd_sess_state_retrieve( hdl1, sess1, &tms ) );
361                CHECK( 0, fd_sess_getsid(sess1, &str1) );
362                mycleanup(tms, str1, NULL);
363        }
364       
365       
366        /* That's all for the tests yet */
367        PASSTEST();
368} 
369       
Note: See TracBrowser for help on using the repository browser.