/* * A CCNx library test. * * Copyright (C) 2011, 2013 Palo Alto Research Center, Inc. * * This work is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. * This work is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ package org.ccnx.ccn.test; /** * Junit cannot catch exceptions from spawned threads. This wrapper class * will catch assertion failures in a Runnable and report them to the caller. * * Junit Assert.X method throw an AssertionError, which is a Throwable -> Error -> AssertionError. * So, we capture both an Error and an Exception. Don't use Throwable, as those get * messy to handle in the caller. * * How to use: * 1) Create a Runnable class (could even be anonymous inner class), and wrap it in a * ThreadAssertionRunner: * * ThreadAssertionRunner tar = new ThreadAssertionRunner(new MyRunner(some_parameter)); * * 2) Start the Runner like a thread: * * tar.start(); * * 3) Do normal processing, then stop your runnable. You must join the Runner to wait for exit. * THIS STEP IS REQUIRED (it's the join that reports any exceptions or errors from the run() * method of your runnable): * * tar.join(); * */ public class ThreadAssertionRunner { public ThreadAssertionRunner(final Runnable runner) { // Create our own thread to run runner in, and just call its run() method _thd = new Thread(new Runnable() { public void run() { try { runner.run(); } catch(Error error) { _error = error; } catch(Exception exception) { _exception = exception; } } }); } public void start() { _thd.start(); } public void join() throws InterruptedException, Error, Exception { _thd.join(); if( _error != null ) throw _error; if( _exception != null ) throw _exception; } public void join(long millis) throws InterruptedException, Error, Exception { _thd.join(millis); if( _error != null ) throw _error; if( _exception != null ) throw _exception; } public boolean isAlive() { return _thd.isAlive(); } // ============= private Thread _thd = null; private volatile Error _error = null; private volatile Exception _exception = null; }