Package fi.jumi.core.suite

Source Code of fi.jumi.core.suite.SuiteFactory

// Copyright © 2011-2014, Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package fi.jumi.core.suite;

import fi.jumi.actors.*;
import fi.jumi.actors.eventizers.ComposedEventizerProvider;
import fi.jumi.actors.listeners.*;
import fi.jumi.core.api.SuiteListener;
import fi.jumi.core.config.*;
import fi.jumi.core.discovery.*;
import fi.jumi.core.drivers.*;
import fi.jumi.core.events.*;
import fi.jumi.core.runs.RunIdSequence;
import fi.jumi.core.stdout.OutputCapturer;
import fi.jumi.core.util.*;

import javax.annotation.concurrent.NotThreadSafe;
import java.io.PrintStream;
import java.net.*;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.*;

@NotThreadSafe
public class SuiteFactory implements AutoCloseable {

    private final DaemonConfiguration config;
    private final OutputCapturer outputCapturer;
    private final PrintStream logOutput;
    private final MessageListener messageListener;

    // some fields are package-private for testing purposes

    private ExecutorService actorThreadPool;
    ExecutorService testThreadPool;
    ClassLoader testClassLoader;
    private TestFileFinder testFileFinder;
    private CompositeDriverFinder driverFinder;
    private RunIdSequence runIdSequence;
    MultiThreadedActors actors;

    public SuiteFactory(DaemonConfiguration daemonConfiguration, OutputCapturer outputCapturer, PrintStream logOutput, MessageListener messageListener) {
        this.config = daemonConfiguration;
        this.outputCapturer = outputCapturer;
        this.logOutput = logOutput;
        this.messageListener = messageListener;
    }

    public void configure(SuiteConfiguration suite) {
        testClassLoader = createClassLoader(suite.getClasspath());
        testFileFinder = createTestFileFinder(suite);
        driverFinder = DriverFinderFactory.createDriverFinder(testClassLoader, logOutput);
        runIdSequence = new RunIdSequence();

        // thread pool configuration
        actorThreadPool = Executors.newCachedThreadPool(new PrefixedThreadFactory("jumi-actor-"));
        testThreadPool = Executors.newFixedThreadPool(config.getTestThreadsCountCalculated(),
                new ContextClassLoaderThreadFactory(testClassLoader, new PrefixedThreadFactory("jumi-test-")));
    }

    public void start(final SuiteListener suiteListener) {

        // logging configuration
        FailureHandler failureHandler = new InternalErrorReportingFailureHandler(suiteListener, logOutput);

        // actor messages are already logged by the actors container, but the test thread pool must be hooked separately
        Executor testExecutor = messageListener.getListenedExecutor(testThreadPool);

        // actors configuration
        // TODO: not all of these eventizers might be needed - create a statistics gathering EventizerProvider
        actors = new MultiThreadedActors(
                actorThreadPool,
                new ComposedEventizerProvider(
                        new StartableEventizer(),
                        new RunnableEventizer(),
                        new WorkerListenerEventizer(),
                        new TestFileFinderListenerEventizer(),
                        new SuiteListenerEventizer(),
                        new RequestListenerEventizer(),
                        new RunListenerEventizer()
                ),
                failureHandler,
                messageListener
        );

        // bootstrap the system
        ActorThread actorThread = actors.startActorThread();
        ActorRef<TestFileFinderListener> suiteRunner = actorThread.bindActor(TestFileFinderListener.class,
                new SuiteRunner(
                        new DriverFactory(suiteListener, actorThread, outputCapturer, driverFinder, runIdSequence, testClassLoader),
                        suiteListener,
                        actorThread,
                        testExecutor,
                        logOutput
                ));

        suiteListener.onSuiteStarted();
        actorThreadPool.execute(new TestFileFinderRunner(testFileFinder, suiteRunner));
    }

    @Override
    public void close() {
        if (actorThreadPool != null) {
            actorThreadPool.shutdownNow();
        }
        if (testThreadPool != null) {
            testThreadPool.shutdownNow();
        }
    }

    private static ClassLoader createClassLoader(List<URI> classpath) {
        try {
            return new URLClassLoader(asUrls(classpath));
        } catch (MalformedURLException e) {
            throw new RuntimeException("Failed to create class loader for classpath " + classpath, e);
        }
    }

    private static URL[] asUrls(List<URI> uris) throws MalformedURLException {
        URL[] urls = new URL[uris.size()];
        for (int i = 0, filesLength = uris.size(); i < filesLength; i++) {
            urls[i] = uris.get(i).toURL();
        }
        return urls;
    }

    private static TestFileFinder createTestFileFinder(SuiteConfiguration suite) {
        List<Path> classDirectories = getClassDirectories(suite);
        List<TestFileFinder> finders = new ArrayList<>();
        for (Path dir : classDirectories) {
            PathMatcher matcher = suite.createTestFileMatcher(dir.getFileSystem());
            finders.add(new PathMatcherTestFileFinder(matcher, dir));
        }
        return new CompositeTestFileFinder(finders);
    }

    public static List<Path> getClassDirectories(SuiteConfiguration suite) {
        ArrayList<Path> dirs = new ArrayList<>();
        for (URI uri : suite.getClasspath()) {
            Path path = Paths.get(uri);
            if (Files.isDirectory(path)) {
                dirs.add(path);
            }
        }
        return dirs;
    }
}
TOP

Related Classes of fi.jumi.core.suite.SuiteFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.