All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.blazemeter.taurus.junit.CustomRunner Maven / Gradle / Ivy

package com.blazemeter.taurus.junit;

import com.blazemeter.taurus.junit4.JUnit4Runner;
import com.blazemeter.taurus.junit5.JUnit5Runner;
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 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 RuntimeException("Nothing to test");
        }
        log.info("Running with classes: " + classes.toString());

        passToSystemProperties(props);

        JUnitRunner runner = getJUnitRunner(props.getProperty(JUNIT_VERSION));

        Object request = runner.createRequest(classes, props);
        TaurusReporter reporter = new TaurusReporter(props.getProperty(REPORT_FILE));

        long iterations = Long.valueOf(props.getProperty(ITERATIONS, "0"));
        float hold = Float.valueOf(props.getProperty(HOLD, "0"));
        if (iterations == 0) {
            if (hold > 0) {
                iterations = Long.MAX_VALUE;
            } else {
                iterations = 1;
            }
        }

        long startTime = System.currentTimeMillis();
        for (int iteration = 0; iteration < iterations; iteration++) {
            runner.executeRequest(request, reporter);
            log.info("Elapsed: " + (System.currentTimeMillis() - startTime) + ", limit: " + (hold * 1000));
            if (hold > 0 && System.currentTimeMillis() - startTime > hold * 1000) {
                log.info("Duration limit reached, stopping");
                break;
            }
        }

        reporter.close();
    }

    protected static JUnitRunner getJUnitRunner(String junitVersion) {
        log.fine("Set JUnit version = " + junitVersion);
        if (junitVersion == null || junitVersion.isEmpty() || junitVersion.equals("4")) {
            log.fine("Will use JUnit 4 version");
            return new JUnit4Runner();
        } else if (junitVersion.equals("5")) {
            log.fine("Will use JUnit 5 version");
            return new JUnit5Runner();
        } else {
            log.warning("Cannot detect JUnit version=" + junitVersion + ". Will use JUnit 4 version");
            return new JUnit4Runner();
        }
    }

    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)
                || 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;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy