com.cognifide.qa.bb.junit.concurrent.ConcurrentSuiteRunnerScheduler.java Source code

Java tutorial

Introduction

Here is the source code for com.cognifide.qa.bb.junit.concurrent.ConcurrentSuiteRunnerScheduler.java

Source

/*-
 * #%L
 * Bobcat
 * %%
 * Copyright (C) 2016 Cognifide Ltd.
 * %%
 * 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.
 * #L%
 */
package com.cognifide.qa.bb.junit.concurrent;

import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.lang3.StringUtils;
import org.junit.runners.model.RunnerScheduler;

import com.cognifide.qa.bb.provider.selenium.webdriver.WebDriverRegistry;

/**
 * Internal test thread scheduler.
 */
final class ConcurrentSuiteRunnerScheduler implements RunnerScheduler {

    private static final String THREAD_COUNT_PROPERTY = "thread.count";

    private final ExecutorService executorService;

    private final CompletionService<Void> completionService;

    private final Queue<Future<Void>> tasks = new LinkedList<>();

    private final Properties properties;

    private final ReportingHandler reportingHandler;

    private final WebDriverRegistry webDriverRegistry;

    /**
     * Constructs ConcurrentSuiteRunnerScheduler.
     *
     * @param clazz
     * @param properties
     * @param reportingHandler
     */
    ConcurrentSuiteRunnerScheduler(Class<?> clazz, Properties properties, ReportingHandler reportingHandler,
            WebDriverRegistry webDriverRegistry) {
        this.properties = properties;
        this.reportingHandler = reportingHandler;
        this.webDriverRegistry = webDriverRegistry;
        executorService = Executors.newFixedThreadPool(determineNumberOfThreads(clazz),
                new NamedThreadFactory(clazz.getSimpleName()));
        completionService = new ExecutorCompletionService<>(executorService);
    }

    /**
     * Schedule a child statement to run
     */
    @Override
    public void schedule(Runnable childStatement) {
        Future<Void> submittedStatement = completionService.submit(childStatement, null);
        tasks.add(submittedStatement);
    }

    /**
     * Performs clean up activities:
     * <ul>
     * <li>cancels and removes all tasks from the queue,
     * <li>shuts down the executor service,
     * <li>tells the reporting handler to generate final report.
     * </ul>
     */
    @Override
    public void finished() {
        QueueFinalizer queueFinalizer = new QueueFinalizer();
        queueFinalizer.finalizeQueue(tasks, completionService, executorService);

        try {
            webDriverRegistry.shutdown();
            reportingHandler.endOfSuite();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

    }

    private int determineNumberOfThreads(Class<?> clazz) {
        String property = properties.getProperty(THREAD_COUNT_PROPERTY);
        int numberOfThreads;
        if (StringUtils.isNotEmpty(property)) {
            numberOfThreads = Integer.parseInt(property);
        } else if (clazz.isAnnotationPresent(Concurrent.class)) {
            numberOfThreads = clazz.getAnnotation(Concurrent.class).threads();
        } else {
            numberOfThreads = (int) (Runtime.getRuntime().availableProcessors() * Concurrent.THREADS_NUMBER_FACTOR);
        }
        return numberOfThreads;
    }
}