Last active
January 4, 2016 02:49
-
-
Save thomasdarimont/8557971 to your computer and use it in GitHub Desktop.
Prototypic test case for the race condition in DATAMONGO-686
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @see DATAMONGO-686 | |
*/ | |
@SuppressWarnings("serial") | |
@Test | |
public void thereShouldBeNoRaceConditionWhenReusingQueryFromMultipleThreads() throws Exception { | |
Query query = new Query().addCriteria(where("_id").in("42")); | |
final CountDownLatch latch = new CountDownLatch(1); | |
final List<Object> observedValues = new ArrayList<Object>(); | |
final DBObject queryObject = query.getQueryObject(); | |
queryObject.put("_id", new BasicDBObject(((DBObject) queryObject.get("_id")).toMap()) { | |
@Override | |
public Object get(String key) { | |
if (key.endsWith("$in") && Thread.currentThread().getName().equals("t2")) { | |
// provokes the race-condition in | |
// org.springframework.data.mongodb.core.convert.QueryMapper.getMappedValue(Field, Object) | |
try { | |
latch.await(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
Object result = super.get(key); | |
observedValues.add(result); | |
return result; | |
} | |
}); | |
final List<Exception> exceptions = new ArrayList<Exception>(); | |
Runnable code = new Runnable() { | |
@Override | |
public void run() { | |
try { | |
mapper.getMappedObject(queryObject, context.getPersistentEntity(Sample.class)); | |
} catch (Exception ex) { | |
exceptions.add(ex); | |
} | |
latch.countDown(); | |
} | |
}; | |
Thread t1 = new Thread(code, "t1"); | |
Thread t2 = new Thread(code, "t2"); | |
t1.start(); | |
t2.start(); | |
t1.join(); | |
t2.join(); | |
assertThat(observedValues, is(not(empty()))); | |
assertThat(observedValues.size(), is(2)); | |
assertThat("Both observed values should be of the same type! But was: " | |
+ observedValues.get(0).getClass().getName() + " and " + observedValues.get(1).getClass().getName(), | |
observedValues.get(0).getClass().equals(observedValues.get(1).getClass()), is(true)); | |
assertThat(exceptions.toString(), exceptions, is(empty())); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
java.lang.AssertionError: Both observed values should be of the same type! But was: java.util.Arrays$ArrayList and [Ljava.lang.Object;
Expected: is
but: was
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:865)
at org.springframework.data.mongodb.core.convert.QueryMapperUnitTests.thereShouldBeNoRaceConditionWhenReusingQueryFromMultipleThreads(QueryMapperUnitTests.java:547)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)