You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2006/07/16 04:31:08 UTC
svn commit: r422338 - in
/directory/branches/apacheds/optimization/benchmarks/src/main/java/org/apache/directory/server/benchmarks:
BindBenchmark.java BindBenchmarkTest.java
Author: akarasulu
Date: Sat Jul 15 19:31:07 2006
New Revision: 422338
URL: http://svn.apache.org/viewvc?rev=422338&view=rev
Log:
Added the BindBenchmark written for use with SLAMD. Right now
this project will not compile unless it has some dependencies
like the netscape LDAP sdk added to it. I will figure out how
to add these deps before incorporating it into the main build.
Added:
directory/branches/apacheds/optimization/benchmarks/src/main/java/org/apache/directory/server/benchmarks/BindBenchmark.java
Removed:
directory/branches/apacheds/optimization/benchmarks/src/main/java/org/apache/directory/server/benchmarks/BindBenchmarkTest.java
Added: directory/branches/apacheds/optimization/benchmarks/src/main/java/org/apache/directory/server/benchmarks/BindBenchmark.java
URL: http://svn.apache.org/viewvc/directory/branches/apacheds/optimization/benchmarks/src/main/java/org/apache/directory/server/benchmarks/BindBenchmark.java?rev=422338&view=auto
==============================================================================
--- directory/branches/apacheds/optimization/benchmarks/src/main/java/org/apache/directory/server/benchmarks/BindBenchmark.java (added)
+++ directory/branches/apacheds/optimization/benchmarks/src/main/java/org/apache/directory/server/benchmarks/BindBenchmark.java Sat Jul 15 19:31:07 2006
@@ -0,0 +1,605 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.directory.server.benchmarks;
+
+
+import java.util.ArrayList;
+import java.util.Date;
+
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPConstraints;
+import netscape.ldap.LDAPException;
+
+import com.sun.slamd.job.JobClass;
+import com.sun.slamd.job.UnableToRunException;
+import com.sun.slamd.parameter.IntegerParameter;
+import com.sun.slamd.parameter.InvalidValueException;
+import com.sun.slamd.parameter.Parameter;
+import com.sun.slamd.parameter.ParameterList;
+import com.sun.slamd.parameter.PasswordParameter;
+import com.sun.slamd.parameter.PlaceholderParameter;
+import com.sun.slamd.parameter.StringParameter;
+import com.sun.slamd.stat.IncrementalTracker;
+import com.sun.slamd.stat.RealTimeStatReporter;
+import com.sun.slamd.stat.StatTracker;
+import com.sun.slamd.stat.TimeTracker;
+
+
+/**
+ *
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class BindBenchmark extends JobClass
+{
+ /**
+ * The name of the stat tracker that will be used to count the number of
+ * authentication attempts.
+ */
+ public static final String STAT_TRACKER_AUTHENTICATION_ATTEMPTS = "Authentication Attempts";
+
+ /**
+ * The name of the stat tracker that will be used to keep track of the time
+ * required to perform each authentication.
+ */
+ public static final String STAT_TRACKER_AUTHENTICATION_TIME = "Authentication Time";
+
+ /**
+ * The name of the stat tracker that will be used to count the number of
+ * failed authentications.
+ */
+ public static final String STAT_TRACKER_FAILED_AUTHENTICATIONS = "Failed Authentications";
+
+ /**
+ * The name of the stat tracker that will be used to count the number of
+ * successful authentications.
+ */
+ public static final String STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS = "Successful Authentications";
+
+ // -----------------------------------------------------------------------
+ // Extracted paramter values for the whole Job
+ // -----------------------------------------------------------------------
+
+ // Indicates whether bind failures because of invalid credentials will be
+ // ignored (so we can optimize for authn failures as well).
+ static boolean ignoreInvalidCredentials;
+
+ // The maximum number of iterations per thread.
+ static int iterations;
+
+ // The maximum length of time that any single LDAP operation will be allowed
+ // to take before it is cancelled.
+ static int timeLimit;
+
+ // The time to start working before beginning statistics collection.
+ static int warmUpTime;
+
+ // The delay in milliseconds between authentication attempts.
+ static long delay;
+
+ // The port number of the directory server.
+ static int directoryPort;
+
+ // The address of the directory server.
+ static String directoryHost;
+
+ // The DN to use to bind to the directory
+ static String bindDN;
+
+ // The password for the bind DN.
+ static String bindPW;
+
+ // -----------------------------------------------------------------------
+ // Paramters definitions
+ // -----------------------------------------------------------------------
+
+ // The parameter that indicates the delay that should be used between each
+ // authentication attempt.
+ IntegerParameter delayParameter = new IntegerParameter( "delay", "Time Between Authentications (ms)",
+ "Specifies the length of time in milliseconds " + "each thread should wait between authentication "
+ + "attempts. Note that this delay will be " + "between the starts of consecutive attempts and "
+ + "not between the end of one attempt and the " + "beginning of the next. If an authentication "
+ + "takes longer than this length of time, then " + "there will be no delay.", true, 0, true, 0, false, 0 );
+
+ // The parameter that indicates the number of iterations to perform.
+ IntegerParameter iterationsParameter = new IntegerParameter( "num_iterations", "Number of Iterations",
+ "The number of authentications that should be " + "performed by each thread", false, -1 );
+
+ // The parameter used to indicate the maximum length of time that any single
+ // LDAP operation will be allowed to take.
+ IntegerParameter timeLimitParameter = new IntegerParameter( "time_limit", "Operation Time Limit",
+ "The maximum length of time in seconds that any " + "single LDAP operation will be allowed to take "
+ + "before it is cancelled.", true, 0, true, 0, false, 0 );
+
+ // The parmeter that specifies the cool-down time in seconds.
+ IntegerParameter warmUpParameter = new IntegerParameter( "warm_up", "Warm Up Time",
+ "The time in seconds that the job should " + "search before beginning statistics collection.", true, 0, true,
+ 0, false, 0 );
+
+ // The placeholder parameter used as a spacer in the admin interface.
+ PlaceholderParameter placeholder = new PlaceholderParameter();
+
+ // The parameter used to indicate the port number for the directory server.
+ IntegerParameter portParameter = new IntegerParameter( "ldap_port", "Directory Server Port",
+ "The port number for the directory server.", true, 389, true, 1, true, 65535 );
+
+ // The parameter used to indicate the address of the directory server.
+ StringParameter hostParameter = new StringParameter( "ldap_host", "Directory Server Address",
+ "The address for the directory server.", true, "" );
+
+ // The parameter used to indicate the bind DN.
+ StringParameter bindDNParameter = new StringParameter( "binddn", "Directory Bind DN",
+ "The DN to use when binding to the directory server.", false, "" );
+
+ // The parameter used to indicate the bind DN.
+ PasswordParameter bindPWParameter = new PasswordParameter( "bindpw", "Bind Password",
+ "The password to use when binding.", false, "" );
+
+ // -----------------------------------------------------------------------
+ // Stat trakers for each thread.
+ // -----------------------------------------------------------------------
+
+ // The stat tracker that will count the # of authentication attempts.
+ IncrementalTracker attemptCounter;
+
+ // The stat tracker that will count the # of failed authentications.
+ IncrementalTracker failureCounter;
+
+ // The stat tracker that will count the # of successful authentications.
+ IncrementalTracker successCounter;
+
+ // The stat tracker that will time each authentication.
+ TimeTracker authTimer;
+
+ // -----------------------------------------------------------------------
+ // Connection and other parameters for each thread
+ // -----------------------------------------------------------------------
+
+ // The LDAP connection that will be used for bind operations by this thread.
+ LDAPConnection bindConnection;
+
+ // The set of constraints that will be used for bind operations.
+ LDAPConstraints bindConstraints;
+
+
+ public String getJobDescription()
+ {
+ return "Does a bind using a single user name then immediately unbinds.";
+ }
+
+
+ public String getJobName()
+ {
+ return "Bind/Unbind Optimization Test";
+ }
+
+
+ public String getJobCategoryName()
+ {
+ return "ApacheDS Optimization Tests";
+ }
+
+
+ /**
+ * Returns the set of parameters whose value may be specified by the end user.
+ *
+ * @return The set of configurable parameters for this job class.
+ */
+ public ParameterList getParameterStubs()
+ {
+ Parameter[] parameterArray = new Parameter[]
+ { placeholder, hostParameter, portParameter, bindDNParameter, bindPWParameter, placeholder,
+ warmUpParameter, timeLimitParameter, delayParameter, placeholder,
+ iterationsParameter };
+
+ return new ParameterList( parameterArray );
+ }
+
+
+ public StatTracker[] getStatTrackerStubs( String clientID, String threadID, int collectionInterval )
+ {
+ return new StatTracker[]
+ {
+ new IncrementalTracker( clientID, threadID, STAT_TRACKER_AUTHENTICATION_ATTEMPTS, collectionInterval ),
+ new IncrementalTracker( clientID, threadID, STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS, collectionInterval ),
+ new IncrementalTracker( clientID, threadID, STAT_TRACKER_FAILED_AUTHENTICATIONS, collectionInterval ),
+ new TimeTracker( clientID, threadID, STAT_TRACKER_AUTHENTICATION_TIME, collectionInterval ) };
+ }
+
+
+ public StatTracker[] getStatTrackers()
+ {
+ return new StatTracker[]
+ { attemptCounter, successCounter, failureCounter, authTimer };
+ }
+
+
+ public void validateJobInfo( int numClients, int threadsPerClient, int threadStartupDelay, Date startTime,
+ Date stopTime, int duration, int collectionInterval, ParameterList parameters ) throws InvalidValueException
+ {
+ // might want to add something here later
+ }
+
+
+ public boolean providesParameterTest()
+ {
+ return true;
+ }
+
+
+ /**
+ * Provides a means of testing the provided job parameters to determine
+ * whether they are valid (e.g., to see if the server is reachable) before
+ * scheduling the job for execution. This method will be executed by the
+ * SLAMD server system itself and not by any of the clients.
+ *
+ * @param parameters The job parameters to be tested.
+ * @param outputMessages The lines of output that were generated as part of
+ * the testing process. Each line of output should
+ * be added to this list as a separate string, and
+ * empty strings (but not <CODE>null</CODE> values)
+ * are allowed to provide separation between
+ * different messages. No formatting should be
+ * provided for these messages, however, since they
+ * may be displayed in either an HTML or plain text
+ * interface.
+ *
+ * @return <CODE>true</CODE> if the test completed successfully, or
+ * <CODE>false</CODE> if not.
+ */
+ public boolean testJobParameters( ParameterList parameters, ArrayList outputMessages )
+ {
+ // Get all the parameters that we might need to perform the test.
+ StringParameter hostParam = parameters.getStringParameter( hostParameter.getName() );
+ if ( ( hostParam == null ) || ( !hostParam.hasValue() ) )
+ {
+ outputMessages.add( "ERROR: No directory server address was provided." );
+ return false;
+ }
+ String host = hostParam.getStringValue();
+
+ IntegerParameter portParam = parameters.getIntegerParameter( portParameter.getName() );
+ if ( ( portParam == null ) || ( !hostParam.hasValue() ) )
+ {
+ outputMessages.add( "ERROR: No directory server port was provided." );
+ return false;
+ }
+ int port = portParam.getIntValue();
+
+ String bindDN = "";
+ StringParameter bindDNParam = parameters.getStringParameter( bindDNParameter.getName() );
+ if ( ( bindDNParam != null ) && bindDNParam.hasValue() )
+ {
+ bindDN = bindDNParam.getStringValue();
+ }
+
+ String bindPassword = "";
+ PasswordParameter bindPWParam = parameters.getPasswordParameter( bindPWParameter.getName() );
+ if ( ( bindPWParam != null ) && bindPWParam.hasValue() )
+ {
+ bindPassword = bindPWParam.getStringValue();
+ }
+
+ // Create the LDAPConnection object that we will use to communicate with the directory server.
+ LDAPConnection conn = new LDAPConnection();
+
+ // Attempt to establish a connection to the directory server.
+ try
+ {
+ outputMessages.add( "Attempting to establish a connection to " + host + ":" + port + "...." );
+ conn.connect( host, port );
+ outputMessages.add( "Connected successfully." );
+ outputMessages.add( "" );
+ }
+ catch ( Exception e )
+ {
+ outputMessages.add( "ERROR: Unable to connect to the directory " + "server: " + stackTraceToString( e ) );
+ return false;
+ }
+
+ // Attempt to bind to the directory server using the bind DN and password.
+ try
+ {
+ outputMessages.add( "Attempting to perform an LDAPv3 bind to the " + "directory server with a DN of '"
+ + bindDN + "'...." );
+ conn.bind( 3, bindDN, bindPassword );
+ outputMessages.add( "Bound successfully." );
+ outputMessages.add( "" );
+ }
+ catch ( Exception e )
+ {
+ try
+ {
+ conn.disconnect();
+ }
+ catch ( Exception e2 )
+ {
+ }
+
+ outputMessages.add( "ERROR: Unable to bind to the directory server: " + stackTraceToString( e ) );
+ return false;
+ }
+
+ // At this point, all tests have passed. Close the connection and return true.
+ try
+ {
+ conn.disconnect();
+ }
+ catch ( Exception e )
+ {
+ }
+
+ outputMessages.add( "All tests completed successfully." );
+ return true;
+ }
+
+
+ /**
+ * Performs initialization for this job on each client immediately before each
+ * thread is created to actually run the job.
+ *
+ * @param clientID The ID assigned to the client running this job.
+ * @param parameters The set of parameters provided to this job that can be
+ * used to customize its behavior.
+ *
+ * @throws UnableToRunException If the client initialization could not be
+ * completed successfully and the job is unable
+ * to run.
+ */
+ public void initializeClient( String clientID, ParameterList parameters ) throws UnableToRunException
+ {
+ // Get the directory server address
+ hostParameter = parameters.getStringParameter( hostParameter.getName() );
+ if ( hostParameter == null )
+ {
+ throw new UnableToRunException( "No directory server host provided." );
+ }
+ else
+ {
+ directoryHost = hostParameter.getStringValue();
+ }
+
+ // Get the directory server port
+ portParameter = parameters.getIntegerParameter( portParameter.getName() );
+ if ( portParameter != null )
+ {
+ directoryPort = portParameter.getIntValue();
+ }
+
+ // Get the DN to use to bind to the directory server.
+ bindDNParameter = parameters.getStringParameter( bindDNParameter.getName() );
+ if ( bindDNParameter == null )
+ {
+ bindDN = "";
+ }
+ else
+ {
+ bindDN = bindDNParameter.getStringValue();
+ }
+
+ // Get the password to use to bind to the directory server.
+ bindPWParameter = parameters.getPasswordParameter( bindPWParameter.getName() );
+ if ( bindPWParameter == null )
+ {
+ bindPW = "";
+ }
+ else
+ {
+ bindPW = bindPWParameter.getStringValue();
+ }
+
+ // Get the warm up time.
+ warmUpTime = 0;
+ warmUpParameter = parameters.getIntegerParameter( warmUpParameter.getName() );
+ if ( warmUpParameter != null )
+ {
+ warmUpTime = warmUpParameter.getIntValue();
+ }
+
+ // Get the max operation time limit.
+ timeLimitParameter = parameters.getIntegerParameter( timeLimitParameter.getName() );
+ if ( timeLimitParameter != null )
+ {
+ timeLimit = timeLimitParameter.getIntValue();
+ }
+
+ // Get the delay between authentication attempts.
+ delay = 0;
+ delayParameter = parameters.getIntegerParameter( delayParameter.getName() );
+ if ( delayParameter != null )
+ {
+ delay = delayParameter.getIntValue();
+ }
+
+ // Get the number of iterations to perform.
+ iterations = -1;
+ iterationsParameter = parameters.getIntegerParameter( iterationsParameter.getName() );
+ if ( ( iterationsParameter != null ) && ( iterationsParameter.hasValue() ) )
+ {
+ iterations = iterationsParameter.getIntValue();
+ }
+ }
+
+
+ public void initializeThread( String clientID, String threadID, int collectionInterval, ParameterList parameters )
+ throws UnableToRunException
+ {
+ bindConnection = new LDAPConnection();
+
+ try
+ {
+ bindConnection.connect( 3, directoryHost, directoryPort, "", "" );
+ }
+ catch ( Exception e )
+ {
+ throw new UnableToRunException( "Unable to establish the connections " + "to the directory server: " + e,
+ e );
+ }
+
+ // Initialize the constraints.
+ bindConstraints = bindConnection.getConstraints();
+ bindConstraints.setTimeLimit( 1000 * timeLimit );
+
+ // Create the stat trackers.
+ attemptCounter = new IncrementalTracker( clientID, threadID, STAT_TRACKER_AUTHENTICATION_ATTEMPTS,
+ collectionInterval );
+ successCounter = new IncrementalTracker( clientID, threadID, STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS,
+ collectionInterval );
+
+ failureCounter = new IncrementalTracker( clientID, threadID, STAT_TRACKER_FAILED_AUTHENTICATIONS,
+ collectionInterval );
+ authTimer = new TimeTracker( clientID, threadID, STAT_TRACKER_AUTHENTICATION_TIME, collectionInterval );
+
+ // Enable real-time reporting of the data for these stat trackers.
+ RealTimeStatReporter statReporter = getStatReporter();
+ if ( statReporter != null )
+ {
+ String jobID = getJobID();
+ attemptCounter.enableRealTimeStats( statReporter, jobID );
+ successCounter.enableRealTimeStats( statReporter, jobID );
+ failureCounter.enableRealTimeStats( statReporter, jobID );
+ authTimer.enableRealTimeStats( statReporter, jobID );
+ }
+ }
+
+
+ /**
+ * Performs the work of actually running the job. When this method completes,
+ * the job will be done.
+ */
+ public void runJob()
+ {
+ // Determine the range of time for which we should collect statistics.
+ long currentTime = System.currentTimeMillis();
+ boolean collectingStats = false;
+ long startCollectingTime = currentTime + ( 1000 * warmUpTime );
+ long stopCollectingTime = Long.MAX_VALUE;
+
+ // See if this thread should operate "infinitely" (i.e., not a fixed number of iterations)
+ boolean infinite = ( iterations <= 0 );
+
+ // Loop until it is time to stop.
+ for ( int ii = 0; !shouldStop() && ( infinite || ii < iterations ); ii++ )
+ {
+ currentTime = System.currentTimeMillis();
+
+ if ( ( !collectingStats ) && ( currentTime >= startCollectingTime ) && ( currentTime < stopCollectingTime ) )
+ {
+ // Start all the stat trackers.
+ attemptCounter.startTracker();
+ successCounter.startTracker();
+ failureCounter.startTracker();
+ authTimer.startTracker();
+ collectingStats = true;
+ }
+ else if ( ( collectingStats ) && ( currentTime >= stopCollectingTime ) )
+ {
+ // Stop all the stat trackers.
+ attemptCounter.stopTracker();
+ successCounter.stopTracker();
+ failureCounter.stopTracker();
+ authTimer.stopTracker();
+ collectingStats = false;
+ }
+
+ // See if we need to sleep before the next attempt
+ if ( delay > 0 )
+ {
+ long now = System.currentTimeMillis();
+ long sleepTime = delay - now;
+
+ if ( sleepTime > 0 )
+ {
+ try
+ {
+ Thread.sleep( sleepTime );
+ }
+ catch ( InterruptedException ie )
+ {
+ }
+
+ if ( shouldStop() )
+ {
+ break;
+ }
+ }
+ }
+
+ if ( collectingStats )
+ {
+ attemptCounter.increment();
+ authTimer.startTimer();
+ }
+
+ // Increment the number of authentication attempts and start the timer
+ try
+ {
+ // Perform a bind as the user to verify that the provided password is
+ // valid.
+ bindConnection.authenticate( 3, bindDN, bindPW );
+ if ( collectingStats )
+ {
+ successCounter.increment();
+ authTimer.stopTimer();
+ }
+ }
+ catch ( LDAPException le )
+ {
+ if ( !( ignoreInvalidCredentials && ( le.getLDAPResultCode() == LDAPException.INVALID_CREDENTIALS ) ) )
+ {
+ if ( collectingStats )
+ {
+ failureCounter.increment();
+ authTimer.stopTimer();
+ }
+ }
+
+ StringBuffer buf = new StringBuffer();
+ buf.append( "LDAPException: " ).append( le.getMessage() )
+ .append( " - " ).append( le.getLDAPErrorMessage() );
+ writeVerbose( buf.toString() );
+ }
+ }
+
+ attemptCounter.stopTracker();
+ successCounter.stopTracker();
+ failureCounter.stopTracker();
+ authTimer.stopTracker();
+ }
+
+
+ /**
+ * Attempts to force this thread to exit by closing the connections to the
+ * directory server and setting them to <CODE>null</CODE>.
+ */
+ public void destroy()
+ {
+ if ( bindConnection != null )
+ {
+ try
+ {
+ bindConnection.disconnect();
+ }
+ catch ( Exception e )
+ {
+ }
+
+ bindConnection = null;
+ }
+ }
+}