changeset 1121:ccbd1426e04a

Improve testmesg_stress to measure impact of loaded dictionary
author Sebastien Decugis <sdecugis@freediameter.net>
date Tue, 14 May 2013 15:27:28 +0800
parents c473581adff2
children d4371b7aa0ff
files extensions/dbg_msg_timings/dbg_msg_timings.c extensions/dict_mip6a/dict_mip6a.c libfdproto/dictionary.c libfdproto/messages.c tests/testmesg_stress.c
diffstat 5 files changed, 167 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/dbg_msg_timings/dbg_msg_timings.c	Tue May 14 12:32:28 2013 +0800
+++ b/extensions/dbg_msg_timings/dbg_msg_timings.c	Tue May 14 15:27:28 2013 +0800
@@ -77,22 +77,21 @@
 			ASSERT(qpmd->sent_on.tv_sec); /* same, would mean the HOOK_MESSAGE_SENT hook was not trigged */
 			TS_DIFFERENCE( &delay, &qpmd->sent_on, &pmd->received_on );
 			CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), return );
-			LOG_N("[TIMING] RCV ANS %ld.%06ld sec: %s", (long)delay.tv_sec, delay.tv_nsec / 1000, buf);
+			LOG_N("[TIMING] RCV ANS %ld.%06ld sec <-'%s': %s", (long)delay.tv_sec, delay.tv_nsec / 1000, peer ? peer->info.pi_diamid : "<unidentified>", buf);
 		}
 	} else if (type == HOOK_MESSAGE_SENT) {
 		DiamId_t source = NULL;
-		size_t slen = 0;
 		
 		(void)clock_gettime(CLOCK_REALTIME, &pmd->sent_on);
 		
 		/* Is this a forwarded message ? */
-		CHECK_FCT_DO( fd_msg_source_get(msg, &source, &slen), return );
+		CHECK_FCT_DO( fd_msg_source_get(msg, &source, NULL), return );
 		if (source) {
 			struct timespec delay;
 			ASSERT(pmd->received_on.tv_sec);
 			TS_DIFFERENCE( &delay, &pmd->received_on, &pmd->sent_on );
 			CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), return );
-			LOG_N("[TIMING] FWD %ld.%06ld sec: %s", (long)delay.tv_sec, delay.tv_nsec / 1000, buf);
+			LOG_N("[TIMING] FWD %ld.%06ld sec '%s'->'%s': %s", (long)delay.tv_sec, delay.tv_nsec / 1000, source, peer ? peer->info.pi_diamid : "<unidentified>", buf);
 		} else if (hdr->msg_flags & CMD_FLAG_REQUEST) {
 			/* We are sending a request issued locally, nothing special to log */
 		} else {
@@ -102,7 +101,7 @@
 				struct timespec delay;
 				TS_DIFFERENCE( &delay, &qpmd->received_on, &pmd->sent_on );
 				CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), return );
-				LOG_N("[TIMING] ANS %ld.%06ld sec: %s", (long)delay.tv_sec, delay.tv_nsec / 1000, buf);
+				LOG_N("[TIMING] ANS %ld.%06ld sec ->'%s': %s", (long)delay.tv_sec, delay.tv_nsec / 1000, peer ? peer->info.pi_diamid : "<unidentified>", buf);
 			}
 		}
 	}
--- a/extensions/dict_mip6a/dict_mip6a.c	Tue May 14 12:32:28 2013 +0800
+++ b/extensions/dict_mip6a/dict_mip6a.c	Tue May 14 15:27:28 2013 +0800
@@ -404,7 +404,7 @@
 			*/
 			struct dict_object * 	 type;
 			struct dict_type_data 	 tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Algorithm-Type)", NULL, NULL, NULL };
-			struct dict_enumval_data t_2 = { "HMAC-SHA-1", { .i32 = 2 }};
+			struct dict_enumval_data t_2 = { "HMAC-SHA-1 [HMAC]", { .i32 = 2 }};
 			struct dict_avp_data data = {
 					345, 					/* Code */
 					0, 					/* Vendor */
--- a/libfdproto/dictionary.c	Tue May 14 12:32:28 2013 +0800
+++ b/libfdproto/dictionary.c	Tue May 14 15:27:28 2013 +0800
@@ -1908,13 +1908,19 @@
 all_errors:
 	if (ret != 0) {
 		char * buf = NULL;
-		size_t len = 0;
+		size_t len = 0, offset=0;
 		
-		CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, NULL, data) );
+		if (type == DICT_ENUMVAL) {
+			CHECK_MALLOC( dump_enumval_data ( &buf, &len, &offset, data, parent->data.type.type_base ));
+		} else {
+			CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, &offset, data) );
+		}
+	
 		TRACE_DEBUG(INFO, "An error occurred while adding the following data in the dictionary: %s", buf);
 		
 		if (ret == EEXIST) {
-			CHECK_MALLOC( dump_object(&buf, &len, NULL, locref, 0, 0, 0) );
+			offset=0;
+			CHECK_MALLOC( dump_object(&buf, &len, &offset, locref, 0, 0, 0) );
 			TRACE_DEBUG(INFO, "Conflicting entry in the dictionary: %s", buf);
 		}
 		free(buf);
--- a/libfdproto/messages.c	Tue May 14 12:32:28 2013 +0800
+++ b/libfdproto/messages.c	Tue May 14 15:27:28 2013 +0800
@@ -884,7 +884,6 @@
 			CHECK_FCT_DO(  fd_msg_browse ( avp, MSG_BRW_FIRST_CHILD, &inavp, NULL ), inavp = NULL );
 			while (inavp) {
 				struct avp * nextavp = NULL;
-				CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL);
 				CHECK_FCT_DO(  fd_msg_browse ( inavp, MSG_BRW_NEXT, &nextavp, NULL ), inavp = NULL  );
 				CHECK_MALLOC_DO( avp_format_treeview(FD_DUMP_STD_PARAMS, inavp, level + 1, first, nextavp ? 0 : 1), return NULL);
 				inavp = nextavp;
--- a/tests/testmesg_stress.c	Tue May 14 12:32:28 2013 +0800
+++ b/tests/testmesg_stress.c	Tue May 14 15:27:28 2013 +0800
@@ -34,6 +34,14 @@
 *********************************************************************************************************/
 
 #include "tests.h"
+#include <dirent.h>
+#include <libgen.h>
+#include <dlfcn.h>
+
+#ifndef BUILD_DIR
+#error "Missing BUILD_DIR information"
+#endif /* BUILD_DIR */
+
 
 /* The number of times each operation is repeated to measure the average operation time */
 #define DEFAULT_NUMBER_OF_SAMPLES	100000
@@ -46,7 +54,138 @@
 	printf("%-19s: %d %-8s %-7s in %.6LFs (%.1LFmsg/s)\n", fct, nr, type, op, dur, thrp);
 }
 
+struct ext_info {
+	struct fd_list	chain;		/* link in the list */
+	void 		*handler;	/* object returned by dlopen() */
+	int 		(*init_cb)(int, int, char *);
+	char		*ext_name;	/* points to the extension name, either inside depends, or basename(filename) */
+	int		free_ext_name;	/* must be freed if it was malloc'd */
+	const char 	**depends;	/* names of the other extensions this one depends on (if provided) */
+};
+	
+static void load_all_extensions(char * prefix)
+{
+	DIR *dir;
+	struct dirent *dp;
+	char fullname[512];
+	int pathlen;
+	struct fd_list all_extensions = FD_LIST_INITIALIZER(all_extensions);
+	struct fd_list ext_with_depends = FD_LIST_INITIALIZER(ext_with_depends);
 
+	/* Find all extensions which have been compiled along the test */
+	LOG_D("Loading %s*.fdx from: '%s'", BUILD_DIR "/extensions", prefix ?: "");
+	CHECK( 0, (dir = opendir (BUILD_DIR "/extensions")) == NULL ? 1 : 0 );
+	pathlen = snprintf(fullname, sizeof(fullname), BUILD_DIR "/extensions/");
+	
+	while ((dp = readdir (dir)) != NULL) {
+		char * dot = strrchr(dp->d_name, '.');
+		if (dot && ((!prefix) || !(strncmp(dp->d_name, prefix, strlen(prefix)))) && (!(strcmp(dot, ".fdx")))) {
+			/* We found a file with name dict_*.fdx, attempt to load it */
+			struct ext_info * new = malloc(sizeof(struct ext_info));
+			CHECK( 1, new ? 1:0);
+			fd_list_init(&new->chain, new);
+			
+			snprintf(fullname + pathlen, sizeof(fullname) - pathlen, "%s", dp->d_name);
+			
+			LOG_D("Extension: '%s'", dp->d_name);
+			
+			/* load */
+			new->handler = dlopen(fullname, RTLD_NOW | RTLD_GLOBAL);
+			if (!new->handler) {
+				TRACE_DEBUG(INFO, "Unable to load '%s': %s.", fullname, dlerror());
+			}
+			CHECK( 0, new->handler == NULL ? 1 : 0 );
+			
+			/* resolve entry */
+			new->init_cb = dlsym( new->handler, "fd_ext_init" );
+			if (!new->init_cb) {
+				TRACE_DEBUG(INFO, "No 'fd_ext_init' entry point in '%s': %s.", fullname, dlerror());
+			}
+			CHECK( 0, new->init_cb == NULL ? 1 : 0 );
+			
+			new->depends = dlsym( new->handler, "fd_ext_depends" );
+			if (new->depends) {
+				new->ext_name = (char *)new->depends[0];
+				new->free_ext_name = 0;
+				if ( new->depends[1] ) {
+					fd_list_insert_before(&ext_with_depends, &new->chain);
+				} else {
+					fd_list_insert_before(&all_extensions, &new->chain);
+				}
+			} else {
+				new->ext_name = strdup(basename(dp->d_name));
+				new->free_ext_name = 1;
+				fd_list_insert_before(&all_extensions, &new->chain);
+			}
+			
+		}
+	}
+	
+	/* Now, reorder the list by dependencies */
+	{
+		int count, prevcount = 0;
+		struct fd_list * li;
+		do {
+			count = 0;
+			for (li=ext_with_depends.next; li != &ext_with_depends; li=li->next) {
+				struct ext_info * e = li->o;
+				int d;
+				int satisfied=0;
+				
+				/* Can we satisfy all dependencies? */
+				for (d=1;  ;d++) {
+					struct fd_list * eli;
+					if (!e->depends[d]) {
+						satisfied = 1;
+						break;
+					}
+					
+					/* can we find this dependency in the list? */
+					for (eli=all_extensions.next; eli != &all_extensions; eli = eli->next) {
+						struct ext_info * de = eli->o;
+						if (!strcasecmp(de->ext_name, e->depends[d]))
+							break; /* this dependency is satisfied */
+					}
+					
+					if (eli == &all_extensions) {
+						satisfied = 0;
+						break;
+					}
+				}
+				
+				if (satisfied) {
+					/* OK, we have all our dependencies in the list */
+					li=li->prev;
+					fd_list_unlink(&e->chain);
+					fd_list_insert_before(&all_extensions, &e->chain);
+				} else {
+					count++;
+				}
+			}
+			
+			if (prevcount && (prevcount == count)) {
+				LOG_E("Some extensions cannot have their dependencies satisfied, e.g.: %s", ((struct ext_info *)ext_with_depends.next->o)->ext_name);
+				CHECK(0, 1);
+			}
+			prevcount = count;
+			
+			if (FD_IS_LIST_EMPTY(&ext_with_depends))
+				break;
+		} while (1);
+	}
+	
+	/* Now, load all the extensions */
+	{
+		struct fd_list * li;
+		for (li=all_extensions.next; li != &all_extensions; li=li->next) {
+			struct ext_info * e = li->o;
+			int ret = (*e->init_cb)( FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR, NULL );
+			LOG_N("Initializing extension '%s': %s", e->ext_name, ret ? strerror(ret) : "Success");
+		}
+	}
+	
+	/* We should probably clean the list here ? */
+}
 
 /* Main test routine */
 int main(int argc, char *argv[])
@@ -54,10 +193,16 @@
 	struct msg * acr = NULL;
 	unsigned char * buf = NULL;
 	
+	int dictionaries_loaded = 0;
+	
 	test_parameter = DEFAULT_NUMBER_OF_SAMPLES;
 	
 	/* First, initialize the daemon modules */
 	INIT_FD();
+	CHECK( 0, fd_queues_init()  );
+	CHECK( 0, fd_msg_init()  );
+	CHECK( 0, fd_rtdisp_init()  );
+	
 	
 	{
 		struct dict_object * acr_model = NULL;
@@ -378,7 +523,7 @@
 	}
 	
 	/* We have our "buf" now, length is 344 -- cf. testmesg.c. */
-	
+redo:	
 	/* Test the throughput of the different functions function */
 	{
 		struct stress_struct {
@@ -530,7 +675,13 @@
 		}
 		free(stress_array);
 	}
-		
+	
+	if (!dictionaries_loaded) {
+		load_all_extensions("dict_");
+		dictionaries_loaded = 1;
+		printf("Loaded all dictionary extensions, restarting...\n");
+		goto redo;
+	}
 	
 	/* That's all for the tests yet */
 	PASSTEST();
"Welcome to our mercurial repository"