mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

andrug
07.53.2008 209619e2e70a11ad978632fe1b20b2c1f7bb1b7a
new scenario 4MMR, using private client addDeleteLoad
11 files added
63441 ■■■■■ changed files
opends/tests/system-tests/scenario/4MMR/4MMR.xml 59 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/addDeleteLoad.xml 300 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/build.ksh 39 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/data/first.names 16917 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/data/last.names 45184 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/run.ksh 28 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/src/Client.java 281 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/src/ExtendedRandom.java 146 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/src/Server.java 46 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/src/Worker.java 209 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/conf.xml 232 ●●●●● patch | view | raw | blame | history
opends/tests/system-tests/scenario/4MMR/4MMR.xml
New file
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "../../../shared/stax.dtd">
<!--
 ! CDDL HEADER START
 !
 ! The contents of this file are subject to the terms of the
 ! Common Development and Distribution License, Version 1.0 only
 ! (the "License").  You may not use this file except in compliance
 ! with the License.
 !
 ! You can obtain a copy of the license at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
 ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 ! See the License for the specific language governing permissions
 ! and limitations under the License.
 !
 ! When distributing Covered Code, include this CDDL HEADER in each
 ! file and include the License file at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 ! add the following below this CDDL HEADER, with the fields enclosed
 ! by brackets "[]" replaced with your own identifying information:
 !      Portions Copyright [yyyy] [name of copyright owner]
 !
 ! CDDL HEADER END
 !
 !      Copyright 2008 Sun Microsystems, Inc.
 ! -->
<stax>
  <defaultcall function="main4MMR"/>
  <function name="main4MMR" scope="local">
      <sequence>
        <import machine="'%s' % (STAF_LOCAL_HOSTNAME)"
          file="'%s/phases/main_run.xml' % (TESTS_DIR)"/>
        <!-- ********************************************************* -->
        <!-- ****************     README               *************** -->
        <!-- directoryName must have the name of the current directory -->
        <!-- pre and post configuration files are stax code based, these
             files allow you to configure the products as you want !-->
        <!-- ********************************************************* -->
        <script>
          DIR_NAME = '4MMR'
          fConf    = '%s/scenario/%s/conf.xml' % (TESTS_DIR,DIR_NAME)
        </script>
        <call function="'main_run'">
        {
         'configurationFile': fConf,
         'runInstallation'  : 'true',
         'runGenerateLdif'  : 'true',
         'runConfiguration' : 'true',
         'runScheduler'     : 'true'
        }
        </call>
    </sequence>
  </function>
</stax>
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/addDeleteLoad.xml
New file
@@ -0,0 +1,300 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "../../../../../shared/stax.dtd">
<!--
 ! CDDL HEADER START
 !
 ! The contents of this file are subject to the terms of the
 ! Common Development and Distribution License, Version 1.0 only
 ! (the "License").  You may not use this file except in compliance
 ! with the License.
 !
 ! You can obtain a copy of the license at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
 ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 ! See the License for the specific language governing permissions
 ! and limitations under the License.
 !
 ! When distributing Covered Code, include this CDDL HEADER in each
 ! file and include the License file at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 ! add the following below this CDDL HEADER, with the fields enclosed
 ! by brackets "[]" replaced with your own identifying information:
 !      Portions Copyright [yyyy] [name of copyright owner]
 !
 ! CDDL HEADER END
 !
 !      Copyright 2008 Sun Microsystems, Inc.
 ! -->
<stax>
  <defaultcall function="addDeleteLoad"/>
  <!-- ************************************************************ -->
  <!-- Client is automatically called by the scheduler and must     -->
  <!-- always define all the parameters below                       -->
  <function name="addDeleteLoad" scope="local">
    <function-map-args>
      <function-arg-def name="workingDir" type="required"/>
      <function-arg-def name="client"     type="required"/>
      <function-arg-def name="instances"  type="required"/>
      <function-arg-def name="duration"   type="required"/>
      <function-arg-def name="suffix"     type="required"/>
      <function-arg-def name="outFile"    type="required"/>
      <function-arg-def name="fileFd"     type="required"/>
    </function-map-args>
    <sequence>
      <!-- ===================   Comments   =================== -->
      <!-- client is run under paralleliterate tag              -->
      <!-- each variables defined are internal                  -->
      <!-- client should have its own err_num variable in order -->
      <!-- to inform scheduler if it has pass/fail status       -->
      <script>
        errNum = 0
        msg = ''
      </script>
      <!-- ==================    Preamble   =================== -->
      <!-- parse the client parameters :                        -->
      <!-- params is [[param1,val1],[param2,val2],...]          -->
      <!-- get the ldap instance parameters                     -->
      <script>
        compilDir = '%s/%s_%s' % (workingDir,client.getHost(),client.getId())
        #
        # Extract client parameters from client.getParams()
        #
        cParams = client.getParams()
        try:
          serverInstanceFromClient = cParams[0][1]
        except IndexError:
          serverInstanceFromClient = NOT_DEFINED
          msg = '%s\nERROR: serverInstanceFromClient undefined,mandatory' % msg
        try:
          baseDn = cParams[1][1]
        except IndexError:
          baseDn = NOT_DEFINED
          msg = '%s\nERROR: baseDn undefined,mandatory' % msg
        try:
          nbCnx = cParams[2][1]
        except IndexError:
          nbCnx = NOT_DEFINED
          msg = '%s\nERROR: nbCnx undefined,mandatory' % msg
        try:
          nbMaxOps = cParams[3][1]
        except IndexError:
          nbMaxOps = NOT_DEFINED
        try:
          attributeName = cParams[4][1]
        except IndexError:
          attributeName = NOT_DEFINED
        #
        # setup parms to run the client
        #
        if serverInstanceFromClient != NOT_DEFINED:
          sys.path.append("%s/phases/scheduler" % TESTS_DIR )
          from scheduler import getInstance
          serverInstance = getInstance(serverInstanceFromClient,instances)
          if (serverInstance == 'ERROR'):
            msg = '%s\nERROR: cant find client instance named' % msg
            msg = '%s %s in server instance list' % \
                  (msg,serverInstanceFromClient)
          else:
            # remove sec, try to finish before timer kill -9 the client
            duration = duration - 20
            parms=[]
            parms.append('-h %s -p %s' % \
                       (serverInstance.getHost(),serverInstance.getLDAPPort()))
            parms.append('-b "%s"' % baseDn)
            parms.append('-D "%s" -w "%s"' % \
                        (DIRECTORY_INSTANCE_DN,DIRECTORY_INSTANCE_PSWD))
            parms.append('-t %s -d %s' % (nbCnx,duration))
            if nbMaxOps != NOT_DEFINED:
              parms.append('-M %s' % nbMaxOps)
            if attributeName != NOT_DEFINED:
              parms.append('-a %s' % attributeName)
            parms = ' '.join(parms)
      </script>
      <if expr="msg.find('ERROR') != -1">
        <sequence>
          <message>'%s' % msg</message>
          <call function="'writeOperationResult'">
            {
              'returncode' : '1',
              'expected'   : '0',
              'result'     : msg,
              'status'     : 'ERROR',
              'fileFd'     : fileFd
            }
          </call>
          <script>
            errNum += 1
          </script>
        </sequence>
      <else>
        <sequence>
          <!-- ==== Add execute permission to build.ksh file ==== -->
          <call function="'writeStartTagOperation'">
          { 'tagName' : 'chmod',
            'fileFd'  : fileFd }
          </call>
          <call function="'writeMessage'">
          {'content' : 'Add execute permission to build.ksh file',
           'fileFd'  : fileFd}
          </call>
          <process name="'%s: chmod +x build.ksh' % client.getHost()">
            <location>client.getHost()</location>
            <command mode="'shell'">'chmod +x build.ksh'</command>
            <parms/>
            <workdir>workingDir</workdir>
            <envs>['PATH=/bin:/usr/bin']</envs>
            <stderr mode="'stdout'"/>
            <stdout/>
            <returnstdout/>
          </process>
          <call function="'checkRC'">
            { 'returncode' : RC,
              'result'     : STAXResult[0][1],
              'fileFd'     : fileFd }
          </call>
          <script>
            errNum += STAXResult
          </script>
          <call function="'writeEndTagOperation'">{'fileFd'  : fileFd}</call>
          <!-- ==== Build client : run build.ksh file ==== -->
          <call function="'writeStartTagOperation'">
          { 'tagName' : 'build',
            'fileFd'  : fileFd }
          </call>
          <call function="'writeMessage'">
          {'content' : 'Build client',
           'fileFd'  : fileFd}
          </call>
          <!-- Build Client in unique directory (compilDir), avoid          -->
          <!-- conflict if same client is run several time at the same time -->
          <process name="'%s: build %s' % (client.getHost(),client.getName())">
            <location>client.getHost()</location>
            <command mode="'shell'">'./build.ksh'</command>
            <parms/>
            <workdir>workingDir</workdir>
            <envs>['PATH=%s/bin:/bin:/usr/bin' % JAVA_HOME,'COMPILDIR=%s' % compilDir]</envs>
            <stderr mode="'stdout'"/>
            <stdout/>
            <returnstdout/>
          </process>
          <call function="'checkRC'">
            { 'returncode' : RC,
              'result'     : STAXResult[0][1],
              'fileFd'     : fileFd }
          </call>
          <if expr="RC != 0">
            <message>
              'FAILED to build client %s on %s' % \
              (client.getName(),client.getHost())
            </message>
          </if>
          <script>
            errNum += STAXResult
          </script>
          <call function="'writeEndTagOperation'">{'fileFd'  : fileFd}</call>
          <!-- ========== Run the client ========== -->
          <call function="'writeStartTagOperation'">
          { 'tagName' : 'run',
            'fileFd'  : fileFd }
          </call>
          <call function="'writeMessage'">
          { 'fileFd'  : fileFd,
            'content' : 'Add and Delete entries on %s:%s' % \
                        (serverInstance.getHost(),serverInstance.getLDAPPort())
          }
          </call>
          <script>
            cParam = '-client -Xmx1G -Xms1G'
            cParam = '%s -XX:NewRatio=1 -XX:SurvivorRatio=100' % cParam
            cParam = '%s -cp %s/clients/LDAPjdk/ldapjdk.jar' \
                      % (cParam,LOCAL_TESTS_DIR)
            cParam = '%s:%s/addDeleteLoad.jar' % (cParam,compilDir)
            cParam = '%s Client %s' % (cParam,parms)
            titleName = '%s: run %s on %s' % \
                        (client.getHost(),client.getName(),
                         serverInstance.getName())
          </script>
          <process name="'%s' % titleName">
            <location>client.getHost()</location>
            <command>'%s/bin/java' % JAVA_HOME</command>
            <parms>cParam </parms>
            <workdir>workingDir</workdir>
            <envs>['PATH=%s/bin:/bin:/usr/bin' % JAVA_HOME]</envs>
            <stderr mode="'stdout'"/>
            <stdout>outFile</stdout>
            <returnstdout/>
          </process>
          <!-- TBD : result should be STAXResult[0][1] : problem when
                     javaexception, with carac " and < >-->
          <call function="'checkRC'">
            { 'returncode' : RC ,
              'result'     : '',
              'fileFd'     : fileFd }
          </call>
          <script>
            errNum += STAXResult
          </script>
          <call function="'writeEndTagOperation'">{'fileFd'  : fileFd}</call>
          <!-- ========== Postamble ========== -->
          <call function="'writeMessage'">
          {'content' : 'Output file %s' % outFile,
           'fileFd'  : fileFd}
          </call>
          <process name="'%s:%s: Grep' % (client.getHost(),client.getName())">
            <location>client.getHost()</location>
            <command mode="'shell'">
              "grep 'TOTAL' %s | cut -d ' ' -f3-" % outFile
            </command>
            <envs>['PATH=/bin:/usr/bin']</envs>
            <stderr mode="'stdout'"/>
            <stdout/>
            <returnstdout/>
          </process>
          <script>
            summary = STAXResult[0][1]
          </script>
          <call function="'writeMessage'">
          {'content' : 'Summary %s' % (summary),
           'fileFd'  : fileFd}
          </call>
        </sequence>
      </else>
      </if>
      <return> errNum </return>
    </sequence>
  </function>
</stax>
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/build.ksh
New file
@@ -0,0 +1,39 @@
#!/bin/ksh
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE
# or https://OpenDS.dev.java.net/OpenDS.LICENSE.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
# add the following below this CDDL HEADER, with the fields enclosed
# information:
#      Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#      Copyright 2008 Sun Microsystems, Inc.
export CLASSPATH=$CLASSPATH:../../../../clients/LDAPjdk/ldapjdk.jar
mkdir -p $COMPILDIR
echo "Compiling classes..."
javac src/*.java -d $COMPILDIR
[ $? -ne 0 ] && return 1
echo "Creating jarfile"
cd $COMPILDIR
jar cvf addDeleteLoad.jar *.class
[ $? -ne 0 ] && return 1
echo "Cleanup"
rm -f *.class
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/data/first.names
New file
Diff too large
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/data/last.names
New file
Diff too large
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/run.ksh
New file
@@ -0,0 +1,28 @@
#!/bin/ksh
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE
# or https://OpenDS.dev.java.net/OpenDS.LICENSE.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
# add the following below this CDDL HEADER, with the fields enclosed
# information:
#      Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#      Copyright 2008 Sun Microsystems, Inc.
java -cp ../../../../clients/LDAPjdk/ldapjdk.jar:addDeleteLoad.jar Client $@
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/src/Client.java
New file
@@ -0,0 +1,281 @@
// CDDL HEADER START
//
// The contents of this file are subject to the terms of the
// Common Development and Distribution License, Version 1.0 only
// (the "License").  You may not use this file except in compliance
// with the License.
//
// You can obtain a copy of the license at
// trunk/opends/resource/legal-notices/OpenDS.LICENSE
// or https://OpenDS.dev.java.net/OpenDS.LICENSE.
// See the License for the specific language governing permissions
// and limitations under the License.
//
// When distributing Covered Code, include this CDDL HEADER in each
// file and include the License file at
// trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
// add the following below this CDDL HEADER, with the fields enclosed
// information:
//      Portions Copyright [yyyy] [name of copyright owner]
//
// CDDL HEADER END
//
//
//      Copyright 2008 Sun Microsystems, Inc.
import netscape.ldap.*;
import netscape.ldap.util.*;
import java.util.*;
import java.io.*;
import java.lang.Thread;
public class Client {
  static int NB_MAX_OPS=100;
  static Object lock;
  static int nb_ops_started=0;
  static int nb_ops_done=0;
  static int total_nb_ops=0;
  static int nb_threads=3;
  public ArrayList<String> DNList;
  static String hostname ;
  static int portnumber;
  static String bindDN;
  static String bindPW;
  static String suffix;
  static Server server;
  static String time= new String ("0 sec.");;
  static long duration=0;
  static long maxDuration=0;
  static long startup=System.currentTimeMillis();
  /*****************************************************************/
  public Client()
  {
    lock = new Object();
    DNList = new ArrayList<String>();
    try {
      // reinitialize startup
      startup=System.currentTimeMillis();
      long t1=System.currentTimeMillis();
      if ( maxDuration != 0 ) {
        maxDuration= t1 + maxDuration * 1000;
      }
      for (int i=0; i < nb_threads; i++ ) {
        Worker w = new Worker(this, server);
      }
      println("INFO", nb_threads + " threads connected to server " + server);
      int seconds=0;
      while (true) {
        long new_t1=System.currentTimeMillis();
        if ( ( maxDuration != 0 ) && ( new_t1 > maxDuration ) ) { break; }
        if ( (new_t1 - t1) >= 1000 ) {
          println("INFO",  nb_ops_done + " ops/sec.");
          // (time = "+(new_t1-t1) + "ms)");
          // println("DEBUG",  nb_ops_started + " ops/sec started");
          total_nb_ops+=nb_ops_done;
          nb_ops_started=0;
          nb_ops_done=0;
          synchronized (lock) {
            lock.notifyAll();
          }
          if ( (seconds++) >= 9 ) {
            duration=((new_t1-startup)/1000);
            println("INFO",  "Avg rate: " + (total_nb_ops/duration)
                    + " ops/sec. after " + getTime(duration));
            seconds=0;
          }
          t1=new_t1;
        }
      }
      System.exit(0);
    }
    catch( Exception e ) {
      e.printStackTrace();
      System.exit(1);
    }
  }
  /*****************************************************************/
  public static String getTime(long d) {
    String time=new String (d + " sec.");
    if ( d > 10000 ) {
      time=new String ((d/3600) + " hours");
    } else if ( d > 300 ) {
      time=new String ((d/60) + " min.");
    }
    return time;
  }
  /*****************************************************************/
  public static void main( String[] args )
  {
    String usage = "Usage: java Main [-h <host>] [-p <port>]  -b <base_dn> "
                    + "[-D <bindDN> ] [-w <bindPW> ] [-t <nb_threads>] "
                    + "[-M <nb_max_ops>] [-d duration (seconds)]";
    int portnumber = LDAPv2.DEFAULT_PORT;
    // Check for these options. -H means to print out a usage message.
    GetOpt options = new GetOpt( "h:p:b:d:D:w:H:t:M:a:", args );
    // Get the arguments specified for each option.
    hostname = options.getOptionParam( 'h' );
    String port = options.getOptionParam( 'p' );
    bindDN = options.getOptionParam( 'D' );
    bindPW = options.getOptionParam( 'w' );
    suffix = options.getOptionParam( 'b' );
    if ( options.hasOption( 't' ) ) {
      nb_threads=Integer.parseInt(options.getOptionParam( 't' ));
    }
    if ( options.hasOption( 'M' ) ) {
      NB_MAX_OPS=Integer.parseInt(options.getOptionParam( 'M' ));
    }
    if ( options.hasOption( 'd' ) ) {
      String sMaxDuration=options.getOptionParam( 'd' );
      maxDuration = Long.parseLong(sMaxDuration);
    }
    //  option -DM to use default QA settings for Directory manager
    if ( bindDN != null && bindDN.equals("M") ) {
      bindDN="cn=Directory Manager";
      bindPW="secret12";
    }
    // Check to see if the hostname (which is mandatory)
    // is not specified or if the user simply wants to
    // see the usage message (-H).
    if ( options.hasOption( 'H' ) || ( suffix == null ) ) {
      System.out.println( usage );
      System.exit( 1 );
    }
    if ( hostname == null ) hostname="localhost";
    // If a port number was specified, convert the port value
    //  to an integer.
    if ( port != null ) {
      try {
        portnumber = java.lang.Integer.parseInt( port );
      } catch ( java.lang.Exception e ) {
        System.out.println( "Invalid port number: " + port );
        System.out.println( usage );
        System.exit( 1 );
      }
    }
    else {
      portnumber=1389;
    }
    server=new Server(hostname,portnumber);
    Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() {
        duration=((System.currentTimeMillis()-startup)/1000);
        if ( duration != 0 )
          println("INFO", "TOTAL: " + total_nb_ops + " ops (Avg rate: "
                  + (total_nb_ops/duration) + " ops/sec.) after "
                  + getTime(duration));
      }
    });
    Client c = new Client();
  }
  /*****************************************************************/
  public static void inc_ops_started() {
    check_ops_started();
    nb_ops_started++;
  }
  /*****************************************************************/
  public static void inc_ops_done() {
    nb_ops_done++;
  }
  /*****************************************************************/
  public static void check_ops_started() {
    if ( nb_ops_started>=NB_MAX_OPS ) {
      //println("DEBUG", "Ops=" + nb_ops);
      try {
        synchronized (lock) {
          lock.wait();
        }
      } catch ( InterruptedException e ) {
        e.printStackTrace();
      }
    }
  }
  /*****************************************************************/
  public static void wait_after_error() {
    try {
      synchronized (lock) {
        lock.wait();
      }
    } catch ( InterruptedException e ) {
      e.printStackTrace();
    }
  }
  /*****************************************************************/
  public static void sleep(int time) {
    try {
      Thread.sleep(time);
    }
    catch ( InterruptedException e )
    {
      println( "ERROR" ,  e.toString() );
    }
  }
  /*****************************************************************/
  public static String getDate() {
    // Initialize the today's date string
    String DATE_FORMAT = "yyyy/MM/dd:HH:mm:ss";
    java.text.SimpleDateFormat sdf =
      new java.text.SimpleDateFormat(DATE_FORMAT);
    Calendar c1 = Calendar.getInstance(); // today
    return("[" + sdf.format(c1.getTime()) + "]");
  }
  /*****************************************************************/
  public static void println(String level, String msg) {
    System.out.println (getDate() + " - " + level + ": " + msg );
  }
}
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/src/ExtendedRandom.java
New file
@@ -0,0 +1,146 @@
// CDDL HEADER START
//
// The contents of this file are subject to the terms of the
// Common Development and Distribution License, Version 1.0 only
// (the "License").  You may not use this file except in compliance
// with the License.
//
// You can obtain a copy of the license at
// trunk/opends/resource/legal-notices/OpenDS.LICENSE
// or https://OpenDS.dev.java.net/OpenDS.LICENSE.
// See the License for the specific language governing permissions
// and limitations under the License.
//
// When distributing Covered Code, include this CDDL HEADER in each
// file and include the License file at
// trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
// add the following below this CDDL HEADER, with the fields enclosed
// information:
//      Portions Copyright [yyyy] [name of copyright owner]
//
// CDDL HEADER END
//
//
//      Copyright 2008 Sun Microsystems, Inc.
import java.util.*;
import java.io.*;
public class ExtendedRandom extends Random {
  ArrayList<String> lastNames;
  ArrayList<String> firstNames;
  /*****************************************************************/
  public ExtendedRandom() {
    super();
    this.init();
  }
  /*****************************************************************/
  public ExtendedRandom(long seed) {
    super(seed);
    this.init();
  }
  /*****************************************************************/
  public void init() {
    lastNames=new ArrayList<String>();
    firstNames=new ArrayList<String>();
    try {
      File lastNamesFile= new File("data", "last.names");
      File firstNamesFile= new File("data", "first.names");
      LineNumberReader in=new LineNumberReader (new FileReader(lastNamesFile) );
      while ( in.ready() ) {
        String lastName = in.readLine();
        if ( ! lastName.startsWith("#") ) {
          lastNames.add(lastName);
        }
      }
      in=new LineNumberReader (new FileReader(firstNamesFile) );
      while ( in.ready() ) {
        String firstName = in.readLine();
        if ( ! firstName.startsWith("#") ) {
          firstNames.add(firstName);
        }
      }
    } catch (IOException e) {
      System.out.println (e.toString());
      System.exit(1);
    }
  }
  /*****************************************************************/
  public int nextInt(int lo, int hi)
  {
    int n = hi - lo + 1;
    int i = this.nextInt() % n;
    if (i < 0)
      i = -i;
    return lo + i;
  }
  /*****************************************************************/
  public String nextDate() {
    return( nextInt(1950,2006) + "-" + nextInt(1,12) + "-" + nextInt(1,12) );
  }
  /*****************************************************************/
  public String nextString (int lo, int hi)
  {
    int n = nextInt(lo, hi);
    byte b[] = new byte[n];
    for (int i = 0; i < n; i++)
      b[i] = (byte)nextInt('a', 'z');
    return new String(b, 0);
  }
  /*****************************************************************/
  public String nextString()
  {
    return nextString(5, 25);
  }
  /*****************************************************************/
  public String nextName()
  {
    int n = nextInt(5, 20);
    // first capital letter
    byte b[] = new byte[n];
    b[0] = (byte)nextInt('A', 'Z');
    for (int i = 1; i < n; i++)
            b[i] = (byte)nextInt('a', 'z');
    return new String(b, 0);
  }
  /*****************************************************************/
  public String nextLastName(){
    int i=this.nextInt( 0, lastNames.size()-1 );
    return ( lastNames.get(i) );
  }
  /*****************************************************************/
  public String nextFirstName(){
    int i=this.nextInt( 0, firstNames.size()-1 );
    return ( firstNames.get(i) );
  }
  /*****************************************************************/
  public static void main(String[] args)
  {
    ExtendedRandom r = new ExtendedRandom();
    System.out.println(r.nextLastName());
  }
}
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/src/Server.java
New file
@@ -0,0 +1,46 @@
// CDDL HEADER START
//
// The contents of this file are subject to the terms of the
// Common Development and Distribution License, Version 1.0 only
// (the "License").  You may not use this file except in compliance
// with the License.
//
// You can obtain a copy of the license at
// trunk/opends/resource/legal-notices/OpenDS.LICENSE
// or https://OpenDS.dev.java.net/OpenDS.LICENSE.
// See the License for the specific language governing permissions
// and limitations under the License.
//
// When distributing Covered Code, include this CDDL HEADER in each
// file and include the License file at
// trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
// add the following below this CDDL HEADER, with the fields enclosed
// information:
//      Portions Copyright [yyyy] [name of copyright owner]
//
// CDDL HEADER END
//
//
//      Copyright 2008 Sun Microsystems, Inc.
import java.util.*;
public class Server {
  public String host;
  public int port;
  public Server (String host, int port) {
    this.host=host;
    this.port=port;
  }
  public Server (String hostPort) {
    StringTokenizer st = new StringTokenizer(hostPort, ":");
    this.host=st.nextToken();
    this.port=Integer.parseInt(st.nextToken());
  }
  public String toString() {
    return (host + ":" + port);
  }
}
opends/tests/system-tests/scenario/4MMR/clients/addDeleteLoad/src/Worker.java
New file
@@ -0,0 +1,209 @@
// CDDL HEADER START
//
// The contents of this file are subject to the terms of the
// Common Development and Distribution License, Version 1.0 only
// (the "License").  You may not use this file except in compliance
// with the License.
//
// You can obtain a copy of the license at
// trunk/opends/resource/legal-notices/OpenDS.LICENSE
// or https://OpenDS.dev.java.net/OpenDS.LICENSE.
// See the License for the specific language governing permissions
// and limitations under the License.
//
// When distributing Covered Code, include this CDDL HEADER in each
// file and include the License file at
// trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
// add the following below this CDDL HEADER, with the fields enclosed
// information:
//      Portions Copyright [yyyy] [name of copyright owner]
//
// CDDL HEADER END
//
//
//      Copyright 2008 Sun Microsystems, Inc.
import netscape.ldap.*;
import netscape.ldap.util.*;
import java.util.*;
import java.io.*;
import java.lang.Thread;
public class Worker extends Thread {
  Server server;
  Client client;
  /*****************************************************************/
  public Worker(Client client, Server server) {
    super();
    try {
      this.server = server;
      this.client = client;
      this.start();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /*****************************************************************/
  public void run() {
    while (true) {
      client.inc_ops_started();
      LDAPEntry entry = generateAnEntry();
      this.addAnEntry(entry);
      this.deleteAnEntry(entry);
      client.inc_ops_done();
    }
  }
  /*****************************************************************/
  public LDAPEntry generateAnEntry() {
    try {
      // Build random strings
      Random rand = new Random();
      int n = 1000000;
      int i = rand.nextInt( n + 1 );
      ExtendedRandom extendedRandom = new ExtendedRandom();
      String sn = extendedRandom.nextLastName();
      String cn = extendedRandom.nextFirstName();
      String uid = sn.substring(0,1) + cn.substring(0,1) + "_" + i;
      // Create entry attributes set
      LDAPAttributeSet attrSet = new LDAPAttributeSet();
      attrSet.add(new LDAPAttribute("objectClass", "top"));
      attrSet.add(new LDAPAttribute("objectClass", "person"));
      attrSet.add(new LDAPAttribute("objectClass", "organizationalperson"));
      attrSet.add(new LDAPAttribute("objectClass", "inetorgperson"));
      attrSet.add(new LDAPAttribute("uid", uid));
      attrSet.add(new LDAPAttribute("sn", sn));
      attrSet.add(new LDAPAttribute("cn", cn));
      attrSet.add(new LDAPAttribute("givenName", sn + " " + cn));
      attrSet.add(new LDAPAttribute("mail", uid + "@sun.com"));
      // Create the entry
      LDAPEntry entry = new LDAPEntry( "uid=" + uid + "," + client.suffix,
                                        attrSet);
      // TBD a fixer return pas global a la function
      return entry;
    }
    catch( Exception e ) {
      println( "ERROR" , e.toString() );
    }
    return null;
  }
  /*****************************************************************/
  public void addAnEntry(LDAPEntry entry) {
    try {
      //************************************
      // LDAP CONNECTION
      LDAPConnection connection = new LDAPConnection();
      connection.connect( server.host, server.port);
      // bind if needed
      if ( client.bindDN == null ) {
        println ("INFO", "Binding as anonymous");
      }
      else {
        connection.bind(client.bindDN, client.bindPW);
      }
      //************************************
      // ADD LDAP ENTRY
      try {
        connection.add(entry);
        // println("INFO","Add entry " + entry.getDN());
      } catch (LDAPException e) {
        int errorCode = e.getLDAPResultCode();
        if ( errorCode == 50 ) {
          println ("ERROR", "Insufficent access, errcode : "+ errorCode + ")");
        }
        else if ( errorCode == 68 ) {
          println ("ERROR", "Entry already exists, errcode "+ errorCode + ")");
        }
        else {
          println ("ERROR", "LDAP Returns error code " + errorCode);
        }
      }
      //************************************
      // CLOSE LDAP CONNECTION
      connection.disconnect();
    }
    catch( LDAPException e ) {
      println( "ERROR" , e.toString() );
    }
  }
  /*****************************************************************/
  public void deleteAnEntry(LDAPEntry entry) {
    try {
      //************************************
      // LDAP CONNECTION
      LDAPConnection connection = new LDAPConnection();
      connection.connect(server.host, server.port);
      // bind if needed
      if ( client.bindDN == null ) {
        println ("INFO", "Binding as anonymous");
      }
      else {
        connection.bind(client.bindDN, client.bindPW);
      }
      //************************************
      // LDAP CONNECTION
      try {
        connection.delete(entry.getDN());
        // println("INFO","Delete entry " + entry.getDN());
      } catch (LDAPException e) {
        int errorCode = e.getLDAPResultCode();
        if ( errorCode == 50 ) {
          println ("ERROR", "Insufficent access, errcode : "+ errorCode + ")");
        }
        else if ( errorCode == 68 ) {
          println ("ERROR", "Entry already exists, errcode "+ errorCode + ")");
        }
        else {
          println ("ERROR", "LDAP Returns error code " + errorCode);
        }
      }
      //************************************
      // CLOSE LDAP CONNECTION
      connection.disconnect();
    }
    catch( LDAPException e ) {
      println( "ERROR" , e.toString() );
    }
  }
  /*****************************************************************/
  private String getDate() {
    // Initialize the today's date string
    String DATE_FORMAT = "yyyy/MM/dd:HH:mm:ss";
    java.text.SimpleDateFormat sdf =
        new java.text.SimpleDateFormat(DATE_FORMAT);
    Calendar c1 = Calendar.getInstance(); // today
    return("[" + sdf.format(c1.getTime()) + "]");
  }
  /*****************************************************************/
  private void println(String level, String msg) {
      System.out.println (getDate() + " - " + level + ": (" + server + ") "
                          + msg );
  }
}
opends/tests/system-tests/scenario/4MMR/conf.xml
New file
@@ -0,0 +1,232 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE systemTestConfiguration SYSTEM "../conf.dtd">
<!--
 ! CDDL HEADER START
 !
 ! The contents of this file are subject to the terms of the
 ! Common Development and Distribution License, Version 1.0 only
 ! (the "License").  You may not use this file except in compliance
 ! with the License.
 !
 ! You can obtain a copy of the license at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
 ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 ! See the License for the specific language governing permissions
 ! and limitations under the License.
 !
 ! When distributing Covered Code, include this CDDL HEADER in each
 ! file and include the License file at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 ! add the following below this CDDL HEADER, with the fields enclosed
 ! by brackets "[]" replaced with your own identifying information:
 !      Portions Copyright [yyyy] [name of copyright owner]
 !
 ! CDDL HEADER END
 !
 !      Copyright 2008 Sun Microsystems, Inc.
 ! -->
<!--==================================================================-->
<!-- This conf.xml file is an example                                 -->
<!-- BEFORE running system-tests, you need to set up your environment -->
<!--==================================================================-->
<systemTestConfiguration>
  <!-- ================= Global Parameters ===================== -->
  <!-- =============  Should be the first node   =============== -->
  <globalParameters>
    <scenario>
      <name>4MMR</name>
      <description>
        4 Ldap Servers each connected to a single changelog server
      </description>
    </scenario>
    <opendsZip>NEED_VALUE</opendsZip>
    <!-- Example : <domain>france.sun.com</domain> -->
    <domain></domain>
  </globalParameters>
  <!-- ================= Instance ============================== -->
  <instance name="I1" product="opends" role="ldapServer">
    <host>localhost</host>
    <installDir>NEED_VALUE</installDir>
    <ports>
      <ldap>5021</ldap>
      <ldaps>5022</ldaps>
      <jmx>5023</jmx>
      <replicationServer>5025</replicationServer>
    </ports>
    <tuning>
      <java xms="2g" xmx="2g"
            xxNewSize="512m" xxMaxNewSize="512m"
            xxSurvivorRatio="6" xxPermSize="128m"
            xxMaxPermSize="128m" xxUseConcMarkSweepGC="true"/>
      <databaseCachePercentage>40</databaseCachePercentage>
      <replicationPurgeDelay unit="h">4</replicationPurgeDelay>
    </tuning>
  </instance>
  <!-- ================= Instance ============================== -->
  <instance name="I2" product="opends" role="ldapServer">
    <host>localhost</host>
    <installDir>NEED_VALUE</installDir>
    <ports>
      <ldap>6021</ldap>
      <ldaps>6022</ldaps>
      <jmx>6023</jmx>
      <replicationServer>6025</replicationServer>
    </ports>
    <tuning>
      <java xms="2g" xmx="2g"
            xxNewSize="512m" xxMaxNewSize="512m"
            xxSurvivorRatio="6" xxPermSize="128m"
            xxMaxPermSize="128m" xxUseConcMarkSweepGC="true"/>
      <databaseCachePercentage>40</databaseCachePercentage>
      <replicationPurgeDelay unit="h">4</replicationPurgeDelay>
    </tuning>
  </instance>
  <!-- ================= Instance ============================== -->
  <instance name="I3" product="opends" role="ldapServer">
    <host>localhost</host>
    <installDir>NEED_VALUE</installDir>
    <ports>
      <ldap>7021</ldap>
      <ldaps>7022</ldaps>
      <jmx>7023</jmx>
      <replicationServer>7025</replicationServer>
    </ports>
    <tuning>
      <java xms="2g" xmx="2g"
            xxNewSize="512m" xxMaxNewSize="512m"
            xxSurvivorRatio="6" xxPermSize="128m"
            xxMaxPermSize="128m" xxUseConcMarkSweepGC="true"/>
      <databaseCachePercentage>40</databaseCachePercentage>
      <replicationPurgeDelay unit="h">4</replicationPurgeDelay>
    </tuning>
  </instance>
  <!-- ================= Instance ============================== -->
  <instance name="I4" product="opends" role="ldapServer">
    <host>localhost</host>
    <installDir>NEED_VALUE</installDir>
    <ports>
      <ldap>8021</ldap>
      <ldaps>8022</ldaps>
      <jmx>8023</jmx>
      <replicationServer>8025</replicationServer>
    </ports>
    <tuning>
      <java xms="2g" xmx="2g"
            xxNewSize="512m" xxMaxNewSize="512m"
            xxSurvivorRatio="6" xxPermSize="128m"
            xxMaxPermSize="128m" xxUseConcMarkSweepGC="true"/>
      <databaseCachePercentage>40</databaseCachePercentage>
      <replicationPurgeDelay unit="h">4</replicationPurgeDelay>
    </tuning>
  </instance>
  <!-- ================= Suffix  ============================== -->
  <suffix dn="dc=com">
    <topology>
        <element instanceName="I1" initRule="importLdif"/>
      <element instanceName="I2" initRule="totalUpdate"
               instanceSourceName="I1"/>
      <element instanceName="I3" initRule="totalUpdate"
               instanceSourceName="I1"/>
      <element instanceName="I4" initRule="totalUpdate"
               instanceSourceName="I1"/>
    </topology>
    <tree nbOfEntries="200">
      <branch name="ou=france,dc=com">
        <branch name="ou=QA Engineers,ou=france,dc=com">
          <subordinateTemplate type="inetOrgPerson" percentage="30"/>
        </branch>
        <branch name="ou=Accounting,ou=france,dc=com">
          <subordinateTemplate type="organizationalPerson" percentage="30"/>
        </branch>
        <branch name="ou=Managers,ou=france,dc=com">
          <subordinateTemplate type="person" nb="1"/>
        </branch>
        <branch name="ou=Engineers,ou=france,dc=com">
          <subordinateTemplate type="person" percentage="40"/>
        </branch>
      </branch>
    </tree>
  </suffix>
  <!-- ================= Scheduler  =========================== -->
  <!-- [1] duration must be more than 1 minute                  -->
  <!-- [2] dependencyId is a list of client id ie : 1,2         -->
  <!--     if using it, specify id attribute for each clients   -->
  <scheduler>
    <duration unit="h">4</duration>
    <!-- 60h : 1% <-> 36 min , 10% <-> 6h -->
    <!-- ============================================================= -->
    <!--== Module 1 ==-->
    <module name="search" enabled="true">
      <client id="1" name="searchLoad" host="localhost" start="t0" stop="t10">
        <serverInstance>I1</serverInstance>
        <baseDn>dc=com</baseDn>
        <nbCnx>20</nbCnx>
        <nbMaxOperations>20</nbMaxOperations>
        <attribute>sn</attribute>
      </client>
    </module>
    <!--== Module 2 ==-->
    <module name="modify" enabled="true">
      <client id="3" name="modifyLoad" host="localhost" start="t20" stop="t50">
        <serverInstance>I1</serverInstance>
        <baseDn>dc=com</baseDn>
        <nbCnx>20</nbCnx>
        <nbMaxOperations>20</nbMaxOperations>
        <attribute>sn</attribute>
      </client>
      <client id="4" name="searchLoad" host="localhost" start="t20" stop="t50">
        <serverInstance>I4</serverInstance>
        <baseDn>dc=com</baseDn>
        <nbCnx>20</nbCnx>
        <nbMaxOperations>20</nbMaxOperations>
        <attribute>sn</attribute>
      </client>
    </module>
    <!--== Module 3 ==-->
    <module name="addAndDelete" enabled="true">
      <client id="6" name="addDeleteLoad" host="localhost" start="t60"
                                                           stop="t80">
        <serverInstance>I2</serverInstance>
        <baseDn>dc=com</baseDn>
        <nbCnx>20</nbCnx>
      </client>
      <client id="7" name="restartDs" host="localhost" start="t70"
                                                       dependencyId="6">
        <serverInstance>I3</serverInstance>
      </client>
    </module>
  </scheduler>
</systemTestConfiguration>