neděle 26. října 2008

Nepovedený zimmerit - díl třetí

Po mnoha večerech, kdy jsem si hrál s novým tmelem jsem nakonec vyměkl koupil plechy od eduarda. Nejhorší bylo ten starý tmel dostat dolů. Myslím ale, že výsledek je tak o 100% lepší, než s použitím tmelu.

pátek 17. října 2008

Testing blocking operation

Sometimes I have a luck and I can write multi-threaded application. I like testing all my classes with JUnit but it has no support for concurrency.

During studding an excellent book Java Concurrency in Practice which explains all new features added in JSE5 regarding to concurrency, I was looking forward to chapter about testing with JUnit.

The author recommends - if you need to test, that your operation blocks the calling thread, it is similar pattern as testing that your operation throws Exception.


void testTakeBlocksWhenEmpty() {
final BoundedBuffer bb = new BoundedBuffer(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();
}
}


While I was watching funny video about java puzzles I was surprised, that the example from the book does not work !!!

JUnit framework all exceptions and errors which are thrown from user thread does not interprets as failure! Fortunately, it logs stack trace to the console at least.

Try this simple example - what colour does your test - green or red ?

public void testFail() throws InterruptedException {
final Thread t = new Thread(new Runnable() {
public void run() {
assertEquals(2, 5);
}
});
t.start();
t.join();
}


My is green and I expect, it should be red, because in my world, two does not equal to five.

How to fix it? You need to catch the exception or error in your user thread and forward it to JUnit normal thread. For example in this way.


private volatile Exception eException = null;
private volatile Error eError = null;

public void testEquals() throws InterruptedException {
final Thread t = new Thread(new Runnable() {
public void run() {
try {
assertEquals(3, 5);
} catch (Exception e) {
eException = e;
} catch (Error e) {
eError = e;
}
}
});
t.start();
t.join();
}

protected void tearDown() throws Exception {
if (eException != null) throw eException;
if (eError !=null) throw eError;
}

protected void setUp() throws Exception {
eException = null;
eError = null;
}