/*
 * Copyright 2002-2006 the original author or authors.
 *
 * 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 org.springframework.core.task;

import junit.framework.TestCase;

import org.springframework.util.ConcurrencyThrottleSupport;

/**
 * @author Rick Evans
 */
public final class SimpleAsyncTaskExecutorTests extends TestCase {

	public void testCannotExecuteWhenConcurrencyIsSwitchedOff() throws Exception {
		SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
		executor.setConcurrencyLimit(ConcurrencyThrottleSupport.NO_CONCURRENCY);
		assertFalse(executor.isThrottleActive());
		try {
			executor.execute(new NoOpRunnable());
		}
		catch (IllegalStateException expected) {
		}
	}

	public void testThrottleIsNotActiveByDefault() throws Exception {
		SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
		assertFalse("Concurrency throttle must not default to being active (on).", executor.isThrottleActive());
	}

	public void testThreadNameGetsSetCorrectly() throws Exception {
		final String customPrefix = "chankPop#";
		final Object monitor = new Object();
		SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor(customPrefix);
		ThreadNameHarvester task = new ThreadNameHarvester(monitor);
		executeAndWait(executor, task, monitor);
		assertTrue(task.getThreadName().startsWith(customPrefix));
	}

	public void testThreadNameRevertsToDefaultIfSetToNull() throws Exception {
		final Object monitor = new Object();
		SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor(null);
		ThreadNameHarvester task = new ThreadNameHarvester(monitor);
		executeAndWait(executor, task, monitor);
		assertTrue(task.getThreadName().startsWith(SimpleAsyncTaskExecutor.DEFAULT_THREAD_NAME_PREFIX));
	}

	public void testThrowsExceptionWhenSuppliedWithNullRunnable() throws Exception {
		try {
			new SimpleAsyncTaskExecutor().execute(null);
			fail("Should have thrown IllegalArgumentException");
		}
		catch (IllegalArgumentException expected) {
		}
	}


	private static void executeAndWait(SimpleAsyncTaskExecutor executor, Runnable task, Object monitor) {
		synchronized (monitor) {
			executor.execute(task);
			try {
				monitor.wait();
			}
			catch (InterruptedException ignored) {
			}
		}
	}


	private static final class NoOpRunnable implements Runnable {

		public void run() {
			// no-op
		}
	}

	private static abstract class AbstractNotifyingRunnable implements Runnable {

		private final Object monitor;

		protected AbstractNotifyingRunnable(Object monitor) {
			this.monitor = monitor;
		}

		public final void run() {
			synchronized (this.monitor) {
				try {
					doRun();
				}
				finally {
					this.monitor.notifyAll();
				}
			}
		}

		protected abstract void doRun();
	}

	private static final class ThreadNameHarvester extends AbstractNotifyingRunnable {

		private String threadName;

		protected ThreadNameHarvester(Object monitor) {
			super(monitor);
		}

		public String getThreadName() {
			return this.threadName;
		}

		protected void doRun() {
			this.threadName = Thread.currentThread().getName();
		}
	}

}

@@ -21,9 +21,9 @@
 -200
-6
+7
  the
@@ -689,16 +689,60 @@
 tCase;%0A%0A
+import org.springframework.util.ClassUtils;%0A
 import o
@@ -820,16 +820,43 @@
 k Evans%0A
+ * @author Juergen Hoeller%0A
  */%0Apubl
@@ -1498,17 +1498,16 @@
 ive (on)
-.
 %22, execu
@@ -2275,58 +2275,68 @@
 ith(
-SimpleAsyncTaskExecutor.DEFAULT_THREAD_NAME_PREFIX
+ClassUtils.getShortName(SimpleAsyncTaskExecutor.class) + %22-%22
 ));%0A
@@ -2583,33 +2583,32 @@
 cted) %7B%0A%09%09%7D%0A%09%7D%0A%0A
-%0A
 %09private static 
@@ -2600,23 +2600,16 @@
 private 
-static 
 void exe
@@ -2929,32 +2929,33 @@
 / no-op%0A%09%09%7D%0A%09%7D%0A%0A
+%0A
 %09private static 
@@ -3326,20 +3326,21 @@
 oRun();%0A
-
 %09%7D%0A%0A
+%0A
 %09private

test against actual default thread name