com.blazemeter.taurus.junit.CustomRunner Maven / Gradle / Ivy
package com.blazemeter.taurus.junit;
import com.blazemeter.taurus.junit.exception.CustomRunnerException;
import com.blazemeter.taurus.junit.generator.Supervisor;
import junit.framework.TestCase;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CustomRunner {
private static final Logger log = Logger.getLogger(CustomRunner.class.getName());
public static final String REPORT_FILE = "report_file";
public static final String TARGET_PREFIX = "target_";
public static final String ITERATIONS = "iterations";
public static final String HOLD = "hold_for";
public static final String CONCURRENCY = "concurrency";
public static final String STEPS = "steps";
public static final String RAMP_UP = "ramp_up";
public static final String INCLUDE_CATEGORY = "include_category";
public static final String EXCLUDE_CATEGORY = "exclude_category";
public static final String RUN_ITEMS = "run_items";
public static final String JUNIT_VERSION = "junit_version";
static {
log.setLevel(Level.FINER);
}
public static void main(String[] args) throws Exception {
log.info("Starting: " + Arrays.toString(args));
if (args.length != 1) {
throw new IllegalArgumentException("Usage requires 1 parameter, containing path to properties file");
}
Properties props = new Properties();
props.load(new FileReader(args[0]));
ArrayList classes = getClasses(props);
if (classes.isEmpty()) {
throw new CustomRunnerException("Nothing to test");
}
log.info("Running with classes: " + classes.toString());
passToSystemProperties(props);
Supervisor supervisor = new Supervisor(classes, props);
supervisor.execute();
}
protected static void passToSystemProperties(Properties props) {
Enumeration> it = props.propertyNames();
while (it.hasMoreElements()) {
String propName = (String) it.nextElement();
if (!isCustomRunnerProperty(propName)) {
System.setProperty(propName, props.getProperty(propName));
}
}
}
protected static boolean isCustomRunnerProperty(String propName) {
return REPORT_FILE.equals(propName)
|| ITERATIONS.equals(propName)
|| HOLD.equals(propName)
|| INCLUDE_CATEGORY.equals(propName)
|| EXCLUDE_CATEGORY.equals(propName)
|| RUN_ITEMS.equals(propName)
|| JUNIT_VERSION.equals(propName)
|| CONCURRENCY.equals(propName)
|| RAMP_UP.equals(propName)
|| STEPS.equals(propName)
|| propName.startsWith(TARGET_PREFIX);
}
protected static ArrayList getClasses(Properties props) {
ArrayList result = new ArrayList<>(0);
Enumeration> it = props.propertyNames();
while (it.hasMoreElements()) {
String propName = (String) it.nextElement();
if (propName.startsWith(TARGET_PREFIX)) {
result.addAll(getClasses(props.getProperty(propName)));
}
}
return result;
}
protected static List> getClasses(String jar_path) {
List> test_classes = new ArrayList<>(); //List of loaded classes
try {
processJAR(test_classes, jar_path);
} catch (IOException | ReflectiveOperationException e) {
log.warning("Failed to add " + jar_path + "\n" + Utils.getStackTrace(e));
}
return test_classes;
}
protected static void processJAR(List> test_classes, String jar_path) throws IOException, ReflectiveOperationException {
log.info("Processing JAR: " + jar_path);
JarFile jarFile = new JarFile(jar_path);
Enumeration jar_entries_enum = jarFile.entries();
URL url = new URL("file:" + jar_path);
addURL(url);
URLClassLoader cl = URLClassLoader.newInstance(new URL[] {url});
while (jar_entries_enum.hasMoreElements()) {
JarEntry jar_entry = jar_entries_enum.nextElement();
if (jar_entry.isDirectory() || !jar_entry.getName().endsWith(".class")) {
continue;
}
String className = jar_entry.getName().substring(0, jar_entry.getName().length() - ".class".length());
className = className.replace('/', '.');
Class> c = cl.loadClass(className);
log.info("TestCase.class.isAssignableFrom(" + c.getCanonicalName() + ") = " + TestCase.class.isAssignableFrom(c));
log.info("has_annotations(" + c.getCanonicalName() + ") = " + has_annotations(c));
if (Modifier.isAbstract(c.getModifiers())) {
log.info("Skip because of abstract");
continue;
}
if (TestCase.class.isAssignableFrom(c) || has_annotations(c)) {
test_classes.add(c);
log.info("class added to tests: " + c.getCanonicalName());
}
}
jarFile.close();
}
private static void addURL(URL url) throws ReflectiveOperationException {
URLClassLoader systemClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(systemClassLoader, url);
}
protected static boolean has_annotations(Class> c) {
for (Method method : c.getMethods()) {
if (method.isAnnotationPresent(org.junit.Test.class)) {
return true;
}
}
return false;
}
}