Commit e3bfb711 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Completed new session module tests; some bugs fixed

parent 00269e19
......@@ -46,7 +46,7 @@ struct mystate {
int * freed; /* location where to write the freed status */
};
void mycleanup( char * sid, struct mystate * data )
static void mycleanup( char * sid, struct mystate * data )
{
/* sanity */
CHECK( 1, sid ? 1 : 0 );
......@@ -60,6 +60,20 @@ void mycleanup( char * sid, struct mystate * data )
free(data);
}
static __inline__ struct mystate * new_state(char * sid, int *freed)
{
struct mystate *new;
new = malloc(sizeof(struct mystate));
CHECK( 1, new ? 1 : 0 );
memset(new, 0, sizeof(struct mystate));
new->eyec = TEST_EYEC;
new->sid = strdup(sid);
CHECK( 1, new->sid ? 1 : 0 );
new->freed = freed;
return new;
}
/* Main test routine */
int main(int argc, char *argv[])
{
......@@ -77,7 +91,7 @@ int main(int argc, char *argv[])
CHECK( 0, fd_sess_handler_create ( &hdl2, mycleanup ) );
CHECK( 0, fd_sess_handler_destroy( &hdl2 ) );
CHECK( 0, fd_sess_handler_create ( &hdl2, mycleanup ) );
#if 1
#if 0
fd_sess_dump_hdl(0, hdl1);
fd_sess_dump_hdl(0, hdl2);
#endif
......@@ -88,7 +102,7 @@ int main(int argc, char *argv[])
/* DiamId is provided, not opt */
CHECK( 0, fd_sess_new( &sess1, TEST_DIAM_ID, NULL, 0 ) );
CHECK( 0, fd_sess_new( &sess2, TEST_DIAM_ID, NULL, 0 ) );
#if 1
#if 0
fd_sess_dump(0, sess1);
fd_sess_dump(0, sess2);
#endif
......@@ -105,7 +119,7 @@ int main(int argc, char *argv[])
/* diamId and opt */
CHECK( 0, fd_sess_new( &sess1, TEST_DIAM_ID, TEST_OPT, 0 ) );
CHECK( 0, fd_sess_new( &sess2, TEST_DIAM_ID, TEST_OPT, strlen(TEST_OPT) - 1 ) );
#if 1
#if 0
fd_sess_dump(0, sess1);
fd_sess_dump(0, sess2);
#endif
......@@ -129,7 +143,7 @@ int main(int argc, char *argv[])
CHECK( EALREADY, fd_sess_new( &sess3, NULL, TEST_SID, strlen(TEST_SID) ) );
CHECK( sess3, sess1 );
CHECK( 0, fd_sess_new( &sess2, NULL, TEST_SID, strlen(TEST_SID) - 1 ) );
#if 1
#if 0
fd_sess_dump(0, sess1);
fd_sess_dump(0, sess2);
#endif
......@@ -139,18 +153,176 @@ int main(int argc, char *argv[])
CHECK( 0, strcmp( str1, TEST_SID ) );
CHECK( 0, fd_sess_destroy( &sess2 ) );
CHECK( 0, fd_sess_destroy( &sess1 ) );
}
/* Test fd_sess_fromsid */
{
CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
CHECK( 1, new ? 1 : 0 );
CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess2, &new ) );
CHECK( 0, new );
CHECK( sess1, sess2 );
CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess3, NULL ) );
CHECK( sess1, sess3 );
CHECK( 0, fd_sess_destroy( &sess1 ) );
}
/*
int fd_sess_new ( struct session ** session, char * diamId, char * opt, size_t optlen );
int fd_sess_fromsid ( char * sid, size_t len, struct session ** session, int * new);
int fd_sess_getsid ( struct session * session, char ** sid );
int fd_sess_settimeout( struct session * session, const struct timespec * timeout );
int fd_sess_destroy ( struct session ** session );
*/
/* Test timeout function */
{
struct timespec timeout;
CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
CHECK( 1, new ? 1 : 0 );
CHECK( 0, clock_gettime(CLOCK_REALTIME, &timeout) );
CHECK( 0, fd_sess_settimeout( sess1, &timeout) );
timeout.tv_sec = 0;
timeout.tv_nsec= 50000000; /* 50 ms */
CHECK( 0, clock_nanosleep(CLOCK_REALTIME, 0, &timeout, NULL) );
CHECK( 0, fd_sess_fromsid( TEST_SID, strlen(TEST_SID), &sess1, &new ) );
CHECK( 1, new ? 1 : 0 );
CHECK( 0, clock_gettime(CLOCK_REALTIME, &timeout) );
timeout.tv_sec += 2678500; /* longer that SESS_DEFAULT_LIFETIME */
CHECK( 0, fd_sess_settimeout( sess1, &timeout) );
/* Create a second session */
CHECK( 0, fd_sess_new( &sess2, TEST_DIAM_ID, NULL, 0 ) );
/* We don't really have away to verify the expiry list is in proper order automatically here... */
CHECK( 0, fd_sess_destroy( &sess2 ) );
CHECK( 0, fd_sess_destroy( &sess1 ) );
}
/* Test states operations */
{
struct mystate * ms[6], *tms;
int freed[6];
int i;
struct timespec timeout;
/* Create three sessions */
CHECK( 0, fd_sess_new( &sess1, TEST_DIAM_ID, NULL, 0 ) );
CHECK( 0, fd_sess_new( &sess2, TEST_DIAM_ID, NULL, 0 ) );
CHECK( 0, fd_sess_new( &sess3, TEST_DIAM_ID, NULL, 0 ) );
/* Create 2 states */
CHECK( 0, fd_sess_getsid(sess1, &str1) );
freed[0] = 0;
ms[0] = new_state(str1, &freed[0]);
ms[1] = new_state(str1, NULL);
tms = ms[0]; /* save a copy */
CHECK( 0, fd_sess_state_store ( hdl1, sess1, &ms[0] ) );
CHECK( NULL, ms[0] );
CHECK( EINVAL, fd_sess_state_store ( hdl1, sess1, NULL ) );
CHECK( EALREADY, fd_sess_state_store ( hdl1, sess1, &ms[1] ) );
CHECK( 1, ms[1] ? 1 : 0 );
#if 0
fd_sess_dump(0, sess1);
#endif
CHECK( 0, fd_sess_state_retrieve( hdl1, sess1, &ms[0] ) );
CHECK( tms, ms[0] );
CHECK( 0, freed[0] );
CHECK( 0, fd_sess_state_retrieve( hdl1, sess2, &tms ) );
CHECK( NULL, tms );
mycleanup(str1, ms[0]);
mycleanup(str1, ms[1]);
/* Now create 6 states */
memset(&freed[0], 0, sizeof(freed));
CHECK( 0, fd_sess_getsid(sess1, &str1) );
ms[0] = new_state(str1, &freed[0]);
ms[1] = new_state(str1, &freed[1]);
CHECK( 0, fd_sess_getsid(sess2, &str1) );
ms[2] = new_state(str1, &freed[2]);
ms[3] = new_state(str1, &freed[3]);
CHECK( 0, fd_sess_getsid(sess3, &str1) );
ms[4] = new_state(str1, &freed[4]);
ms[5] = new_state(str1, &freed[5]);
str2 = strdup(str1);
CHECK( 1, str2 ? 1 : 0 );
/* Store the six states */
CHECK( 0, fd_sess_state_store ( hdl1, sess1, &ms[0] ) );
CHECK( 0, fd_sess_state_store ( hdl2, sess1, &ms[1] ) );
CHECK( 0, fd_sess_state_store ( hdl1, sess2, &ms[2] ) );
CHECK( 0, fd_sess_state_store ( hdl2, sess2, &ms[3] ) );
CHECK( 0, fd_sess_state_store ( hdl1, sess3, &ms[4] ) );
CHECK( 0, fd_sess_state_store ( hdl2, sess3, &ms[5] ) );
#if 0
fd_sess_dump(0, sess1);
fd_sess_dump(0, sess2);
fd_sess_dump(0, sess3);
#endif
/* Destroy session 3 */
CHECK( 0, fd_sess_destroy( &sess3 ) );
CHECK( 0, freed[0] );
CHECK( 0, freed[1] );
CHECK( 0, freed[2] );
CHECK( 0, freed[3] );
CHECK( 1, freed[4] );
CHECK( 1, freed[5] );
/* Destroy handler 2 */
CHECK( 0, fd_sess_handler_destroy( &hdl2 ) );
CHECK( 0, freed[0] );
CHECK( 1, freed[1] );
CHECK( 0, freed[2] );
CHECK( 1, freed[3] );
CHECK( 1, freed[4] );
CHECK( 1, freed[5] );
#if 1
fd_sess_dump(0, sess1);
fd_sess_dump(0, sess2);
#endif
/* Create again session 3, check that no data is associated to it */
CHECK( 0, fd_sess_fromsid( str2, strlen(str2), &sess3, &new ) );
CHECK( 1, new ? 1 : 0 );
CHECK( 0, fd_sess_state_retrieve( hdl1, sess3, &tms ) );
CHECK( NULL, tms );
CHECK( 0, fd_sess_destroy( &sess3 ) );
free(str2);
/* Timeout does call cleanups */
CHECK( 0, clock_gettime(CLOCK_REALTIME, &timeout) );
CHECK( 0, fd_sess_settimeout( sess2, &timeout) );
#if 1
fd_sess_dump(0, sess1);
fd_sess_dump(0, sess2);
#endif
timeout.tv_sec = 0;
timeout.tv_nsec= 50000000; /* 50 ms */
CHECK( 0, clock_nanosleep(CLOCK_REALTIME, 0, &timeout, NULL) );
CHECK( 0, freed[0] );
CHECK( 1, freed[1] );
CHECK( 1, freed[2] );
CHECK( 1, freed[3] );
CHECK( 1, freed[4] );
CHECK( 1, freed[5] );
/* Check the last data can still be retrieved */
CHECK( 0, fd_sess_state_retrieve( hdl1, sess1, &tms ) );
CHECK( 0, fd_sess_getsid(sess1, &str1) );
mycleanup(str1, tms);
}
/* That's all for the tests yet */
PASSTEST();
}
......
......@@ -364,7 +364,7 @@ extern int fd_g_debug_lvl;
/* Compare timespec structures */
#define TS_IS_INFERIOR( ts1, ts2 ) \
( ((ts1)->tv_sec < (ts2)->tv_sec ) \
|| ((ts1)->tv_nsec < (ts2)->tv_nsec) )
|| (((ts1)->tv_sec == (ts2)->tv_sec ) && ((ts1)->tv_nsec < (ts2)->tv_nsec) ))
/*============================================================*/
......@@ -1458,7 +1458,9 @@ int fd_sess_destroy ( struct session ** session );
* EALREADY : Data was already associated with this session and client.
* ENOMEM : Not enough memory to complete the operation
*/
int fd_sess_state_store ( struct session_handler * handler, struct session * session, session_state ** state );
int fd_sess_state_store_int ( struct session_handler * handler, struct session * session, session_state ** state );
#define fd_sess_state_store( _handler, _session, _state ) \
fd_sess_state_store_int( (_handler), (_session), (void *)(_state) )
/*
* FUNCTION: fd_sess_state_retrieve
......@@ -1478,7 +1480,9 @@ int fd_sess_state_store ( struct session_handler * handler, struct session * ses
* 0 : *state is updated (NULL or points to the state if it was found).
* EINVAL : A parameter is invalid.
*/
int fd_sess_state_retrieve ( struct session_handler * handler, struct session * session, session_state ** state );
int fd_sess_state_retrieve_int ( struct session_handler * handler, struct session * session, session_state ** state );
#define fd_sess_state_retrieve( _handler, _session, _state ) \
fd_sess_state_retrieve_int( (_handler), (_session), (void *)(_state) )
/* For debug */
......
......@@ -295,12 +295,13 @@ int fd_sess_handler_destroy ( struct session_handler ** handler )
/* The list is ordered */
if (st->hdl->id < del->id)
continue;
if (st->hdl->id > del->id)
break;
/* This state belongs to the handler we are deleting, move the item to the deleted_states list */
fd_list_unlink(&st->chain);
CHECK_MALLOC( st->sid = strdup(sess->sid) );
fd_list_insert_before(&deleted_states, &st->chain);
if (st->hdl->id == del->id) {
/* This state belongs to the handler we are deleting, move the item to the deleted_states list */
fd_list_unlink(&st->chain);
CHECK_MALLOC( st->sid = strdup(sess->sid) );
fd_list_insert_before(&deleted_states, &st->chain);
}
break;
}
CHECK_POSIX( pthread_mutex_unlock(&sess->stlock) );
}
......@@ -399,9 +400,9 @@ int fd_sess_new ( struct session ** session, char * diamId, char * opt, size_t o
break;
}
/* If the session did not exist, we can add it into the hash table */
/* If the session did not exist, we can link it in global tables */
if (!found) {
fd_list_insert_before(li, &sess->chain_h);
fd_list_insert_before(li, &sess->chain_h); /* hash table */
/* We must also insert in the expiry list */
CHECK_POSIX( pthread_mutex_lock( &exp_lock ) );
......@@ -409,13 +410,21 @@ int fd_sess_new ( struct session ** session, char * diamId, char * opt, size_t o
/* Find the position in that list. We take it in reverse order */
for (li = exp_sentinel.prev; li != &exp_sentinel; li = li->prev) {
struct session * s = (struct session *)(li->o);
if (TS_IS_INFERIOR( &s->timeout, &sess->timeout ) )
break;
continue;
}
fd_list_insert_after( li, &sess->expire );
#if 0
if (TRACE_BOOL(ANNOYING)) {
TRACE_DEBUG(FULL, "-- Updated session expiry list --");
for (li = exp_sentinel.next; li != &exp_sentinel; li = li->next) {
struct session * s = (struct session *)(li->o);
fd_sess_dump(FULL, s);
}
TRACE_DEBUG(FULL, "-- end of expiry list --");
}
#endif
/* We added a new expiring element, we must signal */
CHECK_POSIX( pthread_cond_signal(&exp_cond) );
......@@ -502,6 +511,17 @@ int fd_sess_settimeout( struct session * session, const struct timespec * timeou
/* We added a new expiring element, we must signal */
CHECK_POSIX( pthread_cond_signal(&exp_cond) );
#if 0
if (TRACE_BOOL(ANNOYING)) {
TRACE_DEBUG(FULL, "-- Updated session expiry list --");
for (li = exp_sentinel.next; li != &exp_sentinel; li = li->next) {
struct session * s = (struct session *)(li->o);
fd_sess_dump(FULL, s);
}
TRACE_DEBUG(FULL, "-- end of expiry list --");
}
#endif
/* We're done */
CHECK_POSIX( pthread_mutex_unlock( &exp_lock ) );
......@@ -547,7 +567,7 @@ int fd_sess_destroy ( struct session ** session )
/* Save a state information with a session */
int fd_sess_state_store ( struct session_handler * handler, struct session * session, session_state ** state )
int fd_sess_state_store_int ( struct session_handler * handler, struct session * session, session_state ** state )
{
struct state *new;
struct fd_list * li;
......@@ -596,7 +616,7 @@ int fd_sess_state_store ( struct session_handler * handler, struct session * ses
}
/* Get the data back */
int fd_sess_state_retrieve ( struct session_handler * handler, struct session * session, session_state ** state )
int fd_sess_state_retrieve_int ( struct session_handler * handler, struct session * session, session_state ** state )
{
struct fd_list * li;
struct state * st = NULL;
......@@ -631,29 +651,34 @@ int fd_sess_state_retrieve ( struct session_handler * handler, struct session *
}
/* Dump functions */
void fd_sess_dump(int level, struct session * session)
{
struct fd_list * li;
char buf[30];
struct tm tm;
if (!TRACE_BOOL(level))
return;
fd_log_debug("Session @%p:\n", session);
fd_log_debug("\t %*s -- Session @%p --\n", level, "", session);
if (!VALIDATE_SI(session)) {
fd_log_debug(" Invalid session object\n");
return;
}
fd_log_debug("\t %*s Invalid session object\n", level, "");
} else {
fd_log_debug(" sid '%s', hash %x\n", session->sid, session->hash);
fd_log_debug(" timeout %d.%09d\n", session->timeout.tv_sec, session->timeout.tv_nsec);
CHECK_POSIX_DO( pthread_mutex_lock(&session->stlock), /* ignore */ );
for (li = session->states.next; li != &session->states; li = li->next) {
struct state * st = (struct state *)(li->o);
fd_log_debug(" handler %d registered data %p\n", st->hdl->id, st->state);
fd_log_debug("\t %*s sid '%s', hash %x\n", level, "", session->sid, session->hash);
strftime(buf, sizeof(buf), "%D,%T", localtime_r( &session->timeout.tv_sec , &tm ));
fd_log_debug("\t %*s timeout %s.%09ld\n", level, "", buf, session->timeout.tv_nsec);
CHECK_POSIX_DO( pthread_mutex_lock(&session->stlock), /* ignore */ );
for (li = session->states.next; li != &session->states; li = li->next) {
struct state * st = (struct state *)(li->o);
fd_log_debug("\t %*s handler %d registered data %p\n", level, "", st->hdl->id, st->state);
}
CHECK_POSIX_DO( pthread_mutex_unlock(&session->stlock), /* ignore */ );
}
CHECK_POSIX_DO( pthread_mutex_unlock(&session->stlock), /* ignore */ );
fd_log_debug("\t %*s -- end of session @%p --\n", level, "", session);
}
void fd_sess_dump_hdl(int level, struct session_handler * handler)
......@@ -661,11 +686,11 @@ void fd_sess_dump_hdl(int level, struct session_handler * handler)
if (!TRACE_BOOL(level))
return;
fd_log_debug("Handler @%p:\n", handler);
fd_log_debug("\t %*s -- Handler @%p --\n", level, "", handler);
if (!VALIDATE_SH(handler)) {
fd_log_debug(" Invalid session handler object\n");
return;
fd_log_debug("\t %*s Invalid session handler object\n", level, "");
} else {
fd_log_debug("\t %*s id %d, cleanup %p\n", level, "", handler->id, handler->cleanup);
}
fd_log_debug(" id %d, cleanup %p\n", handler->id, handler->cleanup);
fd_log_debug("\t %*s -- end of handler @%p --\n", level, "", handler);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment