[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [hobbit] randomizing execution of tests



On Fri, Feb 13, 2009 at 06:01:44PM +0100, Frank Gruellich wrote:
> OTOH with so many servers we can't manage several monitoring groups
> keeping in mind how many checks are in one groups and which one still
> has "free slots" available.  Having such a randomization and spreading
> in time integrated into bbtest-net would be really great.  (Thinking
> about it, spreading in time is maybe difficult because you never know
> how long all tests will take.  Randomization of test order should be
> quite simple.  But I don't know anything about hobbit internals.)

You're right that randomizing the sequence of tests is simple - the
attached patch against 4.3.0 should do that nicely.

Completely untested, but it should work :-) It won't be difficult to
port over to the 4.2.3 version if needed.

Spreading things out over a longer time requires much more of a
re-design. That may happen - I have some ideas about doing a major
re-design of how network tests are done - but it will be a while
before that evolves into any code.


Regards,
Henrik

Index: lib/msort.c
===================================================================
--- lib/msort.c	(revision 6114)
+++ lib/msort.c	(working copy)
@@ -24,6 +24,7 @@
 
 #include "libbbgen.h"
 
+#if 0
 static void *merge(void *left, void *right, 
 		   msortcompare_fn_t comparefn, 
 		   msortgetnext_fn_t getnext, 
@@ -102,8 +103,28 @@
 	/* We have sorted the two halves, now we must merge them together */
 	return merge(left, right, comparefn, getnext, setnext);
 }
+#endif
 
+void *msort(void *head, msortcompare_fn_t comparefn, msortgetnext_fn_t getnext, msortsetnext_fn_t setnext)
+{
+	void *walk;
+	int len, i;
+	void **plist;
 
+	for (walk = head, len=0; (walk); walk = getnext(walk)) len++;
+	plist = malloc((len+1) * sizeof(void *));
+	for (walk = head, i=0; (walk); walk = getnext(walk)) plist[i++] = walk;
+	plist[len] = NULL;
+
+	qsort(plist, len, sizeof(plist[0]), comparefn);
+
+	for (i=0, head = plist[0]; (i < len); i++) setnext(plist[i], plist[i+1]);
+	xfree(plist);
+
+	return head;
+}
+
+
 #ifdef STANDALONE
 
 typedef struct rec_t {
@@ -117,14 +138,16 @@
 {
 	rec_t *walk;
 
-	walk = head; while (walk) { printf("%-15s:%3s\n", walk->key, walk->val); walk = walk->next; } printf("\n");
+	walk = head; while (walk) { printf("%p : %-15s:%3s\n", walk, walk->key, walk->val); walk = walk->next; } printf("\n");
 	printf("\n");
 }
 
 
-int record_compare(void *a, void *b)
+int record_compare(void **a, void **b)
 {
-	return strcasecmp(((rec_t *)a)->key, ((rec_t *)b)->key);
+	rec_t **reca = (rec_t **)a;
+	rec_t **recb = (rec_t **)b;
+	return strcasecmp((*reca)->key, (*recb)->key);
 }
 
 void * record_getnext(void *a)
Index: lib/msort.h
===================================================================
--- lib/msort.h	(revision 6114)
+++ lib/msort.h	(working copy)
@@ -11,7 +11,7 @@
 #ifndef __MSORT_H__
 #define __MSORT_H__
 
-typedef int (msortcompare_fn_t)(void *, void *);
+typedef int (msortcompare_fn_t)(void **, void **);
 typedef void * (msortgetnext_fn_t)(void *);
 typedef void (msortsetnext_fn_t)(void *, void *);
 extern void *msort(void *head, msortcompare_fn_t comparefn, msortgetnext_fn_t getnext, msortsetnext_fn_t setnext);
Index: bbnet/contest.c
===================================================================
--- bbnet/contest.c	(revision 6114)
+++ bbnet/contest.c	(working copy)
@@ -751,6 +751,25 @@
 #endif
 
 
+static int tcptest_compare(void **a, void **b)
+{
+	tcptest_t **tcpa = (tcptest_t **)a;
+	tcptest_t **tcpb = (tcptest_t **)b;
+
+	if ((*tcpa)->randomizer < (*tcpb)->randomizer) return -1;
+	else if ((*tcpa)->randomizer > (*tcpb)->randomizer) return 1;
+	else return 0;
+}
+static void * tcptest_getnext(void *a)
+{
+	return ((tcptest_t *)a)->next;
+}
+static void tcptest_setnext(void *a, void *newval)
+{
+	((tcptest_t *)a)->next = (tcptest_t *)newval;
+}
+
+
 void do_tcp_tests(int timeout, int concurrency)
 {
 	int		selres;
@@ -791,8 +810,20 @@
 	dbgprintf("Concurrency evaluation: rlim_cur=%lu, FD_SETSIZE=%d, absmax=%d, initial=%d\n", 
 		  lim.rlim_cur, FD_SETSIZE, absmaxconcurrency, concurrency);
 
+	{
+		struct timeval tv;
+		struct timezone tz;
+		gettimeofday(&tv, &tz);
+		srandom(tv.tv_usec);
+	}
+
 	/* How many tests to do ? */
-	for (item = thead; (item); item = item->next) pending++; 
+	for (item = thead; (item); item = item->next) {
+		item->randomizer = random();
+		pending++; 
+	}
+	thead = msort(thead, tcptest_compare, tcptest_getnext, tcptest_setnext);
+
 	firstactive = nextinqueue = thead;
 	dbgprintf("About to do %d TCP tests running %d in parallel, abs.max %d\n", 
 		  pending, concurrency, absmaxconcurrency);
Index: bbnet/contest.h
===================================================================
--- bbnet/contest.h	(revision 6114)
+++ bbnet/contest.h	(working copy)
@@ -78,6 +78,7 @@
 	struct sockaddr_in addr;        /* Address (IP+port) to test */
 	char *srcaddr;
 	struct svcinfo_t *svcinfo;      /* svcinfo_t for service */
+	long int randomizer;
 	int  fd;                        /* Socket filedescriptor */
 	time_t lastactive;
 	time_t cutoff;
Index: lib/holidays.c
===================================================================
--- lib/holidays.c	(revision 6114)
+++ lib/holidays.c	(working copy)
@@ -328,9 +328,12 @@
 	}
 }
 
-static int record_compare(void *a, void *b)
+static int record_compare(void **a, void **b)
 {
-	return (((holiday_t *)a)->yday < ((holiday_t *)b)->yday);
+	holiday_t **reca = (holiday_t **)a;
+	holiday_t **recb = (holiday_t **)b;
+
+	return ((*reca)->yday < (*recb)->yday);
 }
 
 static void * record_getnext(void *a)