Browse Source

Ticket #613 - ldclt: add timestamp, interval, nozeropad, other improvements

https://fedorahosted.org/389/ticket/613
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description:
add new timestamp, interval, nozeropad options - fix interval
added timestamp and sampinterval options
-e timestamp[=strftime format] - add timestamp "|" to the beginning of every
ldclt status update line
-e sampinterval=SECS - print the status update line every SECS seconds
allow specifying the value to use for the increment instead of 1
in incremental mode, rather than just incrementing the value by 1,
allow specifying -e incr=value and use the value for the increment
also wrap the lastVal number instead of just resetting to randomLow
if the lastVal is > randomHigh.
added -e nozeropad option
ldclt will usually generate random numbers used in RDNs and values padded
with 0 e.g. uid=XXXXX is uid=00001 - with the -e nozeropad option, this will
turn uid=X or XX or .. into uid=1 - no zero padding
increment based on low value
was incorrectly computing wrap-around value
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: Yes
Rich Megginson 13 years ago
parent
commit
09efabfbf2

+ 25 - 12
ldap/servers/slapd/tools/ldclt/ldapfct.c

@@ -442,7 +442,7 @@ buildNewBindDN (
   if (mctx.mode & STRING)
     (void) randomString (tttctx, mctx.bindDNNbDigit);
   else
-    rnd (tttctx->buf2, mctx.bindDNLow, mctx.bindDNHigh, mctx.bindDNNbDigit);
+    rnd (tttctx->buf2, mctx.bindDNLow, mctx.bindDNHigh, (mctx.mod2 & M2_NOZEROPAD) ? 0 : mctx.bindDNNbDigit);
 
   /*
    * First, randomize the bind DN.
@@ -991,7 +991,7 @@ connectToLDAP(thread_context *tttctx, const char *bufBindDN, const char *bufPass
      */
     if ((mod2 & M2_RANDOM_SASLAUTHID) && tttctx) {
       rnd (tttctx->buf2, mctx.sasl_authid_low, mctx.sasl_authid_high,
-	   mctx.sasl_authid_nbdigit);
+	   (mctx.mod2 & M2_NOZEROPAD) ? 0 : mctx.sasl_authid_nbdigit);
       strncpy (&(tttctx->bufSaslAuthid[tttctx->startSaslAuthid]),
 	       tttctx->buf2, mctx.sasl_authid_nbdigit);
       my_saslauthid = tttctx->bufSaslAuthid;
@@ -1324,7 +1324,7 @@ buildVersatileAttribute (
 	  num = field->cnt;
 	  field->cnt++;	/* Next value for next loop */
 	}
-	sprintf (tttctx->buf2, "%0*d", field->nb, num);
+	sprintf (tttctx->buf2, "%0*d", (mctx.mod2 & M2_NOZEROPAD) ? 0 : field->nb, num);
 	strcat (attrib->buf, tttctx->buf2);
 	if (field->var != -1)
 	  strcpy (object->var[field->var], tttctx->buf2);
@@ -1347,7 +1347,7 @@ buildVersatileAttribute (
 	  num = field->cnt;
 	  field->cnt++;	/* Next value for next loop */
 	}
-	sprintf (tttctx->buf2, "%0*d", field->nb, num);
+	sprintf (tttctx->buf2, "%0*d", (mctx.mod2 & M2_NOZEROPAD) ? 0 : field->nb, num);
 	strcat (attrib->buf, tttctx->buf2);
 	if (field->var != -1)
 	  strcpy (object->var[field->var], tttctx->buf2);
@@ -1359,7 +1359,7 @@ buildVersatileAttribute (
 	  strcpy (object->var[field->var], field->dlf->str[num]);
 	break;
       case HOW_RND_NUMBER:
-	rnd (tttctx->buf2, field->low, field->high, field->nb);
+	rnd (tttctx->buf2, field->low, field->high, (mctx.mod2 & M2_NOZEROPAD) ? 0 : field->nb);
 	strcat (attrib->buf, tttctx->buf2);
 	if (field->var != -1)
 	  strcpy (object->var[field->var], tttctx->buf2);
@@ -1430,7 +1430,7 @@ buildRandomRdnOrFilter (
       (void) randomString (tttctx, mctx.baseDNNbDigit);
     else
       rnd (tttctx->buf2, mctx.baseDNLow, mctx.baseDNHigh,	/*JLS 14-11-00*/
-					mctx.baseDNNbDigit);	/*JLS 14-11-00*/
+           (mctx.mod2 & M2_NOZEROPAD) ? 0 : mctx.baseDNNbDigit);	/*JLS 14-11-00*/
     strncpy (&(tttctx->bufBaseDN[tttctx->startBaseDN]), 
 			tttctx->buf2, mctx.baseDNNbDigit);
     if (mctx.mode & VERY_VERBOSE)
@@ -1481,9 +1481,12 @@ buildRandomRdnOrFilter (
 	(void) randomString (tttctx, mctx.randomNbDigit);
       else
 	rnd (tttctx->buf2, mctx.randomLow, mctx.randomHigh,	/*JLS 14-11-00*/
-			mctx.randomNbDigit);			/*JLS 14-11-00*/
+	     (mctx.mod2 & M2_NOZEROPAD) ? 0 : mctx.randomNbDigit);			/*JLS 14-11-00*/
       strncpy (&(tttctx->bufFilter[tttctx->startRandom]), 
-			tttctx->buf2, mctx.randomNbDigit);
+               tttctx->buf2, mctx.randomNbDigit);
+      if ((mctx.mod2 & M2_NOZEROPAD) && mctx.randomTail) {
+        strcat(tttctx->bufFilter, mctx.randomTail);
+      }
       if (mctx.mode & VERY_VERBOSE)
 	printf ("ldclt[%d]: %s: random mode:filter=\"%s\"\n",
                  mctx.pid, tttctx->thrdId, tttctx->bufFilter);
@@ -1496,11 +1499,11 @@ buildRandomRdnOrFilter (
 	val = incrementCommonCounter (tttctx);			/*JLS 14-03-01*/
 	if (val == -1)						/*JLS 14-03-01*/
 	  return (-1);						/*JLS 14-03-01*/
-	sprintf (tttctx->buf2, "%0*d", mctx.randomNbDigit, val);/*JLS 14-03-01*/
+	sprintf (tttctx->buf2, "%0*d", (mctx.mod2 & M2_NOZEROPAD) ? 0 : mctx.randomNbDigit, val);/*JLS 14-03-01*/
       }								/*JLS 14-03-01*/
       else							/*JLS 14-03-01*/
       {								/*JLS 14-03-01*/
-	tttctx->lastVal++;
+	tttctx->lastVal += mctx.incr;
 	if (tttctx->lastVal > mctx.randomHigh)
 	{
 	  if (!(mctx.mode & NOLOOP))
@@ -1511,16 +1514,19 @@ buildRandomRdnOrFilter (
 	     * Well, there is no clean way to exit. Let's use the error
 	     * condition and hope all will be ok.
 	     */
-	    printf ("ldclt[%d]: %s: Hit top incrementeal value\n",
+	    printf ("ldclt[%d]: %s: Hit top incremental value\n",
                      mctx.pid, tttctx->thrdId);
 	    return (-1);
 	  }
 	}
-	sprintf (tttctx->buf2, "%0*d", mctx.randomNbDigit, tttctx->lastVal);
+	sprintf (tttctx->buf2, "%0*d", (mctx.mod2 & M2_NOZEROPAD) ? 0 : mctx.randomNbDigit, tttctx->lastVal);
       }								/*JLS 14-03-01*/
 
       strncpy (&(tttctx->bufFilter[tttctx->startRandom]), tttctx->buf2,
 			mctx.randomNbDigit);
+      if ((mctx.mod2 & M2_NOZEROPAD) && mctx.randomTail) {
+        strcat(tttctx->bufFilter, mctx.randomTail);
+      }
       if (mctx.mode & VERY_VERBOSE)
 	printf ("ldclt[%d]: %s: incremental mode:filter=\"%s\"\n",
                  mctx.pid, tttctx->thrdId, tttctx->bufFilter);
@@ -3919,6 +3925,7 @@ doExactSearch (
     }
     else
     { /* if search success & we are in verbose mode */
+      int nentries = 0;
       if (mctx.mode & VERBOSE)
       {
         for (e = ldap_first_message (tttctx->ldapCtx, res); e != NULL ; e = ldap_next_message (tttctx->ldapCtx, e) )
@@ -3928,6 +3935,7 @@ doExactSearch (
           {
             /* if this is an entry that returned */
             case LDAP_RES_SEARCH_ENTRY:
+              nentries++;
               /* get dereferenced value into resctrls:  deref parsing  */
               parse_rc = ldap_get_entry_controls ( tttctx->ldapCtx, e, &resctrls );
               if ( resctrls != NULL ) 
@@ -3975,6 +3983,11 @@ doExactSearch (
         } /*end of message retriving */
       } /* end of verbose mode */
 
+      if ((mctx.srch_nentries > -1) && (mctx.srch_nentries != nentries)) {
+        printf ("Error: search returned %d entries not the requested %d entries\n", nentries, mctx.srch_nentries);
+        goto bail;
+      }
+
       if (incrementNbOpers (tttctx) < 0)/* Memorize operation */
       {
         goto bail;

+ 42 - 2
ldap/servers/slapd/tools/ldclt/ldclt.c

@@ -777,10 +777,21 @@ monitorThem (void)
   int	 nbOpersTot;	/* Total nb of operations */
   int	 allDead = 0;	/* All threads are dead */
   int	 status;	/* Thread's status */			/*JLS 17-11-00*/
+  time_t t;
+  struct tm *tmstr;
+  char   timestamp[128];
 
   while (!allDead)
   {
     ldclt_sleep (mctx.sampling);
+    if (mctx.tsfmt) {
+      t = time(NULL);
+      tmstr = localtime(&t);
+      strftime(timestamp, sizeof(timestamp), mctx.tsfmt, tmstr);
+    } else {
+      timestamp[0] = '\0';
+    }
+
     nbOpersTot = 0;
     allDead    = 1;	/* Assume all threads are dead */
 
@@ -853,7 +864,8 @@ monitorThem (void)
     /*
      * Summary of operations
      */
-    printf ("ldclt[%d]: Average rate: %7.2f/thr  (%7.2f/sec), total: %6d\n",
+    printf ("%s%sldclt[%d]: Average rate: %7.2f/thr  (%7.2f/sec), total: %6d\n",
+                timestamp, mctx.tsfmt ? "|" : "",
 		mctx.pid, (float)nbOpersTot/(float)mctx.nbThreads,
 		(float)nbOpersTot/(float)mctx.sampling, nbOpersTot);
     fflush (stdout);
@@ -1355,7 +1367,7 @@ basicInit (void)
       fflush (stderr);						/*JLS 14-03-01*/
       return (-1);						/*JLS 14-03-01*/
     }								/*JLS 14-03-01*/
-    mctx.lastVal = mctx.randomLow-1;				/*JLS 14-03-01*/
+    mctx.lastVal = mctx.randomLow-mctx.incr;			/*JLS 14-03-01*/
   }								/*JLS 14-03-01*/
 
   /*
@@ -2251,6 +2263,14 @@ char *execParams[] = {
 	"deref",
 #define EP_ATT_REPLACE_FILE		51
 	"attreplacefile",
+#define EP_SRCH_NENTRIES                52 /* number of entries that must be returned by each search */
+        "srchnentries",
+#define EP_SAMP_INTERVAL                53 /* sampling interval */
+        "sampinterval",
+#define EP_TIMESTAMP                    54 /* show timestamp when reporting progress */
+        "timestamp",
+#define EP_NOZEROPAD                    55 /* do not zero pad numbers created by XXX patterns in values and RDNs */
+        "nozeropad",
 	NULL
 };
 
@@ -2357,6 +2377,8 @@ decodeExecParams (
 	break;							/*JLS 16-11-00*/
       case EP_INCREMENTAL:
 	mctx.mode |= INCREMENTAL;
+	if (subvalue)
+	  mctx.incr = atoi (subvalue);
 	break;
       case EP_KEYDB_FILE:					/* BK 23-11-00*/
 	mctx.mode |= CLTAUTH;				        /* BK 23-11-00*/
@@ -2385,6 +2407,9 @@ decodeExecParams (
       case EP_NOLOOP:
 	mctx.mode |= NOLOOP;
 	break;
+      case EP_NOZEROPAD:
+        mctx.mod2 |= M2_NOZEROPAD;
+        break;
       case EP_OBJECT:						/*JLS 19-03-01*/
 	mctx.mod2 |= M2_OBJECT;				        /*JLS 19-03-01*/
 	if (subvalue == NULL)					/*JLS 19-03-01*/
@@ -2554,6 +2579,19 @@ decodeExecParams (
 		mctx.attrpl = NULL;
 	}
 	break;
+      case EP_SRCH_NENTRIES:
+        mctx.srch_nentries = atoi (subvalue);
+        break;
+      case EP_SAMP_INTERVAL:
+        mctx.sampling = atoi (subvalue);
+        break;
+      case EP_TIMESTAMP:
+        if (subvalue) {
+          mctx.tsfmt = strdup (subvalue);
+        } else {
+          mctx.tsfmt = strdup (DEFAULT_TIMESTAMP_FMT);
+        }
+        break;
       default:
 	fprintf (stderr, "Error: illegal option -e %s\n", subvalue);
 	return (-1);
@@ -2683,6 +2721,7 @@ main (
   mctx.images	     = NULL;					/*JLS 17-11-00*/
   mctx.imagesDir     = DEF_IMAGES_PATH;				/*JLS 16-11-00*/
   mctx.inactivMax    = DEF_INACTIV_MAX;
+  mctx.incr          = 1;
   mctx.maxErrors     = DEF_MAX_ERRORS;
   mctx.mode	     = NOTHING;
   mctx.mod2	     = NOTHING;
@@ -2706,6 +2745,7 @@ main (
   mctx.scope	     = DEF_SCOPE;
   mctx.slaveConn     = 0;
   mctx.slavesNb      = 0;
+  mctx.srch_nentries = -1;
   mctx.timeout	     = DEF_TIMEOUT;
   mctx.totalReq	     = -1;
   mctx.waitSec       = 0;

+ 10 - 5
ldap/servers/slapd/tools/ldclt/ldclt.h

@@ -277,9 +277,10 @@ dd/mm/yy | Author	| Comments
 #define M2_BINDONLY	0x00000020 /* -e bindonly */		/*JLS 04-05-01*/
 #define M2_SASLAUTH     0x00000040 /* -o : SASL authentication */
 #define M2_RANDOM_SASLAUTHID     0x00000080 /* -e randomauthid */
-#define M2_ABANDON     0x00000100 /* -e abandon */
-#define M2_DEREF     0x00000200 /* -e deref */
+#define M2_ABANDON      0x00000100 /* -e abandon */
+#define M2_DEREF        0x00000200 /* -e deref */
 #define M2_ATTR_REPLACE_FILE	 0x00000400 /* -e attreplacefile */
+#define M2_NOZEROPAD    0x00000800 /* -e nozeropad */
 
 /*
  * Combinatory defines
@@ -511,7 +512,7 @@ typedef struct main_context {
 	char		*attrpl;	/* Attrib argument */	/*JLS 21-11-00*/
 	char		*attrplFile;	/* Attrib file to get value from */
 	char		*attrplFileContent;	/* Attrib file content */
-	int		attrplFileSize;		/* Attrib file size*/
+	int		 attrplFileSize;	/* Attrib file size*/
 	char		*attrplHead;	/* Attrib value head */	/*JLS 21-11-00*/
 	char		*attrplName;	/* Attrib name */	/*JLS 21-11-00*/
 	int		 attrplNbDigit;	/* Attrib nb digits */	/*JLS 21-11-00*/
@@ -549,8 +550,9 @@ typedef struct main_context {
 	int		 imagesLast;	/* Last selected image */
 	ldclt_mutex_t	 imagesLast_mutex; /* Protect imagesLast */
 	int		 inactivMax;	/* Allowed inactivity */
-        char            *keydbfile;     /* key DB file */       /* BK 23-11-00*/
-        char            *keydbpin;      /* key DB password */   /* BK 23-11-00*/
+	int              incr;          /* in incremental mode, number to use to increment (default 1) */
+	char            *keydbfile;     /* key DB file */       /* BK 23-11-00*/
+	char            *keydbpin;      /* key DB password */   /* BK 23-11-00*/
 	int		 lastVal;	/* To build filters */	/*JLS 14-03-01*/
 	ldclt_mutex_t	 lastVal_mutex;	/* Protect lastVal */	/*JLS 14-03-01*/
 	int		 ldapauth;	/* Used to indicate auth type */
@@ -593,12 +595,15 @@ typedef struct main_context {
 	int		 slaveConn;	/* Slave has connected */
 	char		*slaves[MAX_SLAVES]; /* Slaves list */
 	int		 slavesNb;	/* Number of slaves */
+	int              srch_nentries; /* number of entries that must be returned by each search op */
 	int		 timeout;	/* LDAP op. t.o. */
 	struct timeval	 timeval;	/* Timeval structure */
 	struct timeval	 timevalZero;	/* Timeout of zero */
 	int		 totalReq;	/* Total requested */
 	int		 totNbOpers;	/* Total opers number */
 	int		 totNbSamples;	/* Total samples nb */
+#define DEFAULT_TIMESTAMP_FMT "%s"
+	char            *tsfmt;         /* if non-null, use this strftime format to print timestamps for status updates */
 	int		 waitSec;	/* Wait between two operations */
 } main_context;
 

+ 3 - 3
ldap/servers/slapd/tools/ldclt/threadMain.c

@@ -343,17 +343,17 @@ incrementCommonCounter (
   /*
    * Compute next value
    */
-  if ((mctx.mode & NOLOOP) && (mctx.lastVal == mctx.randomHigh))
+  if ((mctx.mode & NOLOOP) && (mctx.lastVal >= mctx.randomHigh))
     val = -1;
   else
   {
-    mctx.lastVal++;
+    mctx.lastVal += mctx.incr;
     if (mctx.lastVal > mctx.randomHigh)
     {
       if (mctx.mode & NOLOOP)
 	val = -1;
       else
-	mctx.lastVal = mctx.randomLow;
+	mctx.lastVal -= (mctx.randomHigh-mctx.incr) + mctx.randomLow;
     }
     val = mctx.lastVal;
   }

+ 2 - 2
ldap/servers/slapd/tools/ldclt/utils.c

@@ -199,10 +199,10 @@ rndlim (
 			arguments. The string is returned in the buffer.
 	INPUT :		low	= low limit
 			high	= high limit
-			ndigits	= number of digits
+			ndigits	= number of digits - 0 means no zero pad
 	OUTPUT :	buf	= buffer to write the random string. Note that
 				  it is generated with fixed number of digits,
-				  completed with leading '0'.
+				  completed with leading '0', if ndigits > 0
 	RETURN :	None.
 	DESCRIPTION :
  *****************************************************************************/