/**
* Copyright (C) 2009-2013 Barchart, Inc. <http://www.barchart.com/>
*
* All rights reserved. Licensed under the OSI BSD License.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package com.barchart.udt;
import static org.junit.Assert.*;
import java.nio.ByteBuffer;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import util.TestAny;
/**
* verify mingw c++ exceptions are thread safe (will crash jvm if not using
* -mthreads option for gcc/ld)
*/
public class TestExceptions extends TestAny {
final static int TEST_TIMEOUT = 10; // seconds
static final int SIZE = 1460;
static final int COUNT = 1000;
static final int THREADS = 30;
volatile CyclicBarrier barrier;
volatile ExecutorService service;
volatile AtomicInteger exceptionCount;
@Before
public void setUp() throws Exception {
exceptionCount = new AtomicInteger(0);
barrier = new CyclicBarrier(THREADS + 1);
service = Executors.newFixedThreadPool(THREADS);
}
@After
public void tearDown() throws Exception {
service.shutdownNow();
}
static final AtomicInteger threadCount = new AtomicInteger(0);
final Runnable exceptionTask = new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(
"Exception Runner #" + threadCount.getAndIncrement());
final ByteBuffer buffer = ByteBuffer.allocateDirect(SIZE);
SocketUDT socket = null;
try {
socket = new SocketUDT(TypeUDT.DATAGRAM);
} catch (final Exception e) {
fail("can not init socket; " + e.getMessage());
}
for (int k = 0; k < COUNT; k++) {
try {
/** must throw exception */
socket.receive(buffer);
fail("exception not thrown");
} catch (final Exception e) {
exceptionCount.getAndIncrement();
}
}
if (socket != null) {
try {
socket.close();
} catch (final Exception e) {
fail("can not close socket");
}
}
try {
barrier.await();
} catch (final Exception e) {
fail(e.getMessage());
}
}
};
@Test
public void testException() {
log.info("start");
for (int k = 0; k < THREADS; k++) {
service.submit(exceptionTask);
}
try {
barrier.await(TEST_TIMEOUT, TimeUnit.SECONDS);
} catch (final Exception e) {
fail(e.getMessage());
}
assertEquals(exceptionCount.get(), THREADS * COUNT);
log.info("finish");
}
}