views:

169

answers:

3

How would you unittest a safe-publication guarantee in Java?

To be concrete:

I have a Cache interface that has a method getOrLoad(K key, ObjectLoader loader). Thing is, if a Cache cannot find an object for the given key, then it must load it from the ObjectLoader instance. However, the Cache is required to guarantee that the act of loading an object from the loader and putting it into the Cache, constitutes a safe publication.

I'm now in the midst of writing a generic junit test for this Cache interface and I wonder how I would test that the Cache implementations adhere to this safe publication guarantee.

Any ideas? The actual code is in the test-systest module part of the code repository in case you want to poke at the real files.

A: 

Actually getting an error due to unsafe publication is very difficult (if anyone knows how, let me know). Static analysis is your best bet for an automated solution. I would stick to code review, and not worrying about it unduly.

Tom Hawtin - tackline
The trouble with static analysis and code review in this case, is the number of different implementations I intend for this interface. And the allowance of 3'rd party implementations.
Christian Vest Hansen
Also, code review, that will have to be done by you lot on the internat. I don't personally know anyone who is a better fit for reviewing concurrent code, than myself :-/
Christian Vest Hansen
Maybe you don't need someone who is a better fit for reviewing concurrent code than yourself but just someone who you can explain to why you think you're code is correct. This has helped me a lot of times.
WMR
That would usually be good enough, but in this particular case, I have an interface that promises and mandates that implementations make safe-publication guarantees. So I'd like to write a test to the interface that can check all the implementations I can throw at it.
Christian Vest Hansen
+1  A: 

Maybe you can use ConTest to at least give you a little more confidence that your code is correct.

You'll need to implement a couple of tests that run several threads concurrently. ConTest will then increase the probability that a concurrency bug is actually revealed by instrumenting byte code (adding heuristically-controlled conditional sleep and yield instructions).

WMR
A: 

I discovered a JavaOne presentation by Bill Pugh, Brian Goetz and Cliff Click on the subject of testing concurrent code. They suggested this approach, witch I think is the best I've heard:

A number of producers create stateful and thread-unsafe objects with a state-dependant hashCode implementation. As the objects are sendt through the supposed synchronizatoin point, the hashCodes are summed up (thread-locally). Likewise, the consumers on the other side of the gate sum up the hashCodes.

At the end of the test, we sum up all the results for the producers and consumers respectively. If the two sums are equal, the test passes.

We could also use XOR as an alternative to sum. In fact, any commutative operation will do. Just keep in mind that the test harness itself must not introduce any additional synchronization.

Christian Vest Hansen