JMock is thread-safe if only one thread enters the Mockery at a time.
(E.g. it doesn't use thread-local variables or any magic like that).
So, if your code is meant to guarantee that only one thread calls a
mock object at a time, but you're seeing the Mockery fail because of
race-conditions, then your code is not thread safe.
If you want multiple threads to enter the Mockery at once, you should
use the SynchronisingImposteriser that is currently in Subversion head
but will be in the upcoming 2.6.0 release.
--Nat
2009/4/1 James Abley <
james.abley@...>:
> Hi,
>
> The current policy of not supporting multi-threaded tests has just
> bitten me. We've got a spanking new CI server with multiple cores and
> are now getting build failures; I think due to JMock not being
> thread-safe; specifically the Mockery class which is declared as an
> instance of my test fixture and used throughout each @Test method.
>
> java.lang.ArrayIndexOutOfBoundsException
> at java.lang.System.arraycopy(Native Method)
> at java.util.ArrayList.ensureCapacity(ArrayList.java:170)
> at java.util.ArrayList.add(ArrayList.java:351)
> at org.jmock.Mockery.dispatch(Mockery.java:219)
> at org.jmock.Mockery.access$000(Mockery.java:43)
> at org.jmock.Mockery$MockObject.invoke(Mockery.java:258)
> at org.jmock.internal.InvocationDiverter.invoke(InvocationDiverter.java:27)
> at org.jmock.internal.FakeObjectMethods.invoke(FakeObjectMethods.java:38)
> at org.jmock.lib.JavaReflectionImposteriser$1.invoke(JavaReflectionImposteriser.java:33)
> at $Proxy9.getProperty(Unknown Source)
> at com.example.mediatranscoder.MediaTranscoderRequestContext.getStringProperty(MediaTranscoderRequestContext.java:274)
> at com.example.mediatranscoder.MediaTranscoderRequestContext.getStringProperty(MediaTranscoderRequestContext.java:122)
> at com.example.mediatranscoder.MediaAssetInfo.getHost(MediaAssetInfo.java:68)
> at com.example.mediatranscoder.MediaAssetInfo.toString(MediaAssetInfo.java:99)
> at com.example.mediatranscoder.media.locator.MediaAssetLocatorCacheManager.retrieveFromCache(MediaAssetLocatorCacheManager.java:38)
> at com.example.mediatranscoder.media.locator.ConcurrentCacheAccessTest$4.run(ConcurrentCacheAccessTest.java:278)
> at com.example.mediatranscoder.media.locator.ConcurrentTestUtils$1.run(ConcurrentTestUtils.java:74)
>
> The code being tested is effectively a singleton cache manager which
> takes a cache key and Callable block to populate a cache entry if
> there isn't one already. It's fairly heavily based on the cache given
> in Goetz et al [1]. The tests where I'm seeing failures are the ones
> where I'm using an Executor to simulate lots of concurrent requests
> trying to retrieve the same item from the cache. One of the requests
> should win and populate the cache. All others should block until the
> cache has been successfully populated.
>
> I'm fairly happy that my code is actually thread-safe and doing the
> right thing (of course, I may be wrong!), so I could mark the tests as
> @Ignore for now. But that's not a great place to be. I don't want
> someone (including me) to make a change which breaks the working code,
> etc. I think I can provide a small-ish sample test if required which
> demonstrates the problem (eventually, if you have enough CPUs).
>
> What suggestions do you have for testing this scenario?
>
> Cheers,
>
> James
>
> [1]
http://jcip.net/listings/Memoizer.java>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>
http://xircles.codehaus.org/manage_email>
>
>
--
http://www.natpryce.com---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email