How can I test a blocking method using junit - java

I have a class with a method that blocks and would like to validate that it is blocking. The method is as shown below.
public static void main(String[] args) {
// the main routine is only here so I can also run the app from the command line
applicationLauncherInstance.initialize();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
if (null != application) {
applicationLauncherInstance.terminate();
}
}
});
try {
_latch.await();
} catch (InterruptedException e) {
log.warn(" main : ", e);
}
System.exit(0);
}
How can I write a unit test for such a method. I am stuck before starting.
public class ApplicationLauncherTest extends TestCase {
public void testMain() throws Exception {
ApplicationLauncher launcher = new ApplicationLauncher();
}
}

Thanks to Kulu, I found the solution.
public void testMain() throws Exception {
Thread mainRunner = new Thread(() -> {
ApplicationLauncher.main(new String[]{});
});
mainRunner.start();
Thread.sleep(5000);
assertEquals(Thread.State.WAITING, mainRunner.getState());
mainRunner.interrupt();
}

Bwire's answer is a good way there, but I highly recommend that no
one ever use Thread.sleep() in unit tests for validation of some situation. It's impossible to get the timing right:
If it's too short, you'll get a lotta false results (random failures, yay)
If it's too long, you end up creating painfully slow tests over time. Don't underestimate this.
So, what's the answer? Any time you need to "sleep" to test something, instead "wait" for that to be true (constantly checking). This way:
As soon as the condition is true, your program resumes--no wasted time.
You can set the timeout on this "wait" to a crazy large value, to avoid random failures.
Here's a modified version of Bware's self-response...
public void testMain() throws Exception {
Thread mainRunner = new Thread(() -> {
ApplicationLauncher.main(new String[]{});
});
mainRunner.start();
expectToBlock(mainRunner, 30, TimeUnit.SECONDS);
mainRunner.interrupt();
}
private static void expectToBlock(Thread thread, long waitCount, TimeUnit waitUnits) {
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < waitUnits.toMillis(waitCount)) {
if (thread.getState() == Thread.State.WAITING) {
return;
}
Thread.sleep(50); // Don't hog the CPU
}
Assert.fail("Timed out while waiting for thread to block");
}

Related

How to return from JUnit test to main method if part of test takes too long

I try to run junit from my main() method:
public static void main(String... args) throws ClassNotFoundException,
IOException {
//...
logger.debug("className " + className + "methodName " + methodName);
Request request = Request.method(Class.forName(className), methodName);
return new JUnitCore().run(request);
}
I have an E2E test with 10 commands (say). It is run by JUnit and I want to limit the run time of commands 3-5 to X millis (where X is determined at run time). If it runs longer than X I want to return to the main() and print something.
I have tried System.exit() but it closes the whole application. I tried:
public void setTimeOut(String criticalBlockTimeOutMilli) {
if (criticalBlockTimeOutMilli != null) {
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
E2eResult e2eResult = E2eResult.getInstance();
e2eResult.status = E2eStatus.TIMEOUT;
//System.exit(2);
}
};
new Timer().schedule(timerTask, Long.parseLong(criticalBlockTimeOutMilli));
}
}
public void setTimeOut(final Thread thread, String criticalBlockTimeOutMilli) {
if (criticalBlockTimeOutMilli != null) {
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
E2eResult e2eResult = E2eResult.getInstance();
e2eResult.status = E2eStatus.TIMEOUT;
thread.interrupt();
}
};
new Timer().schedule(timerTask, Long.parseLong(criticalBlockTimeOutMilli));
}
}
but the main thread continues to run the test even if exceeds the limit. What would you suggest?
Unit testing might not be the best approach to solving this sort of performance testing. However, if there's some reason this must be done, read on...
Use an ExecutorService to run the commands you want, with a given timeout. If the timeout expires, throw your own exception that you can catch in your main thread:
#Test
public void yourTest() throws Exception {
// Do commands 1-2
ExecutorService service = Executors.newSingleThreadExecutor();
Future<Void> result = service.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
// call commands 3-5
return null;
}
});
try {
result.get(42, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
throw new YourOwnException();
}
service.shutdown();
// Do commands 6-10
}
One fairly simple mechanism is to use a BlockingQueue to indicate that the test completed. If you find it didn't you can then interrupt it. This will only work if the test correctly responds to being interrupted.
// Send FINISHED down this queue when test completes.
final BlockingQueue<Object> finished = new ArrayBlockingQueue<>(1);
// FINISHED cookie.
static final Object FINISHED = new Object();
public void test() throws InterruptedException {
Thread test = new Thread(new Runnable() {
#Override
public void run() {
// Do your stuff.
// ...
// Signal we finished.
finished.add(FINISHED);
}
});
// Start the test in it's own thread.
test.start();
try {
// Wait for your time.
if (FINISHED == finished.poll(5, TimeUnit.MILLISECONDS)) {
// It completed! No problems.
} else {
// It hasn't finished! Interrupt it.
test.interrupt();
};
} catch (InterruptedException ex) {
// We were interrupted! Do something.
test.interrupt();
// Rethrow it.
throw(ex);
}
}
You can extend this mechanism by adding a "Started" message too so you can ensure that the test thread gets at least a chance to run.

Java - is it possible to find thread with name and cast it to class?

I have some problem with java.
for Example,
public class Test implements Runnable{
Thread thread;
public Test() throws Exception{
thread = new Thread(this);
thread.setName(getClass().getName() + thread.getId());
thread.start();
}
public void run() {
System.out.println("start");
try {
while(!thread.isInterrupted())
Thread.sleep(Long.MAX_VALUE);
}
catch(InterruptedException ie) {
System.out.println("interrupted");
}
System.out.println("stop");
}
public void stop() {
thread.interrupt();
}
}
this code now is infinite sleep status.
then, I find this thread by name in another Java code (something like this way - http://www.ehow.com/how_7467934_java-thread-runtime.html)
I casted "found thread" to Test class
Test test = (Test)Found Thread;
finally,
test.stop();
work!
I want to find and stop this thread in the other application (absolutely not same)
I`m not familiar with Java, also this like code way will not work in C++ or others as I know.
Is my code in sense? no problem? I worry about...
please advise me. thanx a lot.
(I`m not good at english. sorry)
There is no problem in your code! Everything is just perfect. You may omit checking interrupted status of thread in sleep loop, because once thread is interrupted, it will going to throw that exception when it tries to sleep or wait.
public class Test implements Runnable {
Thread thread;
public Test() throws Exception {
thread = new Thread(this);
thread.setName(getClass().getName() + thread.getId());
thread.start();
}
public void run() {
System.out.println("start");
try {
while (true) {
Thread.sleep(Long.MAX_VALUE);
}
} catch (InterruptedException ie) {
System.out.println("interrupted");
}
System.out.println("stop");
}
public void stop() {
thread.interrupt();
}
public static void main(String [] args) throws Exception{
Test t = new Test();
t.stop();
}
}

Java Multithreading doesn't seem to be correctly working

I have a class which processes something. I'm trying to run a number of instances of this class in parallel.
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping. So I'd like to know if I'm doing something wrong?
This is the structure of the class:
public class TaskRunner implements Runnable {
private boolean isRunning = false;
public void run() {
while(true) {
while (! running) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
process();
}
}
public void go() {
isRunning = true;
}
public void stop() {
isRunning = false;
}
private void process() {
//Do some number crunching and processing here
}
}
Here's how these are being run / managed:
public class TaskManager {
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager() {
for (int i = 0; i < 10; i++) {
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
}
public void startAll() {
for (TaskRunner r : runners) {
r.go();
}
}
}
Indeed, you are not "doing it right." If you want to create a multi-threaded Java application, the place to start is with the java.util.concurrent package.
It appears from your code that you want to run ten tasks in parallel. I assume that after "number crunching and processing," you'll want to aggregate the results and do something with them in the main thread. For this, the invokeAll() method of ExecutorService works well.
First, implement Callable to do the work you show in your process() method.
final class YourTask implements Callable<YourResults> {
private final YourInput input;
YourTask(YourInput input) {
this.input = input;
}
#Override
public YourResults call()
throws Exception
{
/* Do some number crunching and processing here. */
return new YourResults(...);
}
}
Then create your tasks and run them. This would take the place of your main() method:
Collection<Callable<YourResults>> tasks = new List<>(inputs.size());
for (YourInput i : inputs)
tasks.add(new YourTask(i));
ExecutorService workers = Executors.newFixedThreadPool(10);
/* The next call blocks while the worker threads complete all tasks. */
List<Future<YourResult>> results = workers.invokeAll(tasks);
workers.shutdown();
for (Future<YourResult> f : results) {
YourResult r = f.get();
/* Do whatever it is you do with the results. */
...
}
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
So my first comment is that you should make isRunning be volatile since it is being shared between threads. If the threads are not starting when it goes to true (or seem to be delayed in starting) then I suspect that's your problem. volatile provides memory synchronization between the threads so the thread that calls go() and makes a change to isRunning will be seen immediately by the thread waiting for the change.
Instead of spinning like this, I would use wait/notify:
// this synchronizes on the instance of `TaskRunner`
synchronized (this) {
// always do your wait in a while loop to protect against spurious wakeups
while (!isRunning && !Thread.currentThread().isInterrupted()) {
try {
// wait until the notify is called on this object
this.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
Then in the go() method you should do the following. stop() would be similar.
public void go() {
synchronized (this) {
isRunning = true;
this.notifyAll();
}
}
Notice that you should handle thread interrupts carefully. Test for isInterrupted() in the while running loop and re-interrupt a thread when InterruptedException is thrown is always a good pattern.
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping.
So although the threads are mostly sleeping, they are still each looping 1000 times a second because of your Thread.sleep(1). If you increased the time sleeping (after making isRunning be volatile) they would loop less but the right mechanism is to use the wait/notify to signal the thread.
Awful solution, terrible. first I highly recommend you start reading some tutorial like [this]
Second, if threads should wait for a signal to go for some job, so why just don't you wait them!!!!!, something like this
import java.util.ArrayList;
public class TaskManager
{
//////////////////////
public volatile static Signal wait=new Signal();
//////////////////////
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager()
{
for (int i = 0; i < 10; i++)
{
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
try {
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
pauseAll();
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
haltAll();System.out.println("DONE!");
}catch(Exception ex){}
}
public void startAll()
{
synchronized(wait){
wait.setRun(true);;
wait.notifyAll();
}
}
public void pauseAll(){
wait.setRun(false);
}
public void haltAll(){
for(TaskRunner tx:runners){tx.halt();}
}
public static void main(String[] args) {
new TaskManager();
}
}
class TaskRunner implements Runnable
{
private Thread thisThread;
private volatile boolean run=true;
public void run()
{
thisThread=Thread.currentThread();
while(run){
if(!TaskManager.wait.isRun()){
synchronized(TaskManager.wait)
{
if(!TaskManager.wait.isRun()){
System.out.println("Wait!...");
try
{
TaskManager.wait.wait();
}
catch (Exception e)
{
e.printStackTrace();
break;
}
}
}}
process();
}
}
private double r=Math.random();
private void process(){System.out.println(r);try {
Thread.sleep(10);
} catch (Exception e) {
// TODO: handle exception
}}
public void halt(){run=false;thisThread.interrupt();}
}
class Signal{
private boolean run=false;
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
in above sample, all runners works till the Signal run boolean is true, and simple TaskManager class set tit as false for every time it needs to pause the threads. and about the halt, it just set the shutdown(run) flag to false, and also interrupt the thread because of if thread is in wait state.
I hope I could prove your solution is like dream-on story, and also could explained enough about my solution.
have a good parallel application :)

Lightweight long-running method cancel pattern for Java

Is there a lightweight pattern to cancel long running method, which replaces code like this:
public void longComputations() {
... first step...
if ( cancelled ) {
rollbackWork();
return;
}
... second step...
if ( cancelled ) {
rollbackWork();
return;
}
... third step...
if ( cancelled ) {
rollbackWork();
return;
}
}
I know that I can make a Task class, subdivide steps to task objects, make a queue and just do tasks step by steps in loop with cancelation checking, but I'm just wondering is there any simple code-structure pattern for such situation.
I am not aware of such a mechanism. Since you have to track your work in order to be able to perform rollbackWork(), a well-designed object-oriented solution is your best choice anyway, if you want to further evolve this logic! Typically, such a scenario could be implemented using the command pattern, which I still find pretty lightweight:
// Task or Command
public interface Command {
void redo();
void undo();
}
A scheduler or queue could then take care of executing such task / command implementations, and of rolling them back in order.
How about this edit, not a pattern though? Exceptions are very cheap, so it should be fast.
public void caller(){
try{
longComputations();
} catch (MeaningfulRuntimeException e){
rollbackWork(e.getStep());
}
}
public void longComputations() {
... first step...
checkStatus(1);
... second step...
checkStatus(2);
... third step...
checkStatus(3);
}
public void checkStatus(int step){
if ( cancelled ) {
... we may rollback here or throw an exception ...
throw MeaningfulRuntimeException(step);
}
}
If the steps call methods which throw InterruptedException then you can use Thread.interrupt(). You will still need to maintain enough state information to do the rollback properly.
If the steps cannot be interrupted this way, you should not consider relying on the deprecated Thread.stop() mechanism since it is inherently unsafe.
It seems that either way it makes sense to do exactly what you described: encapsulate this workflow logic in a class independent of the computation steps. It should support cancellation and/or interruption and accept a bunch of tasks to be executed. Note that the tasks to be fed into the workflow should provide at least two methods: one to perform the computation and one to roll it back.
You might want to consider using the java.util.concurrent package. You need to wrap your working steps as Callables (or Runnables).
public class InterruptibleTest {
public static void main(String[] args) { try {
final ExecutorService queue = Executors.newFixedThreadPool(1);
queue.submit(new Callable<Void>() { #Override public Void call() { busyWait(1000); return null; } });
queue.submit(new Callable<Void>() { #Override public Void call() { busyWait(1000); return null; } });
queue.submit(new Callable<Void>() { #Override public Void call() { busyWait(1000); return null; } });
final AtomicBoolean cancelled = new AtomicBoolean();
new Thread() { #Override public void run() {
try { Thread.sleep(1500); } catch (InterruptedException ex) { }
queue.shutdownNow();
cancelled.set(true);
}
}.run();
if (cancelled.get()) { rollback(); }
queue.shutdown();
System.out.println("Finished");
} catch (Exception ex) { ex.printStackTrace(System.err); } }
public synchronized static void busyWait(int millis) {
System.out.println("Start");
long until = System.currentTimeMillis() + millis;
while (System.currentTimeMillis() < until) { }
System.out.println("Stopped");
}
public synchronized static void rollback() {
System.out.println("Rollback!");
}
}
Note that shutdownNow() might call interrupt() on the currently executing work thread. You will probably also need to synchronize your rollback() because shutdownNow() returns before non-interruptible code finishes execution.

How do I call some blocking method with a timeout in Java?

Is there a standard nice way to call a blocking method with a timeout in Java? I want to be able to do:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
if that makes sense.
Thanks.
You could use an Executor:
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
return something.blockingMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
future.cancel(true); // may or may not desire this
}
If the future.get doesn't return in 5 seconds, it throws a TimeoutException. The timeout can be configured in seconds, minutes, milliseconds or any unit available as a constant in TimeUnit.
See the JavaDoc for more detail.
You could wrap the call in a FutureTask and use the timeout version of get().
See http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
See also Guava's TimeLimiter which uses an Executor behind the scenes.
It's really great that people try to implement this in so many ways. But the truth is, there is NO way.
Most developers would try to put the blocking call in a different thread and have a future or some timer. BUT there is no way in Java to stop a thread externally, let alone a few very specific cases like the Thread.sleep() and Lock.lockInterruptibly() methods that explicitly handle thread interruption.
So really you have only 3 generic options:
Put your blocking call on a new thread and if the time expires you just move on, leaving that thread hanging. In that case you should make sure the thread is set to be a Daemon thread. This way the thread will not stop your application from terminating.
Use non blocking Java APIs. So for network for example, use NIO2 and use the non blocking methods. For reading from the console use Scanner.hasNext() before blocking etc.
If your blocking call is not an IO, but your logic, then you can repeatedly check for Thread.isInterrupted() to check if it was interrupted externally, and have another thread call thread.interrupt() on the blocking thread
This course about concurrency https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
really walks through those fundamentals if you really want to understand how it works in Java. It actually talks about those specific limitations and scenarios, and how to go about them in one of the lectures.
I personally try to program without using blocking calls as much as possible. There are toolkits like Vert.x for example that make it really easy and performant to do IO and no IO operations asynchronously and in a non blocking way.
I hope it helps
There is also an AspectJ solution for that with jcabi-aspects library.
#Timeable(limit = 30, unit = TimeUnit.MINUTES)
public Soup cookSoup() {
// Cook soup, but for no more than 30 minutes (throw and exception if it takes any longer
}
It can't get more succinct, but you have to depend on AspectJ and introduce it in your build lifecycle, of course.
There is an article explaining it further: Limit Java Method Execution Time
I'm giving you here the complete code. In place of the method I'm calling, you can use your method:
public class NewTimeout {
public String simpleMethod() {
return "simple method";
}
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException {
Thread.sleep(1100);
return new NewTimeout().simpleMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(1, TimeUnit.SECONDS);
System.out.println(result);
} catch (TimeoutException ex) {
System.out.println("Timeout............Timeout...........");
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
executor.shutdown(); // may or may not desire this
}
}
}
Thread thread = new Thread(new Runnable() {
public void run() {
something.blockingMethod();
}
});
thread.start();
thread.join(2000);
if (thread.isAlive()) {
thread.stop();
}
Note, that stop is deprecated, better alternative is to set some volatile boolean flag, inside blockingMethod() check it and exit, like this:
import org.junit.*;
import java.util.*;
import junit.framework.TestCase;
public class ThreadTest extends TestCase {
static class Something implements Runnable {
private volatile boolean stopRequested;
private final int steps;
private final long waitPerStep;
public Something(int steps, long waitPerStep) {
this.steps = steps;
this.waitPerStep = waitPerStep;
}
#Override
public void run() {
blockingMethod();
}
public void blockingMethod() {
try {
for (int i = 0; i < steps && !stopRequested; i++) {
doALittleBit();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void doALittleBit() throws InterruptedException {
Thread.sleep(waitPerStep);
}
public void setStopRequested(boolean stopRequested) {
this.stopRequested = stopRequested;
}
}
#Test
public void test() throws InterruptedException {
final Something somethingRunnable = new Something(5, 1000);
Thread thread = new Thread(somethingRunnable);
thread.start();
thread.join(2000);
if (thread.isAlive()) {
somethingRunnable.setStopRequested(true);
thread.join(2000);
assertFalse(thread.isAlive());
} else {
fail("Exptected to be alive (5 * 1000 > 2000)");
}
}
}
You need a circuit breaker implementation like the one present in the failsafe project on GitHub.
Try this. More simple solution. Guarantees that if block didn't execute within the time limit. the process will terminate and throws an exception.
public class TimeoutBlock {
private final long timeoutMilliSeconds;
private long timeoutInteval=100;
public TimeoutBlock(long timeoutMilliSeconds){
this.timeoutMilliSeconds=timeoutMilliSeconds;
}
public void addBlock(Runnable runnable) throws Throwable{
long collectIntervals=0;
Thread timeoutWorker=new Thread(runnable);
timeoutWorker.start();
do{
if(collectIntervals>=this.timeoutMilliSeconds){
timeoutWorker.stop();
throw new Exception("<<<<<<<<<<****>>>>>>>>>>> Timeout Block Execution Time Exceeded In "+timeoutMilliSeconds+" Milli Seconds. Thread Block Terminated.");
}
collectIntervals+=timeoutInteval;
Thread.sleep(timeoutInteval);
}while(timeoutWorker.isAlive());
System.out.println("<<<<<<<<<<####>>>>>>>>>>> Timeout Block Executed Within "+collectIntervals+" Milli Seconds.");
}
/**
* #return the timeoutInteval
*/
public long getTimeoutInteval() {
return timeoutInteval;
}
/**
* #param timeoutInteval the timeoutInteval to set
*/
public void setTimeoutInteval(long timeoutInteval) {
this.timeoutInteval = timeoutInteval;
}
}
example :
try {
TimeoutBlock timeoutBlock = new TimeoutBlock(10 * 60 * 1000);//set timeout in milliseconds
Runnable block=new Runnable() {
#Override
public void run() {
//TO DO write block of code
}
};
timeoutBlock.addBlock(block);// execute the runnable block
} catch (Throwable e) {
//catch the exception here . Which is block didn't execute within the time limit
}
In special case of a blocking queue:
Generic java.util.concurrent.SynchronousQueue has a poll method with timeout parameter.
Assume blockingMethod just sleep for some millis:
public void blockingMethod(Object input) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
My solution is to use wait() and synchronized like this:
public void blockingMethod(final Object input, long millis) {
final Object lock = new Object();
new Thread(new Runnable() {
#Override
public void run() {
blockingMethod(input);
synchronized (lock) {
lock.notify();
}
}
}).start();
synchronized (lock) {
try {
// Wait for specific millis and release the lock.
// If blockingMethod is done during waiting time, it will wake
// me up and give me the lock, and I will finish directly.
// Otherwise, when the waiting time is over and the
// blockingMethod is still
// running, I will reacquire the lock and finish.
lock.wait(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So u can replace
something.blockingMethod(input)
to
something.blockingMethod(input, 2000)
Hope it helps.

Categories