package jp.terasoluna.fw.collector.db;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class QueueingResultHandlerImplTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Before
public void setUp() throws Exception {
QueueingResultHandlerImpl.setVerbose(true);
}
@After
public void tearDown() throws Exception {
QueueingResultHandlerImpl.setVerbose(false);
Thread.interrupted();
}
/**
* testHandleResult
*/
@Test
public void testHandleResult001() {
QueueingResultHandlerImpl<HogeBean> drh = new QueueingResultHandlerImpl<>();
DummyResultContext ctxInNull = new DummyResultContext();
ctxInNull.setResultObject(null);
assertNotNull(drh);
try {
drh.handleResult(ctxInNull);
drh.handleResult(ctxInNull);
drh.handleResult(ctxInNull);
drh.handleResult(ctxInNull);
drh.handleResult(ctxInNull);
} catch (Exception e) {
e.printStackTrace();
fail();
}
}
/**
* testHandleResult
*/
@Test
public void testHandleResult002() {
QueueingResultHandlerImpl<HogeBean> drh = new QueueingResultHandlerImpl<>();
assertNotNull(drh);
try {
DummyResultContext context = new DummyResultContext();
context.setResultObject(HogeBean.buider().hoge("hoge1").build());
drh.handleResult(context);
context = new DummyResultContext();
context.setResultObject(HogeBean.buider().hoge("hoge2").build());
drh.handleResult(context);
DummyResultContext contextInNull = new DummyResultContext();
contextInNull.setResultObject(null);
drh.handleResult(contextInNull);
context = new DummyResultContext();
context.setResultObject(HogeBean.buider().hoge("hoge3").build());
drh.handleResult(context);
context = new DummyResultContext();
context.setResultObject(HogeBean.buider().hoge("hoge4").build());
drh.handleResult(context);
} catch (Exception e) {
e.printStackTrace();
fail();
}
}
/**
* testHandleResult
*/
@Test
public void testHandleResult003() {
QueueingResultHandlerImpl<HogeBean> drh = new QueueingResultHandlerImpl<>();
DaoCollector<HogeBean> daoCollector = new DaoCollectorStub004(5);
drh.setDaoCollector(daoCollector);
assertNotNull(drh);
try {
DummyResultContext context = new DummyResultContext();
context.setResultObject(HogeBean.buider().hoge("hoge1").build());
drh.handleResult(context);
context.setResultObject(HogeBean.buider().hoge("hoge2").build());
drh.handleResult(context);
DummyResultContext contextInNull = new DummyResultContext();
contextInNull.setResultObject(null);
drh.handleResult(contextInNull);
context.setResultObject(HogeBean.buider().hoge("hoge3").build());
drh.handleResult(context);
context.setResultObject(HogeBean.buider().hoge("hoge4").build());
drh.handleResult(context);
} catch (Exception e) {
e.printStackTrace();
fail();
}
}
@Test
public void testHandleResult004() throws Exception {
final QueueingResultHandlerImpl<HogeBean> drh = new QueueingResultHandlerImpl<>();
DaoCollector<HogeBean> daoCollector = new DaoCollectorStub001();
drh.setDaoCollector(daoCollector);
ExecutorService service = Executors.newSingleThreadExecutor();
ErrorFeedBackRunnable runnable = new ErrorFeedBackRunnable() {
@Override
public void doRun() {
Thread.currentThread().interrupt();
// 割り込み発生時はhandleResultは処理されず、スレッドが割り込み状態のままであること。
DummyResultContext context = new DummyResultContext();
context.setResultObject(HogeBean.buider().hoge("hoge1").build());
drh.handleResult(context);
assertTrue(Thread.currentThread().isInterrupted());
assertNull(drh.prevRow);
}
};
service.submit(runnable);
runnable.throwErrorOrExceptionIfThrown();
}
/**
* testHandleResult
*/
@Test
public void testHandleResult005() {
QueueingResultHandlerImpl<HogeBean> drh = new QueueingResultHandlerImpl<>();
DaoCollectorStub001 daoCollector = new DaoCollectorStub001();
drh.setDaoCollector(daoCollector);
assertNotNull(drh);
DummyResultContext context = new DummyResultContext();
context.setResultObject(HogeBean.buider().hoge("hoge1").build());
drh.handleResult(context);
context.setResultObject(HogeBean.buider().hoge("hoge2").build());
drh.handleResult(context);
daoCollector.exceptionFlag = true;
context.setResultObject(HogeBean.buider().hoge("hoge3").build());
drh.handleResult(context);
assertTrue(Thread.currentThread().isInterrupted());
}
@Test
public void testDelayCollect001() throws Exception {
final QueueingResultHandlerImpl<HogeBean> drh = new QueueingResultHandlerImpl<>();
DaoCollectorStub004 daoCollector = new DaoCollectorStub004(1);
drh.setDaoCollector(daoCollector);
drh.prevRow = HogeBean.buider().hoge("rowObject").build();
ExecutorService service = Executors.newSingleThreadExecutor();
ErrorFeedBackRunnable runnable = new ErrorFeedBackRunnable() {
@Override
public void doRun() throws Exception {
Thread.currentThread().interrupt();
// 割り込み発生時はdelayCollectは処理されず、スレッドが割り込み状態のままであること。
drh.delayCollect();
assertTrue(Thread.currentThread().isInterrupted());
}
};
service.submit(runnable);
runnable.throwErrorOrExceptionIfThrown();
// 割り込み例外によりキューイングされていないこと。
assertEquals(0, daoCollector.getQueue().size());
}
@Test
public void testDelayCollect002() throws Exception {
final QueueingResultHandlerImpl<HogeBean> drh = new QueueingResultHandlerImpl<>();
DaoCollectorStub003 daoCollector = new DaoCollectorStub003();
drh.setDaoCollector(daoCollector);
drh.prevRow = HogeBean.buider().hoge("rowObject").build();
ExecutorService service = Executors.newSingleThreadExecutor();
ErrorFeedBackRunnable runnable = new ErrorFeedBackRunnable() {
@Override
public void doRun() throws Exception {
drh.delayCollect();
assertTrue(Thread.currentThread().isInterrupted());
}
};
Future<?> future = service.submit(runnable);
while (true) {
try {
// コレクタのキュー挿入スレッドがブロックされるまで少し待つ
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
}
if (daoCollector.isBlocked()) {
break;
}
}
// タスクキャンセルを実行。
future.cancel(true);
runnable.throwErrorOrExceptionIfThrown();
}
/**
* エラーをフィードバックできるRunnable実装。
* 別スレッドで実施したい内容を doRun() throws Exception に実装する。
* 試験終了時、throwErrorOrExceptionIfThrownメソッドを実行すると、
* doRunメソッドにて想定外のエラーが発生した場合に、そのエラーがスローされる。
*/
abstract class ErrorFeedBackRunnable implements Runnable {
private Exception exception;
private Error error;
private CountDownLatch latch = new CountDownLatch(1);
public void run() {
try {
doRun();
} catch (Exception e) {
exception = e;
} catch (Error e) {
error = e;
} finally {
latch.countDown();
}
}
public void throwErrorOrExceptionIfThrown() throws Exception {
latch.await();
if (error != null) {
throw error;
} else if (exception != null) {
throw exception;
}
}
abstract void doRun() throws Exception;
}
}