From e326f68b0332a5e6963e63663828b0276db1d3c9 Mon Sep 17 00:00:00 2001
From: Gaetan Boismal <gaetan.boismal@forgerock.com>
Date: Fri, 25 Jul 2014 14:21:59 +0000
Subject: [PATCH] OPENDJ-1023 OPENDJ-1024 (CR-4092) Provide duration and warm-up parameters to the xxxrate tools Adding two new parameters to the xxxrate tools, maximum duration time and warm-up duration time.

---
 opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java |   68 +++++++++++++++++++++++++++++++++-
 opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AuthRateITCase.java    |   23 ++++++++---
 opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AddRate.java           |   11 ++++-
 opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java        |   11 ++++-
 opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools.properties  |    1 
 5 files changed, 101 insertions(+), 13 deletions(-)

diff --git a/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AddRate.java b/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AddRate.java
index b7ea17c..9b29b04 100644
--- a/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AddRate.java
+++ b/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AddRate.java
@@ -117,7 +117,14 @@
             private final String[] extraColumn = new String[1];
 
             private AddRateStatsThread() {
-                super(new String[] { "Add%" });
+                super("Add%");
+            }
+
+            @Override
+            void resetStats() {
+                super.resetStats();
+                nbAdd.set(0);
+                nbDelete.set(0);
             }
 
             @Override
@@ -176,7 +183,7 @@
                 case SIZE_THRESHOLD:
                     return dnEntriesAdded.size() > sizeThreshold;
                 case AGE_THRESHOLD:
-                    long olderEntryTimestamp = (Long) dnEntriesAdded.firstKey();
+                    long olderEntryTimestamp = dnEntriesAdded.firstKey();
                     return (olderEntryTimestamp + timeToWait) < currentTime;
                 default:
                     return false;
diff --git a/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java b/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java
index 8398959..155552a 100644
--- a/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java
+++ b/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java
@@ -89,7 +89,7 @@
         protected double recentDuration;
         protected double averageDuration;
 
-        public StatsThread(final String[] additionalColumns) {
+        public StatsThread(final String... additionalColumns) {
             super("Stats Thread");
 
             this.additionalColumns = additionalColumns;
@@ -326,6 +326,35 @@
         String[] getAdditionalColumns() {
             return EMPTY_STRINGS;
         }
+
+        void resetStats() {
+            failedCount = 0;
+            operationCount = 0;
+            successCount = 0;
+            operationRecentCount.set(0);
+            successRecentCount.set(0);
+            failedRecentCount.set(0);
+            waitRecentTime.set(0);
+        }
+    }
+
+    private class TimerThread extends Thread {
+        private long timeToWait;
+
+        public TimerThread(long timeToWait) {
+            this.timeToWait = timeToWait;
+        }
+
+        @Override
+        public void run() {
+            try {
+                Thread.sleep(timeToWait);
+            } catch (InterruptedException e) {
+                throw new IllegalStateException(e);
+            } finally {
+                stopRequested = true;
+            }
+        }
     }
 
     /**
@@ -619,15 +648,21 @@
     };
 
     private volatile boolean stopRequested;
+    private volatile boolean isWarmingUp;
     private int numThreads;
     private int numConnections;
     private int targetThroughput;
     private int maxIterations;
+    /** Warm-up duration time in ms. **/
+    private long warmUpDuration;
+    /** Max duration time in ms, 0 for unlimited. **/
+    private long maxDurationTime;
     private boolean isAsync;
     private boolean noRebind;
     private int statsInterval;
     private final IntegerArgument numThreadsArgument;
     private final IntegerArgument maxIterationsArgument;
+    private final IntegerArgument maxDurationArgument;
     private final IntegerArgument statsIntervalArgument;
     private final IntegerArgument targetThroughputArgument;
     private final IntegerArgument numConnectionsArgument;
@@ -636,6 +671,7 @@
     private final BooleanArgument noRebindArgument;
     private final BooleanArgument asyncArgument;
     private final StringArgument arguments;
+    protected final IntegerArgument warmUpArgument;
 
     PerformanceRunner(final PerformanceRunnerOptions options) throws ArgumentException {
         ArgumentParser argParser = options.getArgumentParser();
@@ -666,6 +702,18 @@
         maxIterationsArgument.setPropertyName("maxIterations");
         argParser.addArgument(maxIterationsArgument);
 
+        maxDurationArgument =
+            new IntegerArgument("maxDuration", 'd', "maxDuration", false, false, true,
+                LocalizableMessage.raw("{maxDuration}"), 0, null, true, 1, false, 0,
+                LocalizableMessage.raw("Maximum duration in seconds, 0 for unlimited"));
+        argParser.addArgument(maxDurationArgument);
+
+        warmUpArgument =
+            new IntegerArgument("warmUpDuration", 'B', "warmUpDuration", false, false, true,
+                LocalizableMessage.raw("{warmUpDuration}"), 0, null,
+                LocalizableMessage.raw("Warm up duration in seconds"));
+        argParser.addArgument(warmUpArgument);
+
         statsIntervalArgument =
                 new IntegerArgument("statInterval", 'i', "statInterval", false, false, true,
                         LocalizableMessage.raw("{statInterval}"), 5, null, true, 1, false, 0,
@@ -762,7 +810,9 @@
     public final void validate() throws ArgumentException {
         numConnections = numConnectionsArgument.getIntValue();
         numThreads = numThreadsArgument.getIntValue();
+        warmUpDuration = warmUpArgument.getIntValue() * 1000L;
         maxIterations = maxIterationsArgument.getIntValue() / numConnections / numThreads;
+        maxDurationTime = maxDurationArgument.getIntValue() * 1000L;
         statsInterval = statsIntervalArgument.getIntValue() * 1000;
         targetThroughput = targetThroughputArgument.getIntValue();
 
@@ -807,6 +857,7 @@
 
         Connection connection = null;
         try {
+            isWarmingUp = warmUpDuration > 0;
             for (int i = 0; i < numConnections; i++) {
                 if (keepConnectionsOpen.isPresent() || noRebindArgument.isPresent()) {
                     connection = connectionFactory.getConnectionAsync(null).get();
@@ -820,7 +871,20 @@
                 }
             }
 
-            final Thread statsThread = newStatsThread();
+            if (maxDurationTime > 0) {
+                new TimerThread(maxDurationTime).start();
+            }
+
+            final StatsThread statsThread = newStatsThread();
+
+            if (isWarmingUp) {
+                if (!app.isScriptFriendly()) {
+                    app.println(INFO_TOOL_WARMING_UP.get(warmUpDuration / 1000));
+                }
+                Thread.sleep(warmUpDuration);
+                statsThread.resetStats();
+                isWarmingUp = false;
+            }
             statsThread.start();
 
             for (final Thread t : threads) {
diff --git a/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java b/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java
index 8318c0c..0027c12 100644
--- a/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java
+++ b/opendj-sdk/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java
@@ -83,11 +83,16 @@
         }
 
         private final class SearchStatsThread extends StatsThread {
-            private final String[] extraColumn;
+            private final String[] extraColumn = new String[1];
 
             private SearchStatsThread() {
-                super(new String[] { "Entries/Srch" });
-                extraColumn = new String[1];
+                super("Entries/Srch");
+            }
+
+            @Override
+            void resetStats() {
+                super.resetStats();
+                entryRecentCount.set(0);
             }
 
             @Override
diff --git a/opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools.properties b/opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools.properties
index 41bcb5a..4b70dfd 100755
--- a/opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools.properties
+++ b/opendj-sdk/opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools.properties
@@ -488,6 +488,7 @@
  (%s per %s)
 ERR_TOOL_ARG_NEEDED_WHEN_USING_ARG=%s must be used when using %s
 ERR_TOOL_ARG_MUST_BE_USED_WHEN_ARG_CONDITION=%s must be used if %s is %s
+INFO_TOOL_WARMING_UP=Warming up for %d seconds...
  #
  # MakeLDIF tool
  #
diff --git a/opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AuthRateITCase.java b/opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AuthRateITCase.java
index af2cf50..4fa5dbe 100644
--- a/opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AuthRateITCase.java
+++ b/opendj-sdk/opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AuthRateITCase.java
@@ -26,6 +26,7 @@
 package com.forgerock.opendj.ldap.tools;
 
 import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_ERROR_PARSING_ARGS;
+import static com.forgerock.opendj.ldap.tools.ToolsMessages.INFO_TOOL_WARMING_UP;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.forgerock.util.Utils.closeSilently;
 
@@ -44,12 +45,22 @@
     public Object[][] authRateArgs() throws Exception {
         return new Object[][] {
             { args(""), "", ERR_ERROR_PARSING_ARGS.get("") },
-            // Simple test
+            // Warm-up test case
             {
-                args("-h", TestCaseUtils.getServerSocketAddress().getHostName(), "-p",
-                    Integer.toString(TestCaseUtils.getServerSocketAddress().getPort()), "-g", "rand(0,1000)", "-D",
-                    "uid=%d,ou=people,o=test", "-w", "password", "-i", "1", "-c", "1", "-m", "10", "-f", "-S"),
-                THROUGHPUT_TEXT, "" }, };
+                args("-h", TestCaseUtils.getServerSocketAddress().getHostName(),
+                     "-p", Integer.toString(TestCaseUtils.getServerSocketAddress().getPort()),
+                     "-g", "rand(0,1000)", "-D", "uid=%d,ou=people,o=test", "-w", "password",
+                     "-i", "1", "-m", "10", "-f", "-B", "1"),
+                INFO_TOOL_WARMING_UP.get(1), "" },
+
+            // Correct test case
+            {
+                args("-h", TestCaseUtils.getServerSocketAddress().getHostName(),
+                     "-p", Integer.toString(TestCaseUtils.getServerSocketAddress().getPort()),
+                     "-g", "rand(0,1000)", "-D", "uid=%d,ou=people,o=test", "-w", "password",
+                     "-i", "1", "-c", "1", "-m", "10", "-f", "-S", "-B", "0"),
+                THROUGHPUT_TEXT, "" },
+        };
     }
 
     @Test(dataProvider = "authRateArgs")
@@ -67,7 +78,7 @@
             checkOuputStreams(out, err, expectedOut, expectedErr);
             String outContent = out.toString();
 
-            if (outContent.contains(THROUGHPUT_TEXT)) {
+            if (expectedOut.toString().contains(THROUGHPUT_TEXT)) {
                 // Check that there was no error in search
                 String[] authRateResLines = outContent.split(System.getProperty("line.separator"));
                 //Skip header line

--
Gitblit v1.10.0