/* * Copyright (c) 2013 Red Hat, Inc. and/or its affiliates. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cheng Fang - Initial API and implementation */ package org.jberet.se; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import javax.batch.operations.BatchRuntimeException; import org.junit.Assert; import org.junit.Test; import static org.jberet.se.BatchSEEnvironment.THREAD_FACTORY; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_ALLOW_CORE_THREAD_TIMEOUT; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_CORE_SIZE; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_KEEP_ALIVE_TIME; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_MAX_SIZE; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_PRESTART_ALL_CORE_THREADS; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_QUEUE_CAPACITY; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_REJECTION_POLICY; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_TYPE; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_TYPE_CONFIGURED; import static org.jberet.se.BatchSEEnvironment.THREAD_POOL_TYPE_FIXED; public class BatchSEEnvironmentTest { private BatchSEEnvironment batchEnvironment = new BatchSEEnvironment(); @Test public void testCreateThreadPoolExecutor() throws Exception { final Properties configProperties = batchEnvironment.getBatchConfigurationProperties(); final Class<? extends ThreadFactory> defaultThreadFactoryClass = BatchThreadFactory.class; final Class<? extends RejectedExecutionHandler> defaultRejectionHandlerClass = ThreadPoolExecutor.AbortPolicy.class; //when jberet-se/src/test/resources/jberet.properties contains no thread-pool related properties, //Cached thread-pool is used, with default values verifyThreadPool(0, Integer.MAX_VALUE, 60L, 0, defaultThreadFactoryClass, false, defaultRejectionHandlerClass, batchEnvironment.createThreadPoolExecutor()); final Class<? extends ThreadFactory> threadFactoryClass = SimpleThreadFactory.class; final int coreSize = 10; final int maxSize = 100; final long keepAliveTime = 600; final int queueCapacity = 300; //a Cached thread-pool, with a thread-factory, coreSize (ignored), maxSize (ignored), keepAliveTime (ignored), //queueCapacity (ignored), allowCoreThreadTimeout (ignored) configProperties.setProperty(THREAD_FACTORY, threadFactoryClass.getName()); configProperties.setProperty(THREAD_POOL_CORE_SIZE, String.valueOf(coreSize)); configProperties.setProperty(THREAD_POOL_MAX_SIZE, String.valueOf(maxSize)); configProperties.setProperty(THREAD_POOL_KEEP_ALIVE_TIME, String.valueOf(keepAliveTime)); configProperties.setProperty(THREAD_POOL_QUEUE_CAPACITY, String.valueOf(queueCapacity)); configProperties.setProperty(THREAD_POOL_ALLOW_CORE_THREAD_TIMEOUT, String.valueOf(true)); verifyThreadPool(0, Integer.MAX_VALUE, 60L, 0, threadFactoryClass, false, defaultRejectionHandlerClass, batchEnvironment.createThreadPoolExecutor()); //a Fixed thread-pool, with a thread-factory, coreSize (ignored), maxSize (ignored), keepAliveTime (ignored), //queueCapacity (ignored), allowCoreThreadTimeout (ignored) configProperties.setProperty(THREAD_POOL_TYPE, THREAD_POOL_TYPE_FIXED); verifyThreadPool(coreSize, coreSize, 0L, Integer.MAX_VALUE, threadFactoryClass, false, defaultRejectionHandlerClass, batchEnvironment.createThreadPoolExecutor()); //a Fixed thread-pool, with default thread-factory configProperties.setProperty(THREAD_FACTORY, defaultThreadFactoryClass.getName()); verifyThreadPool(coreSize, coreSize, 0L, Integer.MAX_VALUE, defaultThreadFactoryClass, false, defaultRejectionHandlerClass, batchEnvironment.createThreadPoolExecutor()); //a Configured thread-pool, with a thread-factory, coreSize (ignored), maxSize (ignored), keepAliveTime (ignored), //queueCapacity (ignored), allowCoreThreadTimeout (ignored) configProperties.setProperty(THREAD_POOL_TYPE, THREAD_POOL_TYPE_CONFIGURED); verifyThreadPool(coreSize, maxSize, keepAliveTime, queueCapacity, defaultThreadFactoryClass, true, defaultRejectionHandlerClass, batchEnvironment.createThreadPoolExecutor()); //a Configured thread-pool, with a custom thread-factory, allowCoreThreadTimeout false configProperties.setProperty(THREAD_FACTORY, threadFactoryClass.getName()); configProperties.setProperty(THREAD_POOL_ALLOW_CORE_THREAD_TIMEOUT, String.valueOf(false)); verifyThreadPool(coreSize, maxSize, keepAliveTime, queueCapacity, threadFactoryClass, false, defaultRejectionHandlerClass, batchEnvironment.createThreadPoolExecutor()); //a Configured thread-pool, with prestartCore true configProperties.setProperty(THREAD_POOL_PRESTART_ALL_CORE_THREADS, String.valueOf(true)); final ThreadPoolExecutor threadPoolExecutor = verifyThreadPool(coreSize, maxSize, keepAliveTime, queueCapacity, threadFactoryClass, false, defaultRejectionHandlerClass, batchEnvironment.createThreadPoolExecutor()); Assert.assertEquals(coreSize, threadPoolExecutor.getPoolSize()); //a Configured thread-pool, with custom rejection policy configProperties.setProperty(THREAD_POOL_REJECTION_POLICY, SimpleRejectionHandler.class.getName()); verifyThreadPool(coreSize, maxSize, keepAliveTime, queueCapacity, threadFactoryClass, false, SimpleRejectionHandler.class, batchEnvironment.createThreadPoolExecutor()); //a Configured thread-pool, with missing coreSize configProperties.remove(THREAD_POOL_CORE_SIZE); try { batchEnvironment.createThreadPoolExecutor(); Assert.fail("Expecting exception, but got no exception when missing property " + THREAD_POOL_CORE_SIZE); } catch (BatchRuntimeException e) { System.out.printf("Got the expected %s%n", e); } //a Configured thread-pool, with missing maxSize configProperties.setProperty(THREAD_POOL_CORE_SIZE, String.valueOf(coreSize)); configProperties.remove(THREAD_POOL_MAX_SIZE); try { batchEnvironment.createThreadPoolExecutor(); Assert.fail("Expecting exception, but got no exception when missing property " + THREAD_POOL_MAX_SIZE); } catch (BatchRuntimeException e) { System.out.printf("Got the expected %s%n", e); } //a Configured thread-pool, with missing keepAliveTime configProperties.setProperty(THREAD_POOL_CORE_SIZE, String.valueOf(coreSize)); configProperties.setProperty(THREAD_POOL_MAX_SIZE, String.valueOf(maxSize)); configProperties.remove(THREAD_POOL_KEEP_ALIVE_TIME); try { batchEnvironment.createThreadPoolExecutor(); Assert.fail("Expecting exception, but got no exception when missing property " + THREAD_POOL_KEEP_ALIVE_TIME); } catch (BatchRuntimeException e) { System.out.printf("Got the expected %s%n", e); } //a Configured thread-pool, with missing queueCapacity configProperties.setProperty(THREAD_POOL_CORE_SIZE, String.valueOf(coreSize)); configProperties.setProperty(THREAD_POOL_MAX_SIZE, String.valueOf(maxSize)); configProperties.setProperty(THREAD_POOL_KEEP_ALIVE_TIME, String.valueOf(keepAliveTime)); configProperties.remove(THREAD_POOL_QUEUE_CAPACITY); try { batchEnvironment.createThreadPoolExecutor(); Assert.fail("Expecting exception, but got no exception when missing property " + THREAD_POOL_QUEUE_CAPACITY); } catch (BatchRuntimeException e) { System.out.printf("Got the expected %s%n", e); } //invalid thread-pool type configProperties.setProperty(THREAD_POOL_TYPE, "xxx"); try { batchEnvironment.createThreadPoolExecutor(); Assert.fail("Expecting exception, but got no exception when specifying invalid property " + THREAD_POOL_TYPE); } catch (BatchRuntimeException e) { System.out.printf("Got the expected %s%n", e); } } private ThreadPoolExecutor verifyThreadPool(final int coreSize, final int maxSize, final long keepAliveTime, final int queueCapacity, final Class<? extends ThreadFactory> threadFactoryClass, final boolean allowCoreThreadTimeout, final Class<? extends RejectedExecutionHandler> rejectionHandlerClass, final ExecutorService executorService) { final ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService; Assert.assertEquals(coreSize, threadPoolExecutor.getCorePoolSize()); Assert.assertEquals(maxSize, threadPoolExecutor.getMaximumPoolSize()); Assert.assertEquals(keepAliveTime, threadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS)); Assert.assertEquals(queueCapacity, threadPoolExecutor.getQueue().remainingCapacity()); Assert.assertEquals(threadFactoryClass, threadPoolExecutor.getThreadFactory().getClass()); Assert.assertEquals(allowCoreThreadTimeout, threadPoolExecutor.allowsCoreThreadTimeOut()); Assert.assertEquals(rejectionHandlerClass, threadPoolExecutor.getRejectedExecutionHandler().getClass()); return threadPoolExecutor; } static class SimpleThreadFactory implements ThreadFactory { @Override public Thread newThread(final Runnable r) { return new Thread(r); } } static class SimpleRejectionHandler implements RejectedExecutionHandler { @Override public void rejectedExecution(final Runnable r, final ThreadPoolExecutor executor) { System.out.printf("In %s, runnalbe is %s, executor is %s%n", this, r, executor); } } }