package ch21concurrent.examples;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/**
* TestBoundedBuffer
* <p/>
* Basic unit tests for BoundedBuffer
*
* @author Brian Goetz and Tim Peierls
*/
@Test
public class TestBoundedBuffer {
private static final long LOCKUP_DETECT_TIMEOUT = 1000;
private static final int CAPACITY = 10000;
private static final int THRESHOLD = 10000;
void testIsEmptyWhenConstructed() {
SemaphoreBoundedBuffer<Integer> bb = new SemaphoreBoundedBuffer<Integer>(10);
assertTrue(bb.isEmpty());
assertFalse(bb.isFull());
}
void testIsFullAfterPuts() throws InterruptedException {
SemaphoreBoundedBuffer<Integer> bb = new SemaphoreBoundedBuffer<Integer>(10);
for (int i = 0; i < 10; i++)
bb.put(i);
assertTrue(bb.isFull());
assertFalse(bb.isEmpty());
}
void testTakeBlocksWhenEmpty() {
final SemaphoreBoundedBuffer<Integer> bb = new SemaphoreBoundedBuffer<Integer>(10);
Thread taker = new Thread() {
public void run() {
try {
int unused = bb.take();
fail(); // if we get here, it's an error
} catch (InterruptedException success) {
}
}
};
try {
taker.start();
Thread.sleep(LOCKUP_DETECT_TIMEOUT);
taker.interrupt();
taker.join(LOCKUP_DETECT_TIMEOUT);
assertFalse(taker.isAlive());
} catch (Exception unexpected) {
fail();
}
}
class Big {
double[] data = new double[100000];
}
void testLeak() throws InterruptedException {
SemaphoreBoundedBuffer<Big> bb = new SemaphoreBoundedBuffer<Big>(CAPACITY);
int heapSize1 = snapshotHeap();
for (int i = 0; i < CAPACITY; i++)
bb.put(new Big());
for (int i = 0; i < CAPACITY; i++)
bb.take();
int heapSize2 = snapshotHeap();
assertTrue(Math.abs(heapSize1 - heapSize2) < THRESHOLD);
}
private int snapshotHeap() {
/* Snapshot heap and return heap size */
return 0;
}
}