/*
 * Copyright 2006 Takahiro Nakamura.
 *
 * 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 woolpack.test.ee;

import java.util.concurrent.CountDownLatch;

import woolpack.LoadAllTests;
import woolpack.test.RunnableGate;
import junit.framework.TestCase;

public class RunnableGateTest extends TestCase {
	
	public void testConstuctor(){
		try{
			new RunnableGate(null, "end", LoadAllTests.THREAD_POOL, 1);
			fail();
		}catch(final NullPointerException e){
		}
		try{
			new RunnableGate("", "end", LoadAllTests.THREAD_POOL, 1);
			fail();
		}catch(final StringIndexOutOfBoundsException e){
		}
		try{
			new RunnableGate("start", null, LoadAllTests.THREAD_POOL, 1);
			fail();
		}catch(final NullPointerException e){
		}
		try{
			new RunnableGate("start", "", LoadAllTests.THREAD_POOL, 1);
			fail();
		}catch(final StringIndexOutOfBoundsException e){
		}
		try{
			new RunnableGate("start", "end", null, 1);
			fail();
		}catch(final NullPointerException e){
		}
		try{
			new RunnableGate("start", "end", LoadAllTests.THREAD_POOL, 0);
			fail();
		}catch(final IllegalArgumentException e){
			assertEquals("timeout must be positive value.", e.getMessage());
		}
	}
	
	/**
	 * 確率的テスト(確率的に失敗する)
	 * @throws InterruptedException 
	 *
	 */
	public void testExecuteTimeout() throws InterruptedException{
		final CountDownLatch latch = new CountDownLatch(LoadAllTests.MAX_THREAD);
		try{
			final RunnableGate g = new RunnableGate("start", "end", LoadAllTests.THREAD_POOL, 1);
			
			// スレッドプールを5ミリ秒ほど全使用状態にする。
			for(int i=0; i<LoadAllTests.MAX_THREAD; i++){
				LoadAllTests.THREAD_POOL.execute(new Runnable(){
					public void run() {
						try {
							Thread.sleep(5);
						} catch (final InterruptedException e) {
							Thread.currentThread().interrupt();
							throw new RuntimeException(e);
						}finally{
							latch.countDown();
						}
					}
				});
			}
			
			g.execute(g.getGate("mid"));
			fail();
		}catch(final RuntimeException e){
			assertTrue(e.getCause() instanceof InterruptedException);
			assertTrue(Thread.currentThread().isInterrupted());
			Thread.interrupted();
		}finally{
			// 次のテストへの副作用をなくすためスレッドプールの全てが待機状態になるまで待つ
			latch.await();
		}
	}
}
