package com.bazaarvoice.ostrich.perftest.utils; import com.google.common.base.Strings; import org.apache.commons.cli.BasicParser; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import java.io.File; import java.io.PrintStream; import static com.bazaarvoice.ostrich.pool.ServiceCachingPolicy.ExhaustionAction; /** * This class parses and holds onto the parsed variable. * It also handles bad arguments appropriately, and prints message to help rectify them. */ @SuppressWarnings ("deprecation") public class Arguments { private int _threadSize = 100; private int _workSize = 1024 * 5; private long _runTimeSecond = Long.MAX_VALUE; private int _maxInstance = 10; private int _idleTimeSecond = 10; private boolean _runSingletonMode = false; private ExhaustionAction _exhaustionAction = ExhaustionAction.WAIT; private int _reportingIntervalSeconds = 1; private PrintStream _output = System.out; private boolean _printStats = false; private int _chaosWorkers = 2; private int _chaosInterval = 15; public Arguments(String[] args) { parseArgs(args); } public int getThreadSize() { return _threadSize; } public int getWorkSize() { return _workSize; } public long getRunTimeSecond() { return _runTimeSecond; } public int getMaxInstance() { return _maxInstance; } public int getIdleTimeSecond() { return _idleTimeSecond; } public ExhaustionAction getExhaustionAction() { return _exhaustionAction; } public PrintStream getOutput() { return _output; } public boolean doPrintStats() { return _printStats; } public int getReportingIntervalSeconds() { return _reportingIntervalSeconds; } public boolean isRunSingletonMode() { return _runSingletonMode; } public int getChaosWorkers() { return _chaosWorkers; } public int getChaosInterval() { return _chaosInterval; } private void parseArgs(String[] args) { Options options = new Options(); options.addOption("h", "help", false, "Show this help message!"); options.addOption("t", "thread-size", true, "# of workers threads to run, default is 100"); options.addOption("w", "work-size", true, "length of the string to generate randomly and crunch hash, default is 1024 X 5 (5kb)"); options.addOption("r", "run-time", true, "seconds to run before it kills worker running threads, default is 9223372036854775807 (Long.MAX_VALUE)"); options.addOption("m", "max-instances", true, "Max instances per end point in service cache, default is 10"); options.addOption("i", "idle-time", true, "Idle time before service cache should take evict action, default is 10"); options.addOption("e", "exhaust-action", true, "Exhaust action when cache is exhausted, acceptable values are WAIT|FAIL|GROW, default is WAIT"); options.addOption("g", "singleton-mode", false, "Run with singleton policy mode, default is false"); options.addOption("c", "chaos-count", true, "Number of chaos workers to use, default is 2"); options.addOption("l", "chaos-interval", true, "time (in seconds) to wait between chaos, default is 15"); options.addOption("o", "output-file", true, "Output file to use instead of STDOUT"); options.addOption("v", "report-every", true, "Reports the running statistics every # seconds"); options.addOption("s", "statistics", false, "Output current running stats on STDOUT, ignored if --output-file is not provided"); String opt = null; String longOpt = null; String value = null; try { CommandLineParser commandLineParser = new BasicParser(); CommandLine commandLine = commandLineParser.parse(options, args); if (commandLine.hasOption("h")) { help(options); } for (Option option : commandLine.getOptions()) { opt = option.getOpt(); longOpt = option.getLongOpt(); value = option.getValue(); switch (opt) { case "t": _threadSize = Integer.parseInt(value); break; case "w": _workSize = Integer.parseInt(value); break; case "r": _runTimeSecond = Long.parseLong(value); break; case "m": _maxInstance = Integer.parseInt(value); break; case "i": _idleTimeSecond = Integer.parseInt(value); break; case "e": _exhaustionAction = ExhaustionAction.valueOf(value); break; case "o": _output = createPrintStream(value); break; case "g": _runSingletonMode = true; break; case "s": _printStats = true; break; case "v": _reportingIntervalSeconds = Integer.parseInt(value); break; case "c": _chaosWorkers = Integer.parseInt(value); break; case "l": _chaosInterval = Integer.parseInt(value); break; } } if (_output == System.out && _printStats) { throw new Exception("Cannot print both report log and statistics to STDOUT at the same time"); } } catch (IllegalArgumentException ex) { printError(opt, longOpt, value); help(options); } catch (Exception ex) { printError(ex, opt, longOpt, value); help(options); } } private void help(Options options) { HelpFormatter helpFormatter = new HelpFormatter(); helpFormatter.printHelp("Ostrich Performance Test Suite", options); System.exit(0); } private void printError(String opt, String longOpt, String value) { if (!Strings.isNullOrEmpty(opt) && !Strings.isNullOrEmpty(value)) { System.err.println(String.format("\"%s\" is not valid value for -%s / --%s", value, opt, longOpt)); } } private void printError(Exception ex, String opt, String longOpt, String value) { System.err.println(ex.getMessage()); printError(opt, longOpt, value); } private PrintStream createPrintStream(String filePath) throws Exception { File file = new File(filePath); if (!file.createNewFile()) { throw new Exception("Cannot create file: " + filePath); } return new PrintStream(file); } }