tempus-fugit

Java micro-library for writing & testing concurrent code

Wait for UI Elements in Tests

When a UI asynchronously updates a value, it can be difficult to make assertions in tests reliably. There are typically two approaches to solving this, either poll the UI until the value matches the assertion (timing out after a certain amount of time) or make the UI notify your test code that a value has changed.

Using the WaitFor class along with Web Driver allows you to do the former with something like this.

Optimise the Number of Threads

Working out the theoretical optimal number of threads you should use for your application is fairly straightforward. You do, however, need to understand your applications runtime characteristics. Is it mostly occupied with CPU intensive work or is it mostly waiting for IO? A good profiler will help you to understand your applications profile.

Avoid JMock Finaliser Problems

The default threading policy for a JMock Mockery warns if the mockery is being used by multiple threads. The SingleThreadedPolicy will output the following.

2012-05-31 07:35:35 ERROR Finalizer [Console$Logger] - the Mockery is not thread-safe: use a Synchroniser to ensure thread safety

If you really need multi-threaded access to the mockery, it’s a straight forward fix to swap the policy out. As in the log line above though, sometimes the JVM’s finaliser thread sticks it’s oar in and confuses the SingleThreadedPolicy.

Timeout in JMock Synchroniser

JMock’s Synchroniser serialises access to the mock object’s “context”, it means all invocations of mocked methods call will be synchronized on the same monitor, effectively forcing them to run in sequence without thread safety concerns. As it uses synchronized though, you can (with some effort) get into trouble with tests that never finish.

If you’re seeing this kind of thing, apart from using the @Test(timeout=1000) annotation, you might consider an alternative ThreadingPolicy implementation using Locks that can timeout and maintain liveliness.

Make JMock Thread Safe

By default, JMock’s “context” is not thread safe. All bets are off if you access the Mockery from multiple threads. Happily, since JMock 2.6.0, you can set a threading policy per mockery.

1
2
3
Mockery mockery = new JUnit4Mockery() {{
  setThreadingPolicy(new Synchroniser());
}};

The Synchroniser forces serialisation of each mocked method call using synchronized. Use it when you’re running multi-threaded style tests using JMock. The default behaviour will warn you if a mockery is being used like this.

the Mockery is not thread-safe: use a Synchroniser to ensure thread safety

Detecting Deadlocks

The DeadlockDetector class allows you to programmatically detect basic deadlocks in your Java code. You can output deadlocks using the following code (note that printing a thread dump using the ThreadDump class will automatically attempt to find any deadlocks).

1
DeadlockDetector.printDeadlocks(System.out);

The DeadlockDecector class will spot Java monitor cyclic locking problems as well as Lock based cyclic problems. It’s implementation is basically the same as that used by jconsole and jstack. The types of deadlock it can detect can be illustrated in the example below.

Testing Concurrent Code

Testing concurrency can be hard. When you fire up threads from within a test, it’s difficult not to introduce concurrency bugs in the test code and be sure you’re actually exercising the code with the intended interleaving. There must be a better way…

Separate the Concurrency Policy from Behaviour

GOOS amongst other people recommend separating the concurrency policy from the parts of the system that are doing the work. So, for example, if you have some form of “executor” which is responsible for farming work out concurrently and behaviour defined separately, you can test each independently and just verify that they collaborate to achieve “worker” behaviour concurrently. Make sense?