/**
* Copyright 2012 Akiban Technologies, Inc.
*
* 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 com.persistit;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
import com.persistit.stress.AbstractSuite;
import com.persistit.stress.AccumulatorRestartSuite;
import com.persistit.stress.InsertBigLoad;
import com.persistit.stress.InsertUUIDs;
import com.persistit.stress.Mixture1;
import com.persistit.stress.Mixture2;
import com.persistit.stress.Mixture3;
import com.persistit.stress.MixtureTxn1;
import com.persistit.stress.MixtureTxn2;
import com.persistit.stress.PersistitMap1;
import com.persistit.stress.PreloadMixtureTxn1;
import com.persistit.stress.StartStop;
import com.persistit.stress.Stress10Suite;
import com.persistit.stress.Stress12txnSuite;
import com.persistit.stress.Stress4Suite;
import com.persistit.stress.Stress8txnSuite;
import com.persistit.util.ArgParser;
/**
* Runs the stress test suites defined in the _classes list below. Arguments:
*
* <dl>
* <dt>tests=testname,test*pattern</dt>
* <dd>Comma-separated list of test class names; allows "*" and "?" as wildcards
* </dd>
* <dt>duration=nnn</dt>
* <dd>Duration of the entire run, in seconds. This number is divided by the
* number of classes to determine the duration of each suite</dd>
* <dt>datapath=/xxx/yyy/zzz</dt>
* <dd>Directory path (no trailing '/') where Persistit will write journal and
* volume files.</dd>
* <dt>report=/xxx/yyy/zzz/reportname</dt>
* <dd>Path to file in which summary report will be written</dd>
* </dl>
*
* @author peter
*
*/
public class StressRunner {
private final static String[] ARGS_TEMPLATE = {
"duration|int::10|Maximum duration in seconds",
"report|String:StressRunner_" + String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", System.currentTimeMillis()),
"tests|String:*|List of comma-separated patterns" };
private static List<Class<? extends AbstractSuite>> _classes = new ArrayList<Class<? extends AbstractSuite>>();
static {
_classes.add(AccumulatorRestartSuite.class);
_classes.add(InsertUUIDs.class);
_classes.add(InsertBigLoad.class);
_classes.add(Mixture1.class);
_classes.add(Mixture2.class);
_classes.add(Mixture3.class);
_classes.add(MixtureTxn1.class);
_classes.add(MixtureTxn2.class);
_classes.add(PersistitMap1.class);
_classes.add(StartStop.class);
_classes.add(Stress10Suite.class);
_classes.add(Stress12txnSuite.class);
_classes.add(Stress4Suite.class);
_classes.add(Stress8txnSuite.class);
_classes.add(PreloadMixtureTxn1.class);
}
private final static String DURATION_PARAM = "duration=";
public static void main(final String[] args) throws Exception {
final ArgParser ap = new ArgParser(StressRunner.class.getSimpleName(), args, ARGS_TEMPLATE);
final List<Class<? extends AbstractSuite>> classes = new ArrayList<Class<? extends AbstractSuite>>();
for (final String s : ap.getStringValue("tests").split(",")) {
final String regex = s.replace("*", ".*").replace("?", ".");
final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
for (final Class<? extends AbstractSuite> cl : _classes) {
if (pattern.matcher(cl.getSimpleName()).matches()) {
classes.add(cl);
}
}
}
if (classes.isEmpty()) {
System.out.println("No tests specified: " + ap.getStringValue("tests"));
System.exit(1);
}
final int duration = ap.getIntValue("duration") / classes.size();
final PrintWriter pw = new PrintWriter(new FileWriter(ap.getStringValue("report")));
int failed = 0;
for (final Class<? extends AbstractSuite> clazz : classes) {
final List<String> suiteArgs = ap.getUnparsedList();
if (ap.isSpecified("duration")) {
suiteArgs.add(DURATION_PARAM + duration);
}
final AbstractSuite suite = clazz.getConstructor(args.getClass()).newInstance(
new Object[] { suiteArgs.toArray(new String[suiteArgs.size()]) });
System.out.printf("\nStart %s at %s\n--------------------------------------------------------\n",
suite.getName(), now());
suite.runTest();
System.out.printf("\n--------------------------------------------------------\n End %s at %s\n",
suite.getName(), now());
pw.printf("%s,%s,%d\n", suite.getName(), suite.isFailed() ? "FAILED" : "PASSED", suite.getRate());
pw.flush();
if (suite.isFailed()) {
failed++;
}
}
pw.close();
// If there were errors, leave a non-zero status code for framework
if (failed > 0) {
System.exit(1);
}
}
private static String now() {
return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
}
}