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

com.peachapisecurity.tg.junit4.JUnit4PeachSuiteRunner Maven / Gradle / Ivy

The newest version!

/*
 * Copyright 2017 Peach Tech
 * 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.peachapisecurity.tg.junit4;

import com.peachapisecurity.api.PeachState;
import com.peachapisecurity.api.PeachApiException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import junit.framework.TestResult;
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;

import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.ParentRunner;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;
import org.junit.runners.model.Statement;

/**
 * Using JUnit4PeachSuiteRunner as a runner allows you to manually
 * build a fuzzing suite containing tests from many classes. It is the JUnit 4
 * equivalent of the JUnit 3.8.x static {@link junit.framework.Test}
 * suite() method. To use it, annotate a class with
 * @RunWith(JUnit4PeachSuiteRunner.class) and
 * @PeachSuiteClasses({TestClass1.class, ...}). When you run this
 * class, it will run all the tests in all the suite classes.
 *
 * @since 4.0
 */
public class JUnit4PeachSuiteRunner extends ParentRunner {

    protected final static PeachContext _context = new PeachContext();
    public static JUnit4PeachListener _listener = new JUnit4PeachListener();

    /**
     * Returns an empty suite.
     *
     * @return Returns runner instance
     */
    public static Runner emptySuite() {
        try {
            return new JUnit4PeachSuiteRunner((Class) null, new Class[0]);
        } catch (InitializationError e) {
            throw new RuntimeException("This shouldn't be possible");
        }
    }

    /**
     * The SuiteClasses annotation specifies the classes to be run
     * when a class annotated with @RunWith(Suite.class) is run.
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Inherited
    public @interface PeachSuiteClasses {

        /**
         * @return the classes to be run
         */
        Class[] value();
    }

    private static Class[] getAnnotatedClasses(Class klass) throws InitializationError {
        PeachSuiteClasses annotation = klass.getAnnotation(PeachSuiteClasses.class);
        if (annotation == null) {
            throw new InitializationError(String.format("class '%s' must have a SuiteClasses annotation", klass.getName()));
        }
        return annotation.value();
    }

    private final List runners;

    protected static List runners(Class[] children) throws InitializationError {
        List runners = new ArrayList();

        for (Class each : children) {
            Runner childRunner = new JUnit4PeachRunner(_context, each);
            if (childRunner != null) {
                runners.add(childRunner);
            }
        }

        return runners;
    }

    /**
     * Called reflectively on classes annotated with
     * @RunWith(JUnit4PeachSuiteRunner.class)
     *
     * @param klass the root class
     * @param builder builds runners for classes in the suite
     * @throws InitializationError throws exception
     */
    public JUnit4PeachSuiteRunner(Class klass, RunnerBuilder builder) throws InitializationError {
        this(builder, klass, getAnnotatedClasses(klass));
        //System.out.println(">> public JUnit4PeachSuiteRunner(Class klass, RunnerBuilder builder)");
    }

    /**
     * Call this when there is no single root class (for example, multiple class
     * names passed on the command line to {@link org.junit.runner.JUnitCore}
     *
     * @param builder builds runners for classes in the suite
     * @param classes the classes in the suite
     * @throws InitializationError throws exception
     */
    public JUnit4PeachSuiteRunner(RunnerBuilder builder, Class[] classes) throws InitializationError {
        this(null, builder.runners(null, classes));
        //System.out.println(">> public JUnit4PeachSuiteRunner(RunnerBuilder builder, Class[] classes)");
    }

    /**
     * Call this when the default builder is good enough. Left in for
     * compatibility with JUnit 4.4.
     *
     * @param klass the root of the suite
     * @param suiteClasses the classes in the suite
     * @throws InitializationError throws exceptions
     */
    protected JUnit4PeachSuiteRunner(Class klass, Class[] suiteClasses) throws InitializationError {
        this(new AllDefaultPossibilitiesBuilder(true), klass, suiteClasses);
        //System.out.println(">> protected JUnit4PeachSuiteRunner(Class klass, Class[] suiteClasses)");
    }

    /**
     * Called by this class and subclasses once the classes making up the suite
     * have been determined
     *
     * @param builder builds runners for classes in the suite
     * @param klass the root of the suite
     * @param suiteClasses the classes in the suite
     * @throws InitializationError throws exceptions
     */
    protected JUnit4PeachSuiteRunner(RunnerBuilder builder, Class klass, Class[] suiteClasses) throws InitializationError {
        this(klass, runners(suiteClasses));
        //System.out.println(">> protected JUnit4PeachSuiteRunner(RunnerBuilder builder, Class klass, Class[] suiteClasses)");
    }

    /**
     * Called by this class and subclasses once the runners making up the suite
     * have been determined
     *
     * @param klass root of the suite
     * @param runners for each class in the suite, a {@link Runner}
     * @throws InitializationError throws exceptions
     */
    protected JUnit4PeachSuiteRunner(Class klass, List runners) throws InitializationError {
        super(klass);
        this.runners = Collections.unmodifiableList(runners);
        String proxyUrl = _context.proxy.getProxyUrl();

        if (proxyUrl == null || proxyUrl.isEmpty()) {
            try {
                // no session was detected so set one up
                _context.proxy.sessionSetup("Default", "Quick");
            } catch (PeachApiException ex) {
                throw new InitializationError(ex);
            }
        }
        //System.out.println(">> protected JUnit4PeachSuiteRunner(Class klass, List runners)");
    }

    @Override
    protected List getChildren() {
        if (_context.debug) {
            System.out.println(">> PeachSuiteRunner.getChildren()");
        }
        return runners;
    }

    @Override
    protected Description describeChild(Runner child) {
        return child.getDescription();
    }

    @Override
    protected Statement childrenInvoker(final RunNotifier notifier) {

        final Statement innerStatement = super.childrenInvoker(notifier);

        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                innerStatement.evaluate();

                if (_context.debug) {
                    System.out.println(">> PeachSuiteRunner.childrenInvoker.evaluate: suiteTeardown");
                }

            }
        };
    }

    @Override
    protected void runChild(Runner runner, final RunNotifier notifier) {
        if (_context.debug) {
            System.out.println(">> PeachSuiteRunner.runChild");
        }

        _context.state = PeachState.Continue;
        _listener.refCount++;
        _listener.setContext(_context);
        notifier.addListener(_listener);

        while (_context.state.equals(PeachState.Continue)) {
            if (_context.debug) {
                System.out.println("PeachSuiteRunner.runChild.run(...)");
            }

            runner.run(notifier);
        }

        if (_context.debug) {
            System.out.println("<< runChild");
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy