blob: 4337c3d6f98b4a9459d36742e53d09def19957c0 [file] [log] [blame]
/*
* Copyright (c) 2010 Olivier Girardot
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Olivier Girardot - initial contribution
*/
package org.eclipse.virgo.nano.core;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Vector;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
/**
* This class is for testing the {@link Signal} implementation {@link BlockingSignal}.
*
*/
public final class BlockingSignalTests {
@Test
public void signalCompletionAfterNoFailure() throws Throwable {
final BlockingSignal signal = new BlockingSignal();
ExceptionCatcherThread testThread = new ExceptionCatcherThread(new Runnable(){
public void run() {
try {
// awaiting for signal completion flag
boolean returnSignal =
signal.awaitCompletion(1000, TimeUnit.SECONDS);
assertTrue(returnSignal);
} catch (FailureSignalledException e) {
// this code should not be reached
fail();
}
}
});
testThread.start();
signal.signalSuccessfulCompletion();
testThread.join(10);
assertFalse("Test thread still alive after delay.", testThread.isAlive());
testThread.rethrowUncaughtExceptions();
}
@Test
public void signalCompletionFailsAfterWaitingExceeded() throws Throwable {
final BlockingSignal signal = new BlockingSignal();
ExceptionCatcherThread testThread = new ExceptionCatcherThread(new Runnable(){
public void run() {
try {
// awaiting for signal completion flag
boolean returnSignal =
signal.awaitCompletion(1, TimeUnit.MILLISECONDS);
assertFalse(returnSignal);
} catch (FailureSignalledException e) {
// this code should not be reached
fail();
}
}
});
testThread.start();
Thread.sleep(100);
signal.signalSuccessfulCompletion();
testThread.join(10);
assertFalse("Test thread still alive after delay.", testThread.isAlive());
testThread.rethrowUncaughtExceptions();
}
@Test
public void signalCompletionFailsAfterFailureNotifiedToSignal() throws Throwable {
final BlockingSignal signal = new BlockingSignal();
final Throwable dummyEx = new Exception("Dummy cause");
ExceptionCatcherThread testThread = new ExceptionCatcherThread(new Runnable(){
public void run() {
try {
// awaiting for signal completion flag (not storing result, as the code should fail)
signal.awaitCompletion(1, TimeUnit.SECONDS);
// this code should not be reached
// an exception being sent before
fail();
} catch (FailureSignalledException e) {
// We'll check that we actually refer to the correct cause
assertSame("Signal failure has incorrect cause.", dummyEx, e.getCause());
}
}
});
testThread.start();
signal.signalFailure(dummyEx);
testThread.join(10);
assertFalse("Test thread still alive after delay.", testThread.isAlive());
testThread.rethrowUncaughtExceptions();
}
/**
* Special thread designed to record uncaught exceptions
* and re-throw the first of them on demand.
*/
private class ExceptionCatcherThread extends Thread{
private final Vector<Throwable> uncaughtExceptions = new Vector<Throwable>();
public ExceptionCatcherThread(Runnable r) {
super(r);
this.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
uncaughtExceptions.add(e);
}
});
}
public void rethrowUncaughtExceptions() throws Throwable {
if (!uncaughtExceptions.isEmpty())
throw uncaughtExceptions.firstElement();
}
}
}