Elegant solution for JUnit testing of run method in Thread implementation - java

I have a class that extends from Thread and want to JUnit test it. At this point I don't want to test for thread-safety, but to merely check whether the implementation logic works fine. My problem is that the run method iterates indefinitely, e.g.:
public void run() {
while (status.isRunning()) {
// do stuff & sleep
}
}
For the purposes of my test, I only want to iterate over the logic in the run method once. The best I came up with to tackle this problem, is a Mockito mock object that uses a static counter and an anonymous implementation of Answer:
private static int counter = 0;
Status status = mock(Status.class);
when(status.isRunning()).thenAnswer(new Answer<Boolean>() {
public Boolean answer(InvocationOnMock invocation) throws Throwable {
if (counter == 0) {
counter++;
return Boolean.TRUE;
}
return Boolean.FALSE;
}
});
I am not sure, whether this solution is the best there is. It seems a bit long-winded for a use case that common.
Can anybody think of a simpler, more elegant solution to the problem?

You don't need to do anything magical, just provide more than one "answer" in the "thenReturn" method, for example...
when(status.isRunning()).thenReturn(true, false);

Related

Run method when multiple conditions fulfilled

I'm currently creating a java programm where I want to run a method, after two conditions are fulfilled. So right when both conditions are occuring, the method should be called. The only way I can think of handling it is as I added it below, but it doesn't seem like the optimal way to do so.
Here no matter if method1 or method2 is called first, the following method is checking if the other condition is already fulfilledand then runs the method. Since there might be methods that depend on more conditions then two, are there more clearer way to handle it?
My example:
public class Test() {
private boolean condition1 = false;
private boolean condition2 = false;
public void method1(){
condition1 = true;
if(condition2){
run();
}
}
public void method2(){
condition2 = true;
if(condition1){
run();
}
}
public void run(){
//Is run when both conditions are true
}
}
Since there might be methods that depend on more conditions then two
As per the statement above I guess I can assume you might have more than two conditions, and perhaps multiple combinations? In that case you wouldn't want to verify the conditions in your run method.
You could have a dedicated method applying the required conditions as needed, something like this:
public void runIfTheConditionsAreMet() {
if(condition1 && condition2) {
run();
}
}
This way you would have a dedicated method to check for the conditions and call your run method only when necessary, without repeating code in your method1, method2, and you would have a place you could document the conditions (if necessary).
Your code would look a little bit cleaner, as below:
public void method1(){
condition1 = true;
runIfTheConditionsAreMet();
}
public void method2(){
condition2 = true;
runIfTheConditionsAreMet();
}
Ps. Even if you don't intend to have more conditions I think this solution would fit your needs.
If I were to open up this code, and have to understand it, I would have a much easier time if I saw something more like this:
public void run(){
if(condition1 && condition2){
// Now run the important code
}
}
Whatever calls were made to method1 and method2 before would be changed to calls to run(). This seems much more intuitive to me, instead of spreading the check out between two methods, either one of which may execute run().
Take a look at CountDownLatch.

Why is it "dangerous" to synchronize on method parameter

My IDE (JetBrains IntelliJ IDEA) warns me about synchronizing on a method parameter even when it's always an object.
The full warning reads:
Synchronization on method parameter 's' ... Inspection
info: Reports synchronization on a local variable or parameter. It is
very difficult to guarantee correctness when such synchronization is
used. It may be possible to improve code like this by controlling
access through e.g. a synchronized wrapper class, or by synchronizing
on a field.
My guess is that with auto-boxing, the parameter might be a primitive which gets converted to an object? Although, with auto-boxing, I would assume it's always an object, but maybe not a shared object which means it wouldn't be shared synchronization.
Anyone know why the warning would be present? In my case ShortCircuit type is always an object and the IDE should be able to know that.
The thing is that if you forget to synchronize on ShortCircuit when using it in other places of your code you might get unpredictable results. It's a lot better to synchronize inside the ShortCircuit class so it's guaranteed to be thread safe.
Update
If you're moving the synchronization outside of the class it's inherently unsafe for threading. If you want to synchronize on it externally you will have to audit all places it's used, that's why you get the warning. It's all about good encapsulation. It will be even worse if it is in a public API.
Now if you move the fireFinalCallback method to your ShortCircuit class you can guarantee that the callback won't fire simultaneously. Otherwise you need to have this in mind when calling the methods on that class.
As jontro already mentioned in his answer (and basically, as the warning already says) : This sort of synchronization on the ShortCircuit object does not have the effect that the developer probably hoped to achieve. Unfortunately, the tooltip in your screenshot hides the actual code, but it seems like the code could roughly be
synchronized (s)
{
if (!s.isFinalCallbackFired())
{
s.doFire();
}
}
That is: It is first checked whether isFinalCallbackFired returns false, and if this is the case, something (hidden) is done, which likely causes the isFinalCallbackFired state to switch to true.
So my assumption is, roughly, that the goal of putting the if statement into the synchronized block was to make sure that doFire is always called exactly once.
And indeed, at this point, the synchronization could be justified. More specifically, and a bit oversimplified:
What can be guaranteed:
When two threads are executing the fireFinalCallback method with the same ShortCircuit parameter, the synchronized block will guarantee that only one thread at a time can check the isFinalCallbackFired state and (if it is false) call the doFire method. So it is guaranteed that doFire will be called only once.
What can not be guaranteed:
When one thread is executing the fireFinalCallback method, and another thread does any operation on the ShortCircuit object (like calling doFire), then this might lead to an inconsistent state. Particularly, if another thread also does
if (!s.isFinalCallbackFired())
{
s.doFire();
}
but without synchronizing on the object, then doFire may be called twice.
The following is an MCVE that illustrates the effect:
public class SynchronizeOnParameter
{
public static void main(String[] args)
{
System.out.println("Running test without synchronization:");
runWithoutSync();
System.out.println();
System.out.println("Running test with synchronization:");
runWithSync();
System.out.println();
System.out.println("Running test with wrong synchronization:");
runWithSyncWrong();
System.out.println();
}
private static void runWithoutSync()
{
ShortCircuit s = new ShortCircuit();
new Thread(() -> fireFinalCallbackWithoutSync(s)).start();
pause(250);
new Thread(() -> fireFinalCallbackWithoutSync(s)).start();
pause(1000);
}
private static void runWithSync()
{
ShortCircuit s = new ShortCircuit();
new Thread(() -> fireFinalCallbackWithSync(s)).start();
pause(250);
new Thread(() -> fireFinalCallbackWithSync(s)).start();
pause(1000);
}
private static void runWithSyncWrong()
{
ShortCircuit s = new ShortCircuit();
new Thread(() -> fireFinalCallbackWithSync(s)).start();
if (!s.isFinalCallbackFired())
{
s.doFire();
}
}
private static void fireFinalCallbackWithoutSync(ShortCircuit s)
{
if (!s.isFinalCallbackFired())
{
s.doFire();
}
}
private static void fireFinalCallbackWithSync(ShortCircuit s)
{
synchronized (s)
{
if (!s.isFinalCallbackFired())
{
s.doFire();
}
}
}
static class ShortCircuit
{
private boolean fired = false;
boolean isFinalCallbackFired()
{
return fired;
}
void doFire()
{
System.out.println("Calling doFire");
pause(500);
fired = true;
}
}
private static void pause(long ms)
{
try
{
Thread.sleep(ms);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
The output is
Running test without synchronization:
Calling doFire
Calling doFire
Running test with synchronization:
Calling doFire
Running test with wrong synchronization:
Calling doFire
Calling doFire
So the synchonized block does make sure that the doFire method is only called once. But this only works if all modifications are only done in the fureFinalCallback method. If the object is modified elsewhere, without a synchronized block, the doFire method may be called twice.
(I'd like to offer a solution for this, but without details about the ShortCircuit class and the remaining classes and processes, one could only give the vague hint to have a look at the java.util.concurrent package and its subpackages: Locks and Conditions might be a viable path, but you have to figure that out...)

Unit test the thread safety of a singleton class in Java?

Let's imagine I have the following java class :
static class Singleton {
static Singleton i;
static Singleton getInstance() {
if (i == null) {
i = new Singleton();
}
return i;
}
}
Now, we all know this will work, but - it apparently is not thread safe - I am not actually trying to fix the thread safety - this is more of a demo, my other class is identical, but uses a mutex and synchronization - the unit test will be ran against each to show that one is thread safe, and the other, is not. What might the unit test which would fail if getInstance is not thread safe look like?
Well, race conditions are by nature probabilistic so there's no deterministic way to truly generate a race condition. Any possible way against your current code would need to be run many times until the desired outcome is achieved. You can enforce a loose ordering of access on i by making a mock singleton to test against to simulate what a certain condition might look like, though. Rule of thumb with synchronization is preventative measures beat trying to test and figure out what's wrong after bad code is mangled in a code base.
static class Singleton {
static Singleton i;
static Singleton getInstance(int tid) {
if (i == null) {
if (tid % 2 == 0) i = new Singleton()
}
return i;
}
}
So certain threads will write to i and other threads will read i as if they reached "return i" before "the even thread id's were able to check and initialize i" (sort of, not exactly, but it simulates the behavior). Still, there's a race between the even threads in this case because the even threads may still write to i after another reads null. To improve, you'd need to implement thread safety to force the condition where one thread reads i, gets null, while the other thread sets i to new Singleton() a thread-unsafe condition. But at that point you're better off just solving the underlying issue (just make getInstance thread safe!)
TLDR: there are infinitely many race conditions that can occur in a unsafe function call. You can mock the code to generate a mock of a specific race condition (say, between just two threads) but it's not feasible to just blanket test for "race conditions"
This code worked for me.
The trick is that it is probabilistic like said by other users.
So, the approach that should be taken is to run for a number of times.
public class SingletonThreadSafety {
public static final int CONCURRENT_THREADS = 4;
private void single() {
// Allocate an array for the singletons
final Singleton[] singleton = new Singleton[CONCURRENT_THREADS];
// Number of threads remaining
final AtomicInteger count = new AtomicInteger(CONCURRENT_THREADS);
// Create the threads
for(int i=0;i<CONCURRENT_THREADS;i++) {
final int l = i; // Capture this value to enter the inner thread class
new Thread() {
public void run() {
singleton[l] = Singleton.getInstance();
count.decrementAndGet();
}
}.start();
}
// Ensure all threads are done
// The sleep(10) is to be somewhat performant, (if just loop,
// this will be a lot slow. We could use some other threading
// classes better, like CountdownLatch or something.)
try { Thread.sleep(10); } catch(InterruptedException ex) { }
while(count.get() >= 1) {
try { Thread.sleep(10); } catch(InterruptedException ex) { }
}
for( int i=0;i<CONCURRENT_THREADS - 1;i++) {
assertTrue(singleton[i] == singleton[i + 1]);
}
}
#Test
public void test() {
for(int i=0;i<1000;i++) {
Singleton.i = null;
single();
System.out.println(i);
}
}
}
This have to make some change in the Singleton design pattern. That the instance variable is now accessible in the Test class. So that we could reset the Singleton instance available to null again every time the test is repeated, then we repeat the test 1000 times (if you have more time, you could make it more, sometimes finding an odd threading problem require that).
In some cases this solution works. Unfortunately its hard to test singleton to provoke thread unsafe.
#Test
public void checkThreadUnSafeSingleton() throws InterruptedException {
int threadsAmount = 500;
Set<Singleton> singletonSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
ExecutorService executorService = Executors.newFixedThreadPool(threadsAmount);
for (int i = 0; i < threadsAmount; i++) {
executorService.execute(() -> {
Singleton singleton = Singleton.getInstance();
singletonSet.add(singleton);
});
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES);
Assert.assertEquals(2, singletonSet.size());
}

Does making variable volatile get rid of: Multithreaded correctness - Inconsistent synchronization

I'm getting Inconsistent synchronization error on sonar on following code.
public int getMessageCount()
{
return m_messageCount;
}
public void onMessage(XQMessage msg) throws XQServiceException
{
synchronized(this)
{
m_messageCount--;
// add the message to the result
m_messages.add(msg);
if (m_messageCount == 0)
{
// wake up client
finished();
}
}
}
Error is on "return m_messageCount". If i make m_message volatile, will it solve the issue?
#jameslarge Can you give this AtomicInteger suggestion in separate post
I was thinking, something like this:
static final int INITIAL_MESSAGE_COUNT = ...;
AtomicInteger messageCount = new AtomicInteger(INITIAL_MESSAGE_COUNT);
public int getMessageCount()
{
return messageCount.get();
}
public void onMessage(XQMessage msg) throws XQServiceException
{
int mc = messageCount.decrementAndGet();
messages.add(msg);
if (mc == 0) wake_up_client();
}
NOTE: the messages.add() call is inside a synchronized block in your implementation. That is no longer the case in my version. I don't know what messages is exactly, but if you were relying on the synchronized block to protect it, you will have to add synchronization back in. At that point you might as well just go with your original version: AtomicInteger is more complicated than just using a regular int. I don't use it except when it allows me to implement some algorithm without using synchronized blocks.
P.S.; What is supposed to happen if the message count is already zero when onMessage() is called? Can that happen? If it happens, you'll get a negative message count. I don't have enough information to know whether that would be a good thing or a bad thing.
P.P.S.; What about that XQServiceException? Both of our implementations will decrement the message count regardless of whether or not messages.add() throws an exception. That might not be what you want. I don't know.
Since you are using synchronized(this) when you modify m_messageCount you can make the getMessageCount() method synchronized and that will solve your problem.
For example:
public synchronized int getMessageCount(){
return m_messageCount;
}

How can I interrupt a sequence of procedures in Java?

I have a bunch of procedures that need to be executed successively until either they are all executed, or a certain condition is met. Here's the basic code that needs to be executed until a condition is met:
public boolean search()
{
robot.go();
robot.spin();
//etc - around 8 more similar commands (each takes around 2 seconds)
return false; //didn't find what it was looking for
}
So far, the only way that I've thought of doing what I wanted is this:
public boolean search()
{
robot.go(false);
while(robot.isMoving())
{
if(thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
robot.spin(false);
while(robot.isMoving())
{
if(thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
//etc - around 8 more similar commands
return false; //didn't find what it was looking for
}
The false parameter to go() and spin() indicates that they should return immediately, allowing the condition to be checked. However, this approach strikes me as rather inefficient, as the same block of code must be repeated 10 times. Could this be achieved more efficiently with exceptions or concurrent Threads?
Not sure why you are using Thread.yield() - are there other threads executing that you didn't mention? Or maybe I misread the problem.
I think maybe the Command pattern could work here. You would have a RobotCommand interface with an execute method, and an implementation of RobotCommand per command type (go, spin, etc). Then you could construct a RobotAlgorithm as a List of RobotCommand, and have a method executeRobotAlgorithm that iterated over the list, calling execute on each RobotCommand and checking the result of thingFound() after each one.
Edit - oh, I think I get it. Do go and spin kick off threads that change the state of the robot, or something like that?
Edit 2 - in response to your comment, it sounds like the problem here is that you need to be able to return immediately if the robot finds what it's looking for, but the go, spin, etc commands won't do this right now, and you need the ability to keep executing new commands in the meantime. So what I might do here is have two threads - one would be an "executor" thread that would execute your List of RobotCommands one by one, and a "watcher" thread that will repeatedly sleep and poll (check thingFound()). If thingFound() is ever true then you can stop your robot as well as the executor thread, or if the executor gets to the end before thingFound() is true then it can signal as such (if necessary).
Clearly, the while loop can be packaged into its own function:
private boolean isFound()
{
while (robot.isMoving())
{
if (thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
return false;
}
public boolean search()
{
robot.go(false);
if (isFound()) return true;
robot.spin(false);
if (isFound()) return true;
//etc - around 8 more similar commands
return false; //didn't find what it was looking for
}
(I don't mind if the conditional is split over two lines; I'd probably do that in production code.)
A better Java programmer than I can tell you whether you can pass 'procedures' around (pointers to functions, in terms of C programming). I suspect you can, but I don't know the syntax and rules. The evidence seems to be that you can't (circa 2004, anyway).
based on Jonathan Leffler's answer:
you can use a Runnable as pointer to the commands
private final Runnable going = new Runnable() {
#Override
public void run() {
robot.go(false);
}
});
private final Runnable spinning = new Runnable {
#Override
public void run() {
robot.spin(false);
}
});
// other commands
private boolean isFoundAfter(Runnable command)
{
command.run();
while (robot.isMoving())
{
if (thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
return false;
}
public boolean search()
{
if (isFoundAfter(going)) return true;
if (isFoundAfter(spinning)) return true;
//etc - around 8 more similar commands
return false; //didn't find what it was looking for
}
one further step, if appropriate, put the commands in an array or a List and execute it as a script
...
private boolean executeSearch(Runnable... commands)
{
for (Runnable cmd : commands) {
if (isFoundAfter(cmd)) return true;
}
return false; //didn't find what it was looking for
}
public boolean search() {
return executeSearch(going, spinning /* around 8 more similar commands */);
}
robot can use a Condition object to signal to the controller that it's completed some sub-task or entered a new state:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Condition.html
interesting, for the environment that's in you could probably use and notify() and wait() instead of the more flexible Condition. controller could wait() until the robot decides to release him with notify().

Categories

Resources