Closed kurbatov closed 4 years ago
Thanks for the quick update, changes look good as far as I see.
BTW, I use something like the following in an abstract base class for all tests to verify that no unexpected threads leak anywhere:
@Before
public void setUp() throws InterruptedException {
waitForThreads();
}
@After
public void tearDownBase() throws InterruptedException {
waitForThreads();
}
protected void waitForThreads() throws InterruptedException {
// ensure that none of our threads are left running during shutdown
waitForThreadToFinishSubstring("Scheduler");
waitForThreadToFinishSubstring("qtp");
waitForThreadToFinishSubstring("firmata");
waitForThreadToFinishSubstring("EventThread");
}
private void waitForThreadToFinishSubstring(String contains) throws InterruptedException {
waitForThreadToFinishSubstring(contains, 10_000);
assertNoThreadLeft("Thread which contains '" + contains + "' was still running after 10 seconds", contains);
}
public static void assertNoThreadLeft(final String error, final String startsWith) {
int count = Thread.currentThread().getThreadGroup().activeCount();
Thread[] threads = new Thread[count];
Thread.currentThread().getThreadGroup().enumerate(threads);
for (Thread t : threads) {
if (t != null && t.getName().startsWith(startsWith)) {
// first take a thread-dump to report the state before we stop threads
final String dump = new ThreadDump(true, true).toString();
// try to stop the thread to make other tests succeed again afterwards
AbstractPipedModule.stopThread(t.getName());
log.severe("ThreadDump: " + dump);
// report the problem:
fail(error + ": " + t);
}
}
}
public static void waitForThreadToFinishSubstring(final String name, final long timeout) throws InterruptedException {
int count = Thread.currentThread().getThreadGroup().activeCount();
Thread[] threads = new Thread[count];
Thread.currentThread().getThreadGroup().enumerate(threads);
for (Thread t : threads) {
if (t != null && t.getName().contains(name)) {
t.join(timeout);
}
}
}
Fixes #38