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.
** PerformanceRunner.java
* Adding a timer thread for the max duration feature and add warm-up implementation.
** AddRate.java SearchRate.java
* Adding resetStats method to reset local statistics (i.e extra columns)
** tools.properties
* Adding warm-up message
** AuthRateITCase.java
** Adding a test with warm-up phase
| | |
| | | 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 |
| | |
| | | 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; |
| | |
| | | protected double recentDuration; |
| | | protected double averageDuration; |
| | | |
| | | public StatsThread(final String[] additionalColumns) { |
| | | public StatsThread(final String... additionalColumns) { |
| | | super("Stats Thread"); |
| | | |
| | | this.additionalColumns = additionalColumns; |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | }; |
| | | |
| | | 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; |
| | |
| | | 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(); |
| | |
| | | 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, |
| | |
| | | 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(); |
| | | |
| | |
| | | |
| | | Connection connection = null; |
| | | try { |
| | | isWarmingUp = warmUpDuration > 0; |
| | | for (int i = 0; i < numConnections; i++) { |
| | | if (keepConnectionsOpen.isPresent() || noRebindArgument.isPresent()) { |
| | | connection = connectionFactory.getConnectionAsync(null).get(); |
| | |
| | | } |
| | | } |
| | | |
| | | 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) { |
| | |
| | | } |
| | | |
| | | 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 |
| | |
| | | (%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 |
| | | # |
| | |
| | | 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; |
| | | |
| | |
| | | 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") |
| | |
| | | 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 |